# HG changeset patch # User Evan Schoenberg # Date 1165719189 0 # Node ID b81e4e44b50949167105edb7bdd52d755b3ff67a # Parent 4b319b19aa247810da26435dc7fdbb60dfe22c99 [gaim-migrate @ 17929] User Info and Tooltips now use the GaimNotifyUserInfo object and methods defined in notify.h. GaimNotifyUserInfo objects encapsulate a list of GaimNotifyUserInfoEntry objects, each of which may have a label, a value, and be specified to be a section header. This moves the burden of UI generation of user information from the various prpls to the UI. The UI can choose how to display the information rather than being fenced into a particular HTML formatting. Consistency across the prpls' information presentation is now enforced, as well. gaim_notify_user_info_get_text_with_newline() generates text in the: label: value label: value format as was passed by convention from prpls in the past. committer: Tailor Script diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/notify.c --- a/libgaim/notify.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/notify.c Sun Dec 10 02:53:09 2006 +0000 @@ -36,6 +36,21 @@ gpointer cb_user_data; } GaimNotifyInfo; +/** + * Definition of a user info entry + */ +struct _GaimNotifyUserInfoEntry +{ + char *label; + char *value; + gboolean is_header; +}; + +struct _GaimNotifyUserInfo +{ + GList *user_info_entries; +}; + void * gaim_notify_message(void *handle, GaimNotifyMsgType type, const char *title, const char *primary, @@ -416,7 +431,7 @@ void * gaim_notify_userinfo(GaimConnection *gc, const char *who, - const char *text, GaimNotifyCloseCallback cb, gpointer user_data) + GaimNotifyUserInfo *user_info, GaimNotifyCloseCallback cb, gpointer user_data) { GaimNotifyUiOps *ops; @@ -426,21 +441,18 @@ if (ops != NULL && ops->notify_userinfo != NULL) { GaimNotifyInfo *info; - char *infotext = g_strdup(text); info = g_new0(GaimNotifyInfo, 1); info->type = GAIM_NOTIFY_USERINFO; info->handle = gc; gaim_signal_emit(gaim_notify_get_handle(), "displaying-userinfo", - gaim_connection_get_account(gc), who, &infotext); + gaim_connection_get_account(gc), who, user_info); - info->ui_handle = ops->notify_userinfo(gc, who, infotext); + info->ui_handle = ops->notify_userinfo(gc, who, user_info); info->cb = cb; info->cb_user_data = user_data; - g_free(infotext); - if (info->ui_handle != NULL) { handles = g_list_append(handles, info); @@ -463,6 +475,158 @@ return NULL; } +static GaimNotifyUserInfoEntry * +gaim_notify_user_info_entry_new(const char *label, const char *value) +{ + GaimNotifyUserInfoEntry *user_info_entry; + + user_info_entry = g_new0(GaimNotifyUserInfoEntry, 1); + user_info_entry->label = g_strdup(label); + user_info_entry->value = g_strdup(value); + user_info_entry->is_header = FALSE; + + return user_info_entry; +} + +static void +gaim_notify_user_info_entry_destroy(GaimNotifyUserInfoEntry *user_info_entry) +{ + g_return_if_fail(user_info_entry != NULL); + + g_free(user_info_entry->label); + g_free(user_info_entry->value); + g_free(user_info_entry); +} + +GaimNotifyUserInfo * +gaim_notify_user_info_new() +{ + GaimNotifyUserInfo *user_info; + + user_info = g_new0(GaimNotifyUserInfo, 1); + user_info->user_info_entries = NULL; + + return user_info; +} + +void +gaim_notify_user_info_destroy(GaimNotifyUserInfo *user_info) +{ + GList *l; + + for (l = user_info->user_info_entries; l != NULL; l = l->next) { + GaimNotifyUserInfoEntry *user_info_entry = l->data; + + gaim_notify_user_info_entry_destroy(user_info_entry); + } + + g_list_free(user_info->user_info_entries); +} + +GList * +gaim_notify_user_info_get_entries(GaimNotifyUserInfo *user_info) +{ + g_return_val_if_fail(user_info != NULL, NULL); + + return user_info->user_info_entries; +} + +char * +gaim_notify_user_info_get_text_with_newline(GaimNotifyUserInfo *user_info, const char *newline) +{ + GList *l; + GString *text; + + text = g_string_new(""); + + for (l = user_info->user_info_entries; l != NULL; l = l->next) { + GaimNotifyUserInfoEntry *user_info_entry = l->data; + if (user_info_entry->is_header) + g_string_append(text, newline); + + if (user_info_entry->label) + g_string_append_printf(text, "%s", user_info_entry->label); + if (user_info_entry->label && user_info_entry->value) + g_string_append(text, ": "); + if (user_info_entry->value) + g_string_append(text, user_info_entry->value); + + if (user_info_entry->is_header) + g_string_append(text, newline); + + if (l->next) + g_string_append(text, newline); + } + + return g_string_free(text, FALSE); +} + + +gchar * +gaim_notify_user_info_entry_get_label(GaimNotifyUserInfoEntry *user_info_entry) +{ + g_return_val_if_fail(user_info_entry != NULL, NULL); + + return user_info_entry->label; +} + +gchar * +gaim_notify_user_info_entry_get_value(GaimNotifyUserInfoEntry *user_info_entry) +{ + g_return_val_if_fail(user_info_entry != NULL, NULL); + + return user_info_entry->value; +} + +void +gaim_notify_user_info_add_pair(GaimNotifyUserInfo *user_info, const char *label, const char *value) +{ + GaimNotifyUserInfoEntry *entry; + + entry = gaim_notify_user_info_entry_new(label, value); + user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); +} + +void +gaim_notify_user_info_prepend_pair(GaimNotifyUserInfo *user_info, const char *label, const char *value) +{ + GaimNotifyUserInfoEntry *entry; + + entry = gaim_notify_user_info_entry_new(label, value); + user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); +} + +void +gaim_notify_user_info_add_section_header(GaimNotifyUserInfo *user_info, const char *label) +{ + GaimNotifyUserInfoEntry *entry; + + entry = gaim_notify_user_info_entry_new(label, NULL); + entry->is_header = TRUE; + + user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); +} + +/** + * Remove the last item which was added to user_info + * This is helpful for removing a section header if the section was empty. + */ +void +gaim_notify_user_info_remove_last_item(GaimNotifyUserInfo *user_info) +{ + user_info->user_info_entries = g_list_remove(user_info->user_info_entries, + g_list_last(user_info->user_info_entries)->data); +} + +void +gaim_notify_user_info_add_section_break(GaimNotifyUserInfo *user_info) +{ + /* This is for future expansion; section breaks should be marked as such so the UI + * can format them differently if desired. + */ + gaim_notify_user_info_add_pair(user_info, NULL, "
"); +} + void * gaim_notify_uri(void *handle, const char *uri) { diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/notify.h --- a/libgaim/notify.h Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/notify.h Sun Dec 10 02:53:09 2006 +0000 @@ -29,9 +29,11 @@ #include #include +typedef struct _GaimNotifyUserInfoEntry GaimNotifyUserInfoEntry; +typedef struct _GaimNotifyUserInfo GaimNotifyUserInfo; + #include "connection.h" - /** * Notification close callbacks. */ @@ -154,7 +156,7 @@ void *data); void *(*notify_userinfo)(GaimConnection *gc, const char *who, - const char *text); + GaimNotifyUserInfo *user_info); void *(*notify_uri)(const char *uri); @@ -403,20 +405,113 @@ * The text is essentially a stripped-down format of HTML, the same that * IMs may send. * - * @param gc The GaimConnection handle associated with the information. - * @param who The username associated with the information. - * @param text The formatted text. - * @param cb The callback to call when the user closes - * the notification. - * @param user_data The data to pass to the callback. + * @param gc The GaimConnection handle associated with the information. + * @param who The username associated with the information. + * @param user_info The GaimNotifyUserInfo which contains the information + * @param cb The callback to call when the user closes + * the notification. + * @param user_data The data to pass to the callback. * * @return A UI-specific handle. */ void *gaim_notify_userinfo(GaimConnection *gc, const char *who, - const char *text, GaimNotifyCloseCallback cb, + GaimNotifyUserInfo *user_info, GaimNotifyCloseCallback cb, gpointer user_data); /** + * Create a new GaimNotifyUserInfo which is suitable for passing to gaim_notify_userinfo() + * + * @return A new GaimNotifyUserInfo, which the caller must destroy when done + */ +GaimNotifyUserInfo *gaim_notify_user_info_new(); + +/** + * Destroy a GaimNotifyUserInfo + * + * @param user_info The GaimNotifyUserInfo + */ +void gaim_notify_user_info_destroy(GaimNotifyUserInfo *user_info); + +/** + * Retrieve the array of GaimNotifyUserInfoEntry objects from a GaimNotifyUserInfo + * + * @param user_info The GaimNotifyUserInfo + * + * @result A GList of GaimNotifyUserInfoEntry objects + */ +GList *gaim_notify_user_info_get_entries(GaimNotifyUserInfo *user_info); + +/** + * Create a textual representation of a GaimNotifyUserInfo, separating entries with newline + * + * @param user_info The GaimNotifyUserInfo + * @param newline The separation character + */ +char *gaim_notify_user_info_get_text_with_newline(GaimNotifyUserInfo *user_info, const char *newline); + +/** + * Add a label/value pair to a GaimNotifyUserInfo object. GaimNotifyUserInfo keeps track of the order in which pairs are added. + * + * @param user_info The GaimNotifyUserInfo + * @param label A label, which for example might be displayed by a UI with a colon after it ("Status:"). Do not include a colon. + * If NULL, value will be displayed without a label. + * @param value The value, which might be displayed by a UI after the label. + * If NULL, label will still be displayed; the UI should then treat label as independent + * and not include a colon if it would otherwise. + */ +void gaim_notify_user_info_add_pair(GaimNotifyUserInfo *user_info, const char *label, const char *value); + +/** + * Prepend a label/value pair to a GaimNotifyUserInfo object + * + * @param user_info The GaimNotifyUserInfo + * @param label A label, which for example might be displayed by a UI with a colon after it ("Status:"). Do not include a colon. + * If NULL, value will be displayed without a label. + * @param value The value, which might be displayed by a UI after the label. + * If NULL, label will still be displayed; the UI should then treat label as independent + * and not include a colon if it would otherwise. + */ +void gaim_notify_user_info_prepend_pair(GaimNotifyUserInfo *user_info, const char *label, const char *value); + +/** + * Add a section break. A UI might display this as a horizontal line. + * + * @param user_info The GaimNotifyUserInfo + */ +void gaim_notify_user_info_add_section_break(GaimNotifyUserInfo *user_info); + +/** + * Add a section header. A UI might display this in a different font from other text. + * + * @param user_info The GaimNotifyUserInfo + * @param label The name of the section + */ +void gaim_notify_user_info_add_section_header(GaimNotifyUserInfo *user_info, const char *label); + +/** + * Remove the last item which was added to a GaimNotifyUserInfo. This could be used to remove a section header which is not needed. + */ +void gaim_notify_user_info_remove_last_item(GaimNotifyUserInfo *user_info); + +/** + * Get the label for a GaimNotifyUserInfoEntry + * + * @param user_info_entry The GaimNotifyUserInfoEntry + * + * @result The label + */ +gchar *gaim_notify_user_info_entry_get_label(GaimNotifyUserInfoEntry *user_info_entry); + +/** + * Get the value for a GaimNotifyUserInfoEntry + * + * @param user_info_entry The GaimNotifyUserInfoEntry + * + * @result The value + */ +gchar *gaim_notify_user_info_entry_get_value(GaimNotifyUserInfoEntry *user_info_entry); + +/** * Opens a URI or somehow presents it to the user. * * @param handle The plugin or connection handle. diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/gg/gg.c --- a/libgaim/protocols/gg/gg.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/gg/gg.c Sun Dec 10 02:53:09 2006 +0000 @@ -1013,56 +1013,47 @@ static void ggp_pubdir_handle_info(GaimConnection *gc, gg_pubdir50_t req, GGPSearchForm *form) { - GString *text; + GaimNotifyUserInfo *user_info; char *val, *who; - text = g_string_new(""); + user_info = gaim_notify_user_info_new(); val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS); /* XXX: Use of ggp_str_to_uin() is an ugly hack! */ - g_string_append_printf(text, "%s: %s
", - _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); + gaim_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); g_free(val); who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN); - g_string_append_printf(text, "%s: %s
", - _("UIN"), who); + gaim_notify_user_info_add_pair(user_info, _("UIN"), who); val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME); - g_string_append_printf(text, "%s: %s
", - _("First Name"), val); + gaim_notify_user_info_add_pair(user_info, _("First Name"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME); - g_string_append_printf(text, "%s: %s
", - _("Nickname"), val); + gaim_notify_user_info_add_pair(user_info, _("Nickname"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY); - g_string_append_printf(text, "%s: %s
", - _("City"), val); + gaim_notify_user_info_add_pair(user_info, _("City"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR); - if (strncmp(val, "0", 1) == 0) { - g_free(val); - val = g_strdup(""); + if (strncmp(val, "0", 1)) { + gaim_notify_user_info_add_pair(user_info, _("Birth Year"), val); } - g_string_append_printf(text, "%s: %s
", - _("Birth Year"), val); g_free(val); val = ggp_buddy_get_name(gc, ggp_str_to_uin(who)); g_free(who); who = val; - val = gaim_strdup_withhtml(text->str); +/* val = gaim_strdup_withhtml(text->str); */ - gaim_notify_userinfo(gc, who, val, ggp_sr_close_cb, form); - - g_string_free(text, TRUE); + gaim_notify_userinfo(gc, who, user_info, ggp_sr_close_cb, form); g_free(val); g_free(who); + gaim_notify_user_info_destroy(user_info); } /* }}} */ @@ -1558,11 +1549,11 @@ } /* }}} */ -/* static void ggp_tooltip_text(GaimBuddy *b, GString *str, gboolean full) {{{ */ -static void ggp_tooltip_text(GaimBuddy *b, GString *str, gboolean full) +/* static void ggp_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) {{{ */ +static void ggp_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { GaimStatus *status; - char *text; + char *text, *tmp; const char *msg, *name; g_return_if_fail(b != NULL); @@ -1574,16 +1565,15 @@ if (msg != NULL) { text = g_markup_escape_text(msg, -1); if (GAIM_BUDDY_IS_ONLINE(b)) { - g_string_append_printf(str, "\n%s: %s: %s", - _("Status"), name, text); + tmp = g_strdup_printf("%s: %s", name, text); + gaim_notify_user_info_add_pair(user_info, _("Status"), tmp); + g_free(tmp); } else { - g_string_append_printf(str, "\n%s:: %s", - _("Message"), text); + gaim_notify_user_info_add_pair(user_info, _("Message"), text); } g_free(text); - } else if (GAIM_BUDDY_IS_ONLINE(b)) { - g_string_append_printf(str, "\n%s: %s", - _("Status"), name); + } else { + gaim_notify_user_info_add_pair(user_info, _("Status"), name); } } /* }}} */ diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/irc/msgs.c --- a/libgaim/protocols/irc/msgs.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/irc/msgs.c Sun Dec 10 02:53:09 2006 +0000 @@ -199,7 +199,8 @@ { GaimConnection *gc; GString *info; - char *str, *tmp; + char *str, *tmp, *tmp2; + GaimNotifyUserInfo *user_info; if (!irc->whois.nick) { gaim_debug(GAIM_DEBUG_WARNING, "irc", "Unexpected End of WHOIS for %s\n", args[1]); @@ -210,55 +211,59 @@ return; } - info = g_string_new(""); - tmp = g_markup_escape_text(args[1], -1); - g_string_append_printf(info, _("%s: %s"), _("Nick"), tmp); + user_info = gaim_notify_user_info_new(); + + tmp2 = g_markup_escape_text(args[1], -1); + tmp = g_strdup_printf("%s%s%s", tmp2, + (irc->whois.ircop ? _(" (ircop)") : ""), + (irc->whois.identified ? _(" (identified)") : "")); + gaim_notify_user_info_add_pair(user_info, _("Nick"), tmp); + g_free(tmp2); g_free(tmp); - g_string_append_printf(info, "%s%s
", - irc->whois.ircop ? _(" (ircop)") : "", - irc->whois.identified ? _(" (identified)") : ""); + if (irc->whois.away) { tmp = g_markup_escape_text(irc->whois.away, strlen(irc->whois.away)); g_free(irc->whois.away); - g_string_append_printf(info, _("%s: %s
"), _("Away"), tmp); + gaim_notify_user_info_add_pair(user_info, _("Away"), tmp); g_free(tmp); } if (irc->whois.userhost) { tmp = g_markup_escape_text(irc->whois.name, strlen(irc->whois.name)); g_free(irc->whois.name); - g_string_append_printf(info, _("%s: %s
"), _("Username"), irc->whois.userhost); - g_string_append_printf(info, _("%s: %s
"), _("Real name"), tmp); + gaim_notify_user_info_add_pair(user_info, _("Username"), irc->whois.userhost); + gaim_notify_user_info_add_pair(user_info, _("Real name"), tmp); g_free(irc->whois.userhost); g_free(tmp); } if (irc->whois.server) { - g_string_append_printf(info, _("%s: %s"), _("Server"), irc->whois.server); - g_string_append_printf(info, " (%s)
", irc->whois.serverinfo); + tmp = g_strdup_printf("%s (%s)", irc->whois.server, irc->whois.serverinfo); + gaim_notify_user_info_add_pair(user_info, _("Server"), tmp); + g_free(tmp); g_free(irc->whois.server); g_free(irc->whois.serverinfo); } if (irc->whois.channels) { - g_string_append_printf(info, _("%s: %s
"), _("Currently on"), irc->whois.channels); + gaim_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels); g_free(irc->whois.channels); } if (irc->whois.idle) { gchar *timex = gaim_str_seconds_to_string(irc->whois.idle); - g_string_append_printf(info, _("Idle for: %s
"), timex); + gaim_notify_user_info_add_pair(user_info, _("Idle for"), timex); g_free(timex); - g_string_append_printf(info, _("%s: %s"), _("Online since"), - gaim_date_format_full(localtime(&irc->whois.signon))); + gaim_notify_user_info_add_pair(user_info, + _("Online since"), gaim_date_format_full(localtime(&irc->whois.signon))); } if (!strcmp(irc->whois.nick, "Paco-Paco")) { - g_string_append_printf(info, _("
Defining adjective: Glorious
")); + gaim_notify_user_info_add_pair(user_info, + _("Defining adjective:"), _("Glorious")); } gc = gaim_account_get_connection(irc->account); - str = g_string_free(info, FALSE); - gaim_notify_userinfo(gc, irc->whois.nick, str, NULL, NULL); + gaim_notify_userinfo(gc, irc->whois.nick, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); g_free(irc->whois.nick); - g_free(str); memset(&irc->whois, 0, sizeof(irc->whois)); } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/jabber/buddy.c --- a/libgaim/protocols/jabber/buddy.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/jabber/buddy.c Sun Dec 10 02:53:09 2006 +0000 @@ -602,17 +602,17 @@ static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi) { - GString *info_text; - char *resource_name; + char *resource_name, *tmp; JabberBuddyResource *jbr; JabberBuddyInfoResource *jbir = NULL; GList *resources; + GaimNotifyUserInfo *user_info; /* not yet */ if(jbi->ids) return; - info_text = g_string_new(""); + user_info = gaim_notify_user_info_new(); resource_name = jabber_get_resource(jbi->jid); if(resource_name) { @@ -622,29 +622,29 @@ char *purdy = NULL; if(jbr->status) purdy = gaim_strdup_withhtml(jbr->status); - g_string_append_printf(info_text, "%s: %s%s%s
", - _("Status"), jabber_buddy_state_get_name(jbr->state), - purdy ? ": " : "", - purdy ? purdy : ""); - if(purdy) - g_free(purdy); + tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), + (purdy ? ": " : ""), + (purdy ? purdy : "")); + gaim_notify_user_info_add_pair(user_info, _("Status"), tmp); + g_free(tmp); + g_free(purdy); } else { - g_string_append_printf(info_text, "%s: %s
", - _("Status"), _("Unknown")); + gaim_notify_user_info_add_pair(user_info, _("Status"), _("Unknown")); } if(jbir) { if(jbir->idle_seconds > 0) { - g_string_append_printf(info_text, "%s: %s
", - _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); + gaim_notify_user_info_add_pair(user_info, _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); } } if(jbr && jbr->client.name) { - g_string_append_printf(info_text, "%s: %s %s
", - _("Client:"), jbr->client.name, - jbr->client.version ? jbr->client.version : ""); + tmp = g_strdup_printf("%s%s%s", jbr->client.name, + (jbr->client.version ? " " : ""), + (jbr->client.version ? jbr->client.version : "")); + gaim_notify_user_info_add_pair(user_info, _("Client"), tmp); + g_free(tmp); + if(jbr->client.os) { - g_string_append_printf(info_text, "%s: %s
", - _("Operating System"), jbr->client.os); + gaim_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os); } } } else { @@ -654,54 +654,57 @@ if(jbr->status) purdy = gaim_strdup_withhtml(jbr->status); if(jbr->name) - g_string_append_printf(info_text, "%s: %s
", - _("Resource"), jbr->name); - g_string_append_printf(info_text, "%s: %d
", - _("Priority"), jbr->priority); - g_string_append_printf(info_text, "%s: %s%s%s
", - _("Status"), jabber_buddy_state_get_name(jbr->state), - purdy ? ": " : "", - purdy ? purdy : ""); - if(purdy) - g_free(purdy); + gaim_notify_user_info_add_pair(user_info, _("Resource"), jbr->name); + tmp = g_strdup_printf("%d", jbr->priority); + gaim_notify_user_info_add_pair(user_info, _("Priority"), tmp); + g_free(tmp); + + tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), + (purdy ? ": " : ""), + (purdy ? purdy : "")); + gaim_notify_user_info_add_pair(user_info, _("Status"), tmp); + g_free(tmp); + g_free(purdy); if(jbr->name) jbir = g_hash_table_lookup(jbi->resources, jbr->name); if(jbir) { if(jbir->idle_seconds > 0) { - g_string_append_printf(info_text, "%s: %s
", - _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); + gaim_notify_user_info_add_pair(user_info, _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); } } - if(jbr->client.name) { - g_string_append_printf(info_text, "%s: %s %s
", - _("Client"), jbr->client.name, - jbr->client.version ? jbr->client.version : ""); + if(jbr && jbr->client.name) { + tmp = g_strdup_printf("%s%s%s", jbr->client.name, + (jbr->client.version ? " " : ""), + (jbr->client.version ? jbr->client.version : "")); + gaim_notify_user_info_add_pair(user_info, + _("Client"), tmp); + g_free(tmp); + if(jbr->client.os) { - g_string_append_printf(info_text, "%s: %s
", - _("Operating System"), jbr->client.os); + gaim_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os); } } - - g_string_append_printf(info_text, "
"); } } g_free(resource_name); - if (jbi->vcard_text != NULL) - info_text = g_string_append(info_text, jbi->vcard_text); + if (jbi->vcard_text != NULL) { + gaim_notify_user_info_add_section_break(user_info); + /* Should this have some sort of label? */ + gaim_notify_user_info_add_pair(user_info, NULL, jbi->vcard_text); + } - gaim_notify_userinfo(jbi->js->gc, jbi->jid, info_text->str, NULL, NULL); + gaim_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); while(jbi->vcard_imgids) { gaim_imgstore_unref(GPOINTER_TO_INT(jbi->vcard_imgids->data)); jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids); } - g_string_free(info_text, TRUE); - if (jbi->timeout_handle > 0) gaim_timeout_remove(jbi->timeout_handle); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/jabber/jabber.c --- a/libgaim/protocols/jabber/jabber.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/jabber/jabber.c Sun Dec 10 02:53:09 2006 +0000 @@ -1127,7 +1127,7 @@ return ret; } -static void jabber_tooltip_text(GaimBuddy *b, GString *str, gboolean full) +static void jabber_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { JabberBuddy *jb; @@ -1160,12 +1160,14 @@ else sub = _("None"); } - g_string_append_printf(str, "\n%s: %s", _("Subscription"), sub); + + gaim_notify_user_info_add_pair(user_info, _("Subscription"), sub); } for(l=jb->resources; l; l = l->next) { char *text = NULL; char *res = NULL; + char *label, *value; const char *state; jbr = l->data; @@ -1188,20 +1190,23 @@ text = NULL; } - g_string_append_printf(str, "\n%s%s: %s%s%s", - _("Status"), - res ? res : "", - state, - text ? ": " : "", - text ? text : ""); + label = g_strdup_printf("%s%s", + _("Status"), (res ? res : "")); + value = g_strdup_printf("%s%s%s", + state, + (text ? ": " : ""), + (text ? text : "")); + gaim_notify_user_info_add_pair(user_info, label, value); + + g_free(label); + g_free(value); g_free(text); g_free(res); } if(!GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) { - g_string_append_printf(str, "\n%s: %s", - _("Error"), jb->error_msg); + gaim_notify_user_info_add_pair(user_info, _("Error"), jb->error_msg); } } } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/msn/msn.c --- a/libgaim/protocols/msn/msn.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/msn/msn.c Sun Dec 10 02:53:09 2006 +0000 @@ -67,10 +67,8 @@ MsnGetInfoData *info_data; char *stripped; char *url_buffer; - GString *s; + GaimNotifyUserInfo *user_info; char *photo_url_text; - char *tooltip_text; - const char *title; } MsnGetInfoStepTwoData; @@ -533,7 +531,7 @@ } static void -msn_tooltip_text(GaimBuddy *buddy, GString *str, gboolean full) +msn_tooltip_text(GaimBuddy *buddy, GaimNotifyUserInfo *user_info, gboolean full) { MsnUser *user; GaimPresence *presence = gaim_buddy_get_presence(buddy); @@ -541,27 +539,27 @@ user = buddy->proto_data; + if (gaim_presence_is_online(presence)) { - g_string_append_printf(str, _("\n%s: %s"), _("Status"), - gaim_presence_is_idle(presence) ? - _("Idle") : gaim_status_get_name(status)); + gaim_notify_user_info_add_pair(user_info, _("Status"), + (gaim_presence_is_idle(presence) ? _("Idle") : gaim_status_get_name(status))); } - + if (full && user) { - g_string_append_printf(str, _("\n%s: %s"), _("Has you"), - (user->list_op & (1 << MSN_LIST_RL)) ? - _("Yes") : _("No")); + gaim_notify_user_info_add_pair(user_info, _("Has you"), + ((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No"))); + } /* XXX: This is being shown in non-full tooltips because the * XXX: blocked icon overlay isn't always accurate for MSN. * XXX: This can die as soon as gaim_privacy_check() knows that * XXX: this prpl always honors both the allow and deny lists. */ if (user) - g_string_append_printf(str, _("\n%s: %s"), _("Blocked"), - (user->list_op & (1 << MSN_LIST_BL)) ? - _("Yes") : _("No")); + { + gaim_notify_user_info_add_pair(user_info, _("Blocked"), + ((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No"))); } } @@ -1341,47 +1339,44 @@ } } -static char * -msn_tooltip_info_text(MsnGetInfoData *info_data) +/** + * Extract info text from info_data and add it to user_info + */ +static gboolean +msn_tooltip_extract_info_text(GaimNotifyUserInfo *user_info, MsnGetInfoData *info_data) { - GString *s; GaimBuddy *b; - s = g_string_sized_new(80); /* wild guess */ - b = gaim_find_buddy(gaim_connection_get_account(info_data->gc), info_data->name); if (b) { - GString *str = g_string_new(""); char *tmp; if (b->alias && b->alias[0]) { char *aliastext = g_markup_escape_text(b->alias, -1); - g_string_append_printf(s, _("Alias: %s
"), aliastext); + gaim_notify_user_info_add_pair(user_info, _("Alias"), aliastext); g_free(aliastext); } if (b->server_alias) { char *nicktext = g_markup_escape_text(b->server_alias, -1); - g_string_append_printf(s, _("%s: "), _("Nickname")); - g_string_append_printf(s, "%s
", - nicktext); + tmp = g_strdup_printf("%s
", nicktext); + gaim_notify_user_info_add_pair(user_info, _("Nickname"), tmp); + g_free(tmp); g_free(nicktext); } - msn_tooltip_text(b, str, TRUE); - tmp = gaim_strreplace((*str->str == '\n' ? str->str + 1 : str->str), - "\n", "
"); - g_string_free(str, TRUE); - g_string_append_printf(s, "%s
", tmp); - g_free(tmp); + /* Add the tooltip information */ + msn_tooltip_text(b, user_info, TRUE); + + return TRUE; } - return g_string_free(s, FALSE); + return FALSE; } #if PHOTO_SUPPORT @@ -1419,7 +1414,7 @@ #endif #define MSN_GOT_INFO_GET_FIELD(a, b) \ - found = gaim_markup_extract_info_field(stripped, stripped_len, s, \ + found = gaim_markup_extract_info_field(stripped, stripped_len, user_info, \ "\n" a ":", 0, "\n", 0, "Undisclosed", b, 0, NULL, NULL); \ if (found) \ sect_info = TRUE; @@ -1429,17 +1424,15 @@ const gchar *url_text, size_t len, const gchar *error_message) { MsnGetInfoData *info_data = (MsnGetInfoData *)data; - char *stripped, *p, *q; - char buf[1024]; - char *tooltip_text; + GaimNotifyUserInfo *user_info; + char *stripped, *p, *q, *tmp; char *user_url = NULL; gboolean found; + gboolean has_tooltip_text = FALSE; gboolean has_info = FALSE; gboolean sect_info = FALSE; - const char* title = NULL; + gboolean has_contact_info = FALSE; char *url_buffer; - char *personal = NULL; - char *business = NULL; GString *s, *s2; int stripped_len; #if PHOTO_SUPPORT @@ -1458,17 +1451,18 @@ return; } - tooltip_text = msn_tooltip_info_text(info_data); - title = _("MSN Profile"); + user_info = gaim_notify_user_info_new(); + has_tooltip_text = msn_tooltip_extract_info_text(user_info, info_data); if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) { - g_snprintf(buf, 1024, "%s%s", - tooltip_text, _("Error retrieving profile")); + tmp = g_strdup_printf("%s", _("Error retrieving profile")); + gaim_notify_user_info_add_pair(user_info, NULL, tmp); + g_free(tmp); - gaim_notify_userinfo(info_data->gc, info_data->name, buf, NULL, NULL); + gaim_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); - g_free(tooltip_text); g_free(info_data->name); g_free(info_data); return; @@ -1528,10 +1522,16 @@ /* No we're not. */ s = g_string_sized_new(strlen(url_buffer)); s2 = g_string_sized_new(strlen(url_buffer)); - + + /* General section header */ + if (has_tooltip_text) + gaim_notify_user_info_add_section_break(user_info); + + gaim_notify_user_info_add_section_header(user_info, _("General")); + /* Extract their Name and put it in */ - MSN_GOT_INFO_GET_FIELD("Name", _("Name")) - + MSN_GOT_INFO_GET_FIELD("Name", _("Name")); + /* General */ MSN_GOT_INFO_GET_FIELD("Nickname", _("Nickname")); MSN_GOT_INFO_GET_FIELD("Age", _("Age")); @@ -1540,7 +1540,7 @@ MSN_GOT_INFO_GET_FIELD("Location", _("Location")); /* Extract their Interests and put it in */ - found = gaim_markup_extract_info_field(stripped, stripped_len, s, + found = gaim_markup_extract_info_field(stripped, stripped_len, user_info, "\nInterests\t", 0, " (/default.aspx?page=searchresults", 0, "Undisclosed", _("Hobbies and Interests") /* _("Interests") */, 0, NULL, NULL); @@ -1549,20 +1549,24 @@ sect_info = TRUE; MSN_GOT_INFO_GET_FIELD("More about me", _("A Little About Me")); - + if (sect_info) { - /* trim off the trailing "
\n" */ - g_string_truncate(s, strlen(s->str) - 5); - g_string_append_printf(s2, _("%sGeneral
%s"), - (*tooltip_text) ? "
" : "", s->str); - s = g_string_truncate(s, 0); has_info = TRUE; sect_info = FALSE; } - - + else + { + /* Remove the section header */ + gaim_notify_user_info_remove_last_item(user_info); + if (has_tooltip_text) + gaim_notify_user_info_remove_last_item(user_info); + } + /* Social */ + gaim_notify_user_info_add_section_break(user_info); + gaim_notify_user_info_add_section_header(user_info, _("Social")); + MSN_GOT_INFO_GET_FIELD("Marital status", _("Marital Status")); MSN_GOT_INFO_GET_FIELD("Interested in", _("Interests")); MSN_GOT_INFO_GET_FIELD("Pets", _("Pets")); @@ -1575,14 +1579,22 @@ if (sect_info) { - g_string_append_printf(s2, _("%sSocial
%s"), has_info ? "

" : "", s->str); - s = g_string_truncate(s, 0); has_info = TRUE; sect_info = FALSE; } + else + { + /* Remove the section header */ + gaim_notify_user_info_remove_last_item(user_info); + gaim_notify_user_info_remove_last_item(user_info); + } /* Contact Info */ /* Personal */ + gaim_notify_user_info_add_section_break(user_info); + gaim_notify_user_info_add_section_header(user_info, _("Contact Info")); + gaim_notify_user_info_add_section_header(user_info, _("Personal")); + MSN_GOT_INFO_GET_FIELD("Name", _("Name")); MSN_GOT_INFO_GET_FIELD("Significant other", _("Significant Other")); MSN_GOT_INFO_GET_FIELD("Home phone", _("Home Phone")); @@ -1598,13 +1610,18 @@ if (sect_info) { - personal = g_strdup_printf(_("
Personal
%s"), s->str); - s = g_string_truncate(s, 0); + has_info = TRUE; sect_info = FALSE; - has_info = TRUE; + has_contact_info = TRUE; + } + else + { + /* Remove the section header */ + gaim_notify_user_info_remove_last_item(user_info); } /* Business */ + gaim_notify_user_info_add_section_header(user_info, _("Work")); MSN_GOT_INFO_GET_FIELD("Name", _("Name")); MSN_GOT_INFO_GET_FIELD("Job title", _("Job Title")); MSN_GOT_INFO_GET_FIELD("Company", _("Company")); @@ -1623,27 +1640,22 @@ if (sect_info) { - business = g_strdup_printf(_("
Business
%s"), s->str); - s = g_string_truncate(s, 0); + has_info = TRUE; sect_info = FALSE; + has_contact_info = TRUE; + } + else + { + /* Remove the section header */ + gaim_notify_user_info_remove_last_item(user_info); } - if ((personal != NULL) || (business != NULL)) + if (!has_contact_info) { - /* trim off the trailing "
\n" */ - g_string_truncate(s, strlen(s->str) - 5); - - has_info = TRUE; - g_string_append_printf(s2, _("
Contact Info%s%s"), - personal ? personal : "", - business ? business : ""); + /* Remove the Contact Info section header */ + gaim_notify_user_info_remove_last_item(user_info); } - g_free(personal); - g_free(business); - g_string_free(s, TRUE); - s = s2; - #if 0 /* these probably don't show up any more */ /* * The fields, 'A Little About Me', 'Favorite Things', 'Hobbies @@ -1768,12 +1780,9 @@ /* If we were able to fetch a homepage url earlier, stick it in there */ if (user_url != NULL) { - g_snprintf(buf, sizeof(buf), - "%s:
%s
\n", - _("Homepage"), user_url, user_url); - - g_string_append(s, buf); - + tmp = g_strdup_printf("%s", user_url, user_url); + gaim_notify_user_info_add_pair(user_info, _("Homepage"), tmp); + g_free(tmp); g_free(user_url); has_info = TRUE; @@ -1792,25 +1801,22 @@ char *p = strstr(url_buffer, "form id=\"SpacesSearch\" name=\"SpacesSearch\""); GaimBuddy *b = gaim_find_buddy (gaim_connection_get_account(info_data->gc), info_data->name); - g_string_append_printf(s, "
%s
%s

", - _("Error retrieving profile"), - ((p && b)? - _("The user has not created a public profile."): - p? _("MSN reported not being able to find the user's profile. " - "This either means that the user does not exist, " - "or that the user exists " - "but has not created a public profile."): - _("Gaim could not find " /* This should never happen */ - "any information in the user's profile. " - "The user most likely does not exist."))); + gaim_notify_user_info_add_pair(user_info, _("Error retrieving profile"), + ((p && b) ? _("The user has not created a public profile.") : + (p ? _("MSN reported not being able to find the user's profile. " + "This either means that the user does not exist, " + "or that the user exists " + "but has not created a public profile.") : + _("Gaim could not find " /* This should never happen */ + "any information in the user's profile. " + "The user most likely does not exist.")))); } + /* put a link to the actual profile URL */ - g_string_append_printf(s, _("
%s: "), _("Profile URL")); - g_string_append_printf(s, "
%s%s
", - PROFILE_URL, info_data->name, PROFILE_URL, info_data->name); - - /* Finish it off, and show it to them */ - g_string_append(s, "\n"); + tmp = g_strdup_printf("%s%s", + PROFILE_URL, info_data->name, PROFILE_URL, info_data->name); + gaim_notify_user_info_add_pair(user_info, _("Profile URL"), tmp); + g_free(tmp); #if PHOTO_SUPPORT /* Find the URL to the photo; must be before the marshalling [Bug 994207] */ @@ -1821,10 +1827,8 @@ info2_data->info_data = info_data; info2_data->stripped = stripped; info2_data->url_buffer = url_buffer; - info2_data->s = s; + info2_data->user_info = user_info; info2_data->photo_url_text = photo_url_text; - info2_data->tooltip_text = tooltip_text; - info2_data->title = title; /* Try to put the photo in there too, if there's one */ if (photo_url_text) @@ -1851,9 +1855,8 @@ MsnGetInfoData *info_data = info2_data->info_data; char *stripped = info2_data->stripped; char *url_buffer = info2_data->url_buffer; - GString *s = info2_data->s; + GaimNotifyUserInfo *user_info = info2_data->user_info; char *photo_url_text = info2_data->photo_url_text; - char *tooltip_text = info2_data->tooltip_text; /* Make sure the connection is still valid if we got here by fetching a photo url */ if (url_text && (error_message != NULL || @@ -1862,8 +1865,7 @@ gaim_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n"); g_free(stripped); g_free(url_buffer); - g_string_free(s, TRUE); - g_free(tooltip_text); + g_free(user_info); g_free(info_data->name); g_free(info_data); g_free(photo_url_text); @@ -1889,20 +1891,17 @@ gaim_debug_info("msn", "%s is %d bytes\n", photo_url_text, len); id = gaim_imgstore_add(url_text, len, NULL); g_snprintf(buf, sizeof(buf), "
", id); - g_string_prepend(s, buf); + gaim_notify_user_info_prepend_pair(user_info, NULL, buf); } } /* We continue here from msn_got_info, as if nothing has happened */ #endif - - g_string_prepend(s, tooltip_text); - gaim_notify_userinfo(info_data->gc, info_data->name, s->str, NULL, NULL); + gaim_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL); g_free(stripped); g_free(url_buffer); - g_string_free(s, TRUE); - g_free(tooltip_text); + gaim_notify_user_info_destroy(user_info); g_free(info_data->name); g_free(info_data); #if PHOTO_SUPPORT diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/novell/novell.c --- a/libgaim/protocols/novell/novell.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/novell/novell.c Sun Dec 10 02:53:09 2006 +0000 @@ -1494,6 +1494,7 @@ static void _show_info(GaimConnection * gc, NMUserRecord * user_record) { + GaimNotifyUserInfo *user_info = gaim_notify_user_info_new(); GString *info_text; int count, i; NMProperty *property; @@ -1504,21 +1505,20 @@ tag = _("User ID"); value = nm_user_record_get_userid(user_record); if (value) { - g_string_append_printf(info_text, "%s: %s
", tag, value); + gaim_notify_user_info_add_pair(user_info, tag, value); } /* tag = _("DN"); value = nm_user_record_get_dn(user_record); if (value) { - g_string_append_printf(info_text, "%s: %s
", - tag, value); + gaim_notify_user_info_add_pair(user_info, tag, value); } */ tag = _("Full name"); value = nm_user_record_get_full_name(user_record); if (value) { - g_string_append_printf(info_text, "%s: %s
", tag, value); + gaim_notify_user_info_add_pair(user_info, tag, value); } count = nm_user_record_get_property_count(user_record); @@ -1528,17 +1528,15 @@ tag = _map_property_tag(nm_property_get_tag(property)); value = nm_property_get_value(property); if (tag && value) { - g_string_append_printf(info_text, "%s: %s
", - tag, value); + gaim_notify_user_info_add_pair(user_info, tag, value); } nm_release_property(property); } } gaim_notify_userinfo(gc, nm_user_record_get_userid(user_record), - info_text->str, NULL, NULL); - - g_string_free(info_text, TRUE); + user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); } /* Send a join conference, the first item in the parms list is the @@ -2826,7 +2824,7 @@ } static void -novell_tooltip_text(GaimBuddy * buddy, GString * str, gboolean full) +novell_tooltip_text(GaimBuddy * buddy, GaimNotifyUserInfo * user_info, gboolean full) { NMUserRecord *user_record = NULL; GaimConnection *gc; @@ -2869,14 +2867,10 @@ break; } + gaim_notify_user_info_add_pair(user_info, _("Status"), status_str); + if (text) - g_string_append_printf(str, "\n%s: %s" - "\n%s: %s", - _("Status"), status_str, - _("Message"), text); - else - g_string_append_printf(str, "\n%s: %s", - _("Status"), status_str); + gaim_notify_user_info_add_pair(user_info, _("Message"), text); } } } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/oscar/oscar.c --- a/libgaim/protocols/oscar/oscar.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/oscar/oscar.c Sun Dec 10 02:53:09 2006 +0000 @@ -705,11 +705,22 @@ } static void -oscar_string_append(GString *str, const char *newline, - const char *name, const char *value) +oscar_user_info_add_pair(GaimNotifyUserInfo *user_info, const char *name, const char *value) { if (value && value[0]) { - g_string_append_printf(str, "%s%s: %s", newline, name, value); + gaim_notify_user_info_add_pair(user_info, name, value); + } +} + +static void +oscar_user_info_convert_and_add_pair(GaimAccount *account, GaimNotifyUserInfo *user_info, + const char *name, const char *value) +{ + gchar *utf8; + + if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, value))) { + gaim_notify_user_info_add_pair(user_info, name, utf8); + g_free(utf8); } } @@ -725,7 +736,19 @@ } } -static void oscar_string_append_info(GaimConnection *gc, GString *str, const char *newline, GaimBuddy *b, aim_userinfo_t *userinfo) +static void +oscar_user_info_convert_and_add(GaimAccount *account, GaimNotifyUserInfo *user_info, + const char *name, const char *value) +{ + gchar *utf8; + + if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, value))) { + gaim_notify_user_info_add_pair(user_info, name, value); + g_free(utf8); + } +} + +static void oscar_string_append_info(GaimConnection *gc, GaimNotifyUserInfo *user_info, GaimBuddy *b, aim_userinfo_t *userinfo) { OscarData *od; GaimAccount *account; @@ -738,7 +761,7 @@ od = gc->proto_data; account = gaim_connection_get_account(gc); - if ((str == NULL) || (newline == NULL) || ((b == NULL) && (userinfo == NULL))) + if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL))) return; if (userinfo == NULL) @@ -760,17 +783,14 @@ if (gaim_presence_is_online(presence)) { if (aim_sn_is_icq(b->name)) { GaimStatus *status = gaim_presence_get_active_status(presence); - oscar_string_append(str, newline, _("Status"), - gaim_status_get_name(status)); + oscar_user_info_add_pair(user_info, _("Status"), gaim_status_get_name(status)); } } else { tmp = aim_ssi_itemlist_findparentname(od->ssi.local, b->name); if (aim_ssi_waitingforauth(od->ssi.local, tmp, b->name)) - oscar_string_append(str, newline, _("Status"), - _("Not Authorized")); + oscar_user_info_add_pair(user_info, _("Status"), _("Not Authorized")); else - oscar_string_append(str, newline, _("Status"), - _("Offline")); + oscar_user_info_add_pair(user_info, _("Status"), _("Offline")); } } @@ -780,14 +800,14 @@ (bi->ipaddr & 0x00ff0000) >> 16, (bi->ipaddr & 0x0000ff00) >> 8, (bi->ipaddr & 0x000000ff)); - oscar_string_append(str, newline, _("IP Address"), tmp); + oscar_user_info_add_pair(user_info, _("IP Address"), tmp); g_free(tmp); } if ((userinfo != NULL) && (userinfo->warnlevel != 0)) { tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5)); - oscar_string_append(str, newline, _("Warning Level"), tmp); + oscar_user_info_add_pair(user_info, _("Warning Level"), tmp); g_free(tmp); } @@ -796,7 +816,8 @@ if (tmp != NULL) { char *tmp2 = g_markup_escape_text(tmp, strlen(tmp)); g_free(tmp); - oscar_string_convert_and_append(account, str, newline, _("Buddy Comment"), tmp2); + + oscar_user_info_convert_and_add_pair(account, user_info, _("Buddy Comment"), tmp2); g_free(tmp2); } } @@ -2581,21 +2602,25 @@ switch(reason) { case 0x0003: { /* Reply from an ICQ status message request */ - char *title, *statusmsg, **splitmsg, *dialogmsg; - - title = g_strdup_printf(_("Info for %s"), who); + char *statusmsg, **splitmsg; + GaimNotifyUserInfo *user_info; /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ statusmsg = oscar_icqstatus(state); splitmsg = g_strsplit(msg, "\r\n", 0); - dialogmsg = g_strdup_printf(_("UIN: %s
Status: %s
%s"), who, statusmsg, g_strjoinv("
", splitmsg)); + + user_info = gaim_notify_user_info_new(); + + gaim_notify_user_info_add_pair(user_info, _("UIN"), who); + gaim_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + gaim_notify_user_info_add_pair(user_info, NULL, g_strjoinv("
", splitmsg)); + g_free(statusmsg); g_strfreev(splitmsg); - gaim_notify_userinfo(gc, who, dialogmsg, NULL, NULL); - - g_free(title); - g_free(dialogmsg); + gaim_notify_userinfo(gc, who, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); + } break; default: { @@ -2766,7 +2791,7 @@ static int gaim_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { GaimConnection *gc = od->gc; GaimAccount *account = gaim_connection_get_account(gc); - GString *str; + GaimNotifyUserInfo *user_info; gchar *tmp = NULL, *info_utf8 = NULL, *away_utf8 = NULL; va_list ap; aim_userinfo_t *userinfo; @@ -2775,33 +2800,36 @@ userinfo = va_arg(ap, aim_userinfo_t *); va_end(ap); - str = g_string_new(""); - g_string_append_printf(str, "%s: %s", _("Screen Name"), userinfo->sn); - g_string_append_printf(str, "\n
%s: %d%%", _("Warning Level"), (int)((userinfo->warnlevel/10.0) + 0.5)); + user_info = gaim_notify_user_info_new(); + gaim_notify_user_info_add_pair(user_info, _("Screen Name"), userinfo->sn); + + tmp = g_strdup_printf("%d", (int)((userinfo->warnlevel/10.0) + 0.5)); + gaim_notify_user_info_add_pair(user_info, _("Warning Level"), tmp); + g_free(tmp); if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) { time_t t = userinfo->onlinesince - od->timeoffset; - oscar_string_append(str, "\n
", _("Online Since"), gaim_date_format_full(localtime(&t))); + oscar_user_info_add_pair(user_info, _("Online Since"), gaim_date_format_full(localtime(&t))); } if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { time_t t = userinfo->membersince - od->timeoffset; - oscar_string_append(str, "\n
", _("Member Since"), gaim_date_format_full(localtime(&t))); + oscar_user_info_add_pair(user_info, _("Member Since"), gaim_date_format_full(localtime(&t))); } if (userinfo->capabilities != 0) { tmp = oscar_caps_to_string(userinfo->capabilities); - oscar_string_append(str, "\n
", _("Capabilities"), tmp); + oscar_user_info_add_pair(user_info, _("Capabilities"), tmp); g_free(tmp); } if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) { tmp = gaim_str_seconds_to_string(userinfo->idletime*60); - oscar_string_append(str, "\n
", _("Idle"), tmp); + oscar_user_info_add_pair(user_info, _("Idle"), tmp); g_free(tmp); } - oscar_string_append_info(gc, str, "\n
", NULL, userinfo); + oscar_string_append_info(gc, user_info, NULL, userinfo); /* Available message */ if ((userinfo->status != NULL) && !(userinfo->flags & AIM_FLAG_AWAY)) @@ -2809,7 +2837,7 @@ if (userinfo->status[0] != '\0') tmp = oscar_encoding_to_utf8(userinfo->status_encoding, userinfo->status, userinfo->status_len); - oscar_string_convert_and_append(account, str, "\n
", _("Available Message"), tmp); + oscar_user_info_add_pair(user_info, _("Available Message"), tmp); g_free(tmp); } @@ -2819,7 +2847,9 @@ away_utf8 = oscar_encoding_to_utf8(tmp, userinfo->away, userinfo->away_len); g_free(tmp); if (away_utf8 != NULL) { - g_string_append_printf(str, "\n
%s", away_utf8); + tmp = gaim_str_sub_away_formatters(away_utf8, gaim_account_get_username(account)); + oscar_user_info_add_pair(user_info, NULL, tmp); + g_free(tmp); g_free(away_utf8); } } @@ -2830,16 +2860,15 @@ info_utf8 = oscar_encoding_to_utf8(tmp, userinfo->info, userinfo->info_len); g_free(tmp); if (info_utf8 != NULL) { - g_string_append_printf(str, "\n
%s", info_utf8); + tmp = gaim_str_sub_away_formatters(info_utf8, gaim_account_get_username(account)); + oscar_user_info_add_pair(user_info, _("Profile"), tmp); + g_free(tmp); g_free(info_utf8); } } - tmp = gaim_str_sub_away_formatters(str->str, gaim_account_get_username(account)); - g_string_free(str, TRUE); - gaim_str_strip_char(tmp, '\r'); - gaim_notify_userinfo(gc, userinfo->sn, tmp, NULL, NULL); - g_free(tmp); + gaim_notify_userinfo(gc, userinfo->sn, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); return 1; } @@ -3581,8 +3610,10 @@ GaimBuddy *buddy; struct buddyinfo *bi; gchar who[16]; - GString *str; + GaimNotifyUserInfo *user_info; + GString *tmp; gchar *utf8; + gchar *buf; const gchar *alias; va_list ap; struct aim_icq_info *info; @@ -3597,7 +3628,8 @@ if (!info->uin) return 0; - str = g_string_sized_new(100); + user_info = gaim_notify_user_info_new(); + g_snprintf(who, sizeof(who), "%u", info->uin); buddy = gaim_find_buddy(gaim_connection_get_account(gc), who); if (buddy != NULL) @@ -3605,35 +3637,41 @@ else bi = NULL; - g_string_append_printf(str, "%s: %s", _("UIN"), who); - oscar_string_convert_and_append(account, str, "\n
", _("Nick"), info->nick); + gaim_notify_user_info_add_pair(user_info, _("UIN"), who); + oscar_user_info_convert_and_add(account, user_info, _("Nick"), info->nick); if ((bi != NULL) && (bi->ipaddr != 0)) { char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", (bi->ipaddr & 0xff000000) >> 24, (bi->ipaddr & 0x00ff0000) >> 16, (bi->ipaddr & 0x0000ff00) >> 8, (bi->ipaddr & 0x000000ff)); - oscar_string_append(str, "\n
", _("IP Address"), tstr); + gaim_notify_user_info_add_pair(user_info, _("IP Address"), tstr); g_free(tstr); } - oscar_string_convert_and_append(account, str, "\n
", _("First Name"), info->first); - oscar_string_convert_and_append(account, str, "\n
", _("Last Name"), info->last); + oscar_user_info_convert_and_add(account, user_info, _("First Name"), info->first); + oscar_user_info_convert_and_add(account, user_info, _("Last Name"), info->last); if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->email))) { - g_string_append_printf(str, "\n
%s: %s", _("E-Mail Address"), utf8, utf8); + buf = g_strdup_printf("%s", utf8, utf8); + gaim_notify_user_info_add_pair(user_info, _("E-Mail Address"), buf); + g_free(buf); g_free(utf8); } if (info->numaddresses && info->email2) { int i; for (i = 0; i < info->numaddresses; i++) { if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(gc->account, info->email2[i]))) { - g_string_append_printf(str, "\n
%s: %s", _("E-Mail Address"), utf8, utf8); + buf = g_strdup_printf("%s", utf8, utf8); + gaim_notify_user_info_add_pair(user_info, _("E-Mail Address"), buf); + g_free(buf); g_free(utf8); } } } - oscar_string_convert_and_append(account, str, "\n
", _("Mobile Phone"), info->mobile); + oscar_user_info_convert_and_add(account, user_info, _("Mobile Phone"), info->mobile); + if (info->gender != 0) - oscar_string_append(str, "\n
", _("Gender"), info->gender == 1 ? _("Female") : _("Male")); + gaim_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male"))); + if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) { /* Initialize the struct properly or strftime() will crash * under some conditions (e.g. Debian sarge w/ LANG=en_HK). */ @@ -3649,57 +3687,68 @@ * feel free to remove it. --rlaager */ mktime(tm); - oscar_string_append(str, "\n
", _("Birthday"), - gaim_date_format_short(tm)); + oscar_user_info_convert_and_add(account, user_info, _("Birthday"), gaim_date_format_short(tm)); } if ((info->age > 0) && (info->age < 255)) { char age[5]; snprintf(age, sizeof(age), "%hhd", info->age); - oscar_string_append(str, "\n
", _("Age"), age); + gaim_notify_user_info_add_pair(user_info, + _("Age"), age); } if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->personalwebpage))) { - g_string_append_printf(str, "\n
%s: %s", _("Personal Web Page"), utf8, utf8); - g_free(utf8); - } - if (info->info && info->info[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->info))) { - g_string_append_printf(str, "
%s:
%s", _("Additional Information"), utf8); + buf = g_strdup_printf("%s", utf8, utf8); + gaim_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf); + g_free(buf); g_free(utf8); } - g_string_append_printf(str, "
"); + + oscar_user_info_convert_and_add(account, user_info, _("Additional Information"), info->info); + +/* g_string_append_printf(str, "
"); */ + if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) { - g_string_append_printf(str, "%s:", _("Home Address")); - oscar_string_convert_and_append(account, str, "\n
", _("Address"), info->homeaddr); - oscar_string_convert_and_append(account, str, "\n
", _("City"), info->homecity); - oscar_string_convert_and_append(account, str, "\n
", _("State"), info->homestate); - oscar_string_convert_and_append(account, str, "\n
", _("Zip Code"), info->homezip); - g_string_append_printf(str, "\n
"); + tmp = g_string_sized_new(100); + oscar_string_convert_and_append(account, tmp, "\n
", _("Address"), info->homeaddr); + oscar_string_convert_and_append(account, tmp, "\n
", _("City"), info->homecity); + oscar_string_convert_and_append(account, tmp, "\n
", _("State"), info->homestate); + oscar_string_convert_and_append(account, tmp, "\n
", _("Zip Code"), info->homezip); + + gaim_notify_user_info_add_pair(user_info, _("Home Address"), tmp->str); + + g_string_free(tmp, TRUE); } if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) { - g_string_append_printf(str, "%s:", _("Work Address")); - oscar_string_convert_and_append(account, str, "\n
", _("Address"), info->workaddr); - oscar_string_convert_and_append(account, str, "\n
", _("City"), info->workcity); - oscar_string_convert_and_append(account, str, "\n
", _("State"), info->workstate); - oscar_string_convert_and_append(account, str, "\n
", _("Zip Code"), info->workzip); - g_string_append_printf(str, "\n
"); + tmp = g_string_sized_new(100); + + oscar_string_convert_and_append(account, tmp, "\n
", _("Address"), info->workaddr); + oscar_string_convert_and_append(account, tmp, "\n
", _("City"), info->workcity); + oscar_string_convert_and_append(account, tmp, "\n
", _("State"), info->workstate); + oscar_string_convert_and_append(account, tmp, "\n
", _("Zip Code"), info->workzip); + + gaim_notify_user_info_add_pair(user_info, _("Work Address"), tmp->str); + + g_string_free(tmp, TRUE); } if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) { - g_string_append_printf(str, "%s:", _("Work Information")); - oscar_string_convert_and_append(account, str, "\n
", _("Company"), info->workcompany); - oscar_string_convert_and_append(account, str, "\n
", _("Division"), info->workdivision); - oscar_string_convert_and_append(account, str, "\n
", _("Position"), info->workposition); + tmp = g_string_sized_new(100); + + oscar_string_convert_and_append(account, tmp, "\n
", _("Company"), info->workcompany); + oscar_string_convert_and_append(account, tmp, "\n
", _("Division"), info->workdivision); + oscar_string_convert_and_append(account, tmp, "\n
", _("Position"), info->workposition); if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->workwebpage))) { - g_string_append_printf(str, "\n
%s: %s", _("Web Page"), utf8, utf8); + g_string_append_printf(tmp, "\n
%s: %s", _("Web Page"), utf8, utf8); g_free(utf8); } - g_string_append_printf(str, "\n
"); + gaim_notify_user_info_add_pair(user_info, _("Work Information"), tmp->str); + g_string_free(tmp, TRUE); } if (buddy != NULL) alias = gaim_buddy_get_alias(buddy); else alias = who; - gaim_notify_userinfo(gc, who, str->str, NULL, NULL); - g_string_free(str, TRUE); + gaim_notify_userinfo(gc, who, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); return 1; } @@ -5361,7 +5410,7 @@ *ne = emblems[3]; } -void oscar_tooltip_text(GaimBuddy *b, GString *str, gboolean full) { +void oscar_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { GaimConnection *gc = b->account->gc; OscarData *od = gc->proto_data; aim_userinfo_t *userinfo = aim_locate_finduserinfo(od, b->name); @@ -5372,7 +5421,7 @@ const char *message; if (full) - oscar_string_append_info(gc, str, "\n", b, userinfo); + oscar_string_append_info(gc, user_info, b, userinfo); presence = gaim_buddy_get_presence(b); status = gaim_presence_get_active_status(presence); @@ -5385,7 +5434,7 @@ /* Available status messages are plain text */ gchar *tmp; tmp = g_markup_escape_text(message, -1); - g_string_append_printf(str, "\n%s: %s", _("Message"), tmp); + gaim_notify_user_info_add_pair(user_info, _("Message"), tmp); g_free(tmp); } } @@ -5400,12 +5449,12 @@ g_free(tmp2); tmp2 = gaim_str_sub_away_formatters(tmp1, gaim_account_get_username(gaim_connection_get_account(gc))); g_free(tmp1); - g_string_append_printf(str, "\n%s: %s", _("Message"), tmp2); + gaim_notify_user_info_add_pair(user_info, _("Away Message"), tmp2); g_free(tmp2); } else { - g_string_append_printf(str, "\n%s: %s", _("Message"), _("(retrieving)")); + gaim_notify_user_info_add_pair(user_info, _("Away Message"), _("(retrieving)")); } } } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/oscar/oscarcommon.h --- a/libgaim/protocols/oscar/oscarcommon.h Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/oscar/oscarcommon.h Sun Dec 10 02:53:09 2006 +0000 @@ -28,6 +28,7 @@ #include "internal.h" #include "prpl.h" #include "version.h" +#include "notify.h" #define OSCAR_DEFAULT_LOGIN_SERVER "login.oscar.aol.com" #define OSCAR_DEFAULT_LOGIN_PORT 5190 @@ -48,7 +49,7 @@ const char *oscar_list_icon_aim(GaimAccount *a, GaimBuddy *b); void oscar_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne); char *oscar_status_text(GaimBuddy *b); -void oscar_tooltip_text(GaimBuddy *b, GString *str, gboolean full); +void oscar_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full); GList *oscar_status_types(GaimAccount *account); GList *oscar_blist_node_menu(GaimBlistNode *node); GList *oscar_chat_info(GaimConnection *gc); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/qq/buddy_info.c --- a/libgaim/protocols/qq/buddy_info.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/qq/buddy_info.c Sun Dec 10 02:53:09 2006 +0000 @@ -153,56 +153,58 @@ } } -static void append_field_value(GString *info_text, const gchar *field, +static gboolean append_field_value(GaimNotifyUserInfo *user_info, const gchar *field, const gchar *title, const gchar **choice, gint choice_size) { gchar *value = field_value(field, choice, choice_size); if (value != NULL) { - g_string_append_printf(info_text, "
%s: %s", title, value); + gaim_notify_user_info_add_pair(user_info, title, value); g_free(value); + + return TRUE; } + + return FALSE; } -static GString *info_to_str(const contact_info *info) +static GaimNotifyUserInfo * +info_to_notify_user_info(const contact_info *info) { - GString *info_text, *extra_info; + GaimNotifyUserInfo *user_info = gaim_notify_user_info_new(); const gchar *intro; - gint len; + gboolean has_extra_info = FALSE; - info_text = g_string_new(""); - g_string_append_printf(info_text, "%s

", QQ_PRIMARY_INFORMATION); - g_string_append_printf(info_text, "%s: %s", QQ_NUMBER, info->uid); - append_field_value(info_text, info->nick, QQ_NICKNAME, NULL, 0); - append_field_value(info_text, info->name, QQ_NAME, NULL, 0); - append_field_value(info_text, info->age, QQ_AGE, NULL, 0); - append_field_value(info_text, info->gender, QQ_GENDER, genders, QQ_GENDER_SIZE); - append_field_value(info_text, info->country, QQ_COUNTRY, NULL, 0); - append_field_value(info_text, info->province, QQ_PROVINCE, NULL, 0); - append_field_value(info_text, info->city, QQ_CITY, NULL, 0); + gaim_notify_user_info_add_pair(user_info, QQ_NUMBER, info->uid); + + append_field_value(user_info, info->nick, QQ_NICKNAME, NULL, 0); + append_field_value(user_info, info->name, QQ_NAME, NULL, 0); + append_field_value(user_info, info->age, QQ_AGE, NULL, 0); + append_field_value(user_info, info->gender, QQ_GENDER, genders, QQ_GENDER_SIZE); + append_field_value(user_info, info->country, QQ_COUNTRY, NULL, 0); + append_field_value(user_info, info->province, QQ_PROVINCE, NULL, 0); + append_field_value(user_info, info->city, QQ_CITY, NULL, 0); - extra_info = g_string_new(""); - g_string_append_printf(extra_info, "

%s
", QQ_ADDITIONAL_INFORMATION); - len = extra_info->len; - append_field_value(extra_info, info->horoscope, QQ_HOROSCOPE, horoscope_names, QQ_HOROSCOPE_SIZE); - append_field_value(extra_info, info->occupation, QQ_OCCUPATION, NULL, 0); - append_field_value(extra_info, info->zodiac, QQ_ZODIAC, zodiac_names, QQ_ZODIAC_SIZE); - append_field_value(extra_info, info->blood, QQ_BLOOD, blood_types, QQ_BLOOD_SIZE); - append_field_value(extra_info, info->college, QQ_COLLEGE, NULL, 0); - append_field_value(extra_info, info->email, QQ_EMAIL, NULL, 0); - append_field_value(extra_info, info->address, QQ_ADDRESS, NULL, 0); - append_field_value(extra_info, info->zipcode, QQ_ZIPCODE, NULL, 0); - append_field_value(extra_info, info->hp_num, QQ_CELL, NULL, 0); - append_field_value(extra_info, info->tel, QQ_TELEPHONE, NULL, 0); - append_field_value(extra_info, info->homepage, QQ_HOMEPAGE, NULL, 0); - if (len != extra_info->len) - g_string_append(info_text, extra_info->str); - g_string_free(extra_info, TRUE); + gaim_notify_user_info_add_section_header(user_info, QQ_ADDITIONAL_INFORMATION); + + has_extra_info |= append_field_value(user_info, info->horoscope, QQ_HOROSCOPE, horoscope_names, QQ_HOROSCOPE_SIZE); + has_extra_info |= append_field_value(user_info, info->occupation, QQ_OCCUPATION, NULL, 0); + has_extra_info |= append_field_value(user_info, info->zodiac, QQ_ZODIAC, zodiac_names, QQ_ZODIAC_SIZE); + has_extra_info |= append_field_value(user_info, info->blood, QQ_BLOOD, blood_types, QQ_BLOOD_SIZE); + has_extra_info |= append_field_value(user_info, info->college, QQ_COLLEGE, NULL, 0); + has_extra_info |= append_field_value(user_info, info->email, QQ_EMAIL, NULL, 0); + has_extra_info |= append_field_value(user_info, info->address, QQ_ADDRESS, NULL, 0); + has_extra_info |= append_field_value(user_info, info->zipcode, QQ_ZIPCODE, NULL, 0); + has_extra_info |= append_field_value(user_info, info->hp_num, QQ_CELL, NULL, 0); + has_extra_info |= append_field_value(user_info, info->tel, QQ_TELEPHONE, NULL, 0); + has_extra_info |= append_field_value(user_info, info->homepage, QQ_HOMEPAGE, NULL, 0); + + if (!has_extra_info) + gaim_notify_user_info_remove_last_item(user_info); intro = field_value(info->intro, NULL, 0); if (intro) { - g_string_append_printf(info_text, "

%s

", QQ_INTRO); - g_string_append(info_text, intro); + gaim_notify_user_info_add_pair(user_info, QQ_INTRO, intro); } /* for debugging */ @@ -227,7 +229,7 @@ append_field_value(info_text, info->unknown6, "unknown6", NULL, 0); */ - return info_text; + return user_info; } /* send a packet to get detailed information of uid */ @@ -658,7 +660,7 @@ qq_data *qd; contact_info *info; GList *list, *query_list; - GString *info_text; + GaimNotifyUserInfo *user_info; g_return_if_fail(buf != NULL && buf_len != 0); @@ -689,9 +691,9 @@ query = (qq_info_query *) query_list->data; if (query->uid == atoi(info->uid)) { if (query->show_window) { - info_text = info_to_str(info); - gaim_notify_userinfo(gc, info->uid, info_text->str, NULL, NULL); - g_string_free(info_text, TRUE); + user_info = info_to_notify_user_info(info); + gaim_notify_userinfo(gc, info->uid, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); } else if (query->modify_info) { create_modify_info_dialogue(gc, info); } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/qq/qq.c --- a/libgaim/protocols/qq/qq.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/qq/qq.c Sun Dec 10 02:53:09 2006 +0000 @@ -191,10 +191,11 @@ /* a floating text when mouse is on the icon, show connection status here */ -static void _qq_tooltip_text(GaimBuddy *b, GString *tooltip, gboolean full) +static void _qq_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { qq_buddy *q_bud; gchar *ip_str; + char *tmp, *tmp2; g_return_if_fail(b != NULL); @@ -205,27 +206,40 @@ { ip_str = gen_ip_str(q_bud->ip); if (strlen(ip_str) != 0) { - g_string_append_printf(tooltip, _("\n%s Address: %s:%d"), - (q_bud->comm_flag & QQ_COMM_FLAG_TCP_MODE) - ? "TCP" : "UDP", ip_str, q_bud->port); + tmp = g_strdup_printf(_("%s Address"), + ((q_bud->comm_flag & QQ_COMM_FLAG_TCP_MODE) ? "TCP" : "UDP")); + tmp2 = g_strdup_printf("%s:%d", ip_str, q_bud->port); + gaim_notify_user_info_add_pair(user_info, tmp, tmp2); + g_free(tmp2); + g_free(tmp); } g_free(ip_str); - g_string_append_printf(tooltip, _("\nAge: %d"), q_bud->age); + + tmp = g_strdup_printf("%d", q_bud->age); + gaim_notify_user_info_add_pair(user_info, _("Age"), tmp); + g_free(tmp); + switch (q_bud->gender) { case QQ_BUDDY_GENDER_GG: - g_string_append(tooltip, _("\nGender: Male")); + gaim_notify_user_info_add_pair(user_info, _("Gender"), _("Male")); break; case QQ_BUDDY_GENDER_MM: - g_string_append(tooltip, _("\nGender: Female")); + gaim_notify_user_info_add_pair(user_info, _("Gender"), _("Female")); break; case QQ_BUDDY_GENDER_UNKNOWN: - g_string_append(tooltip, _("\nGender: Unknown")); + gaim_notify_user_info_add_pair(user_info, _("Gender"), _("Unknown")); break; default: - g_string_append_printf(tooltip, _("\nGender: ERROR(%d)"), q_bud->gender); + tmp = g_strdup_printf("Error (%d)", q_bud->gender); + gaim_notify_user_info_add_pair(user_info, _("Gender"), tmp); + g_free(tmp); } - if (q_bud->level) - g_string_append_printf(tooltip, _("\nLevel: %d"), q_bud->level); + + if (q_bud->level) { + tmp = g_strdup_printf("%d", q_bud->level); + gaim_notify_user_info_add_pair(user_info, _("Level"), tmp); + g_free(tmp); + } /* For debugging */ /* g_string_append_printf(tooltip, "\nFlag: %01x", q_bud->flag1); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/sametime/sametime.c --- a/libgaim/protocols/sametime/sametime.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/sametime/sametime.c Sun Dec 10 02:53:09 2006 +0000 @@ -3250,7 +3250,7 @@ } -static void mw_prpl_tooltip_text(GaimBuddy *b, GString *str, gboolean full) { +static void mw_prpl_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { GaimConnection *gc; struct mwGaimPluginData *pd; struct mwAwareIdBlock idb = { mwAware_USER, b->name, NULL }; @@ -3267,22 +3267,22 @@ if(message != NULL && gaim_utf8_strcasecmp(status, message)) { tmp = g_markup_escape_text(message, -1); - g_string_append_printf(str, _("\n%s: %s"), status, tmp); + gaim_notify_user_info_add_pair(user_info, status, tmp); g_free(tmp); } else { - g_string_append_printf(str, _("\nStatus: %s"), status); + gaim_notify_user_info_add_pair(user_info, _("Status"), status); } if(full) { tmp = user_supports_text(pd->srvc_aware, b->name); if(tmp) { - g_string_append_printf(str, _("\nSupports: %s"), tmp); + gaim_notify_user_info_add_pair(user_info, _("Supports"), tmp); g_free(tmp); } if(buddy_is_external(b)) { - g_string_append(str, _("\nExternal User")); + gaim_notify_user_info_add_pair(user_info, NULL, _("External User")); } } } @@ -4111,9 +4111,9 @@ struct mwGaimPluginData *pd; GaimAccount *acct; GaimBuddy *b; - - GString *str; - const char *tmp; + GaimNotifyUserInfo *user_info; + char *tmp; + const char *tmp2; g_return_if_fail(who != NULL); g_return_if_fail(*who != '\0'); @@ -4122,64 +4122,57 @@ acct = gaim_connection_get_account(gc); b = gaim_find_buddy(acct, who); - - str = g_string_new(NULL); + user_info = gaim_notify_user_info_new(); if(gaim_str_has_prefix(who, "@E ")) { - g_string_append(str, _("External User
")); + gaim_notify_user_info_add_pair(user_info, _("External User"), NULL); } - g_string_append_printf(str, _("User ID: %s
"), who); + gaim_notify_user_info_add_pair(user_info, _("User ID"), who); if(b) { guint32 type; if(b->server_alias) { - g_string_append_printf(str, _("Full Name: %s
"), - b->server_alias); + gaim_notify_user_info_add_pair(user_info, _("Full Name"), b->server_alias); } type = gaim_blist_node_get_int((GaimBlistNode *) b, BUDDY_KEY_CLIENT); if(type) { - g_string_append(str, _("Last Known Client: ")); - - tmp = mw_client_name(type); - if(tmp) { - g_string_append(str, tmp); - g_string_append(str, "
"); - - } else { - g_string_append_printf(str, _("Unknown (0x%04x)
"), type); - } + tmp = g_strdup(mw_client_name(type)); + if (!tmp) + tmp = g_strdup_printf(_("Unknown (0x%04x)
"), type); + + gaim_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp); + + g_free(tmp); } } - + tmp = user_supports_text(pd->srvc_aware, who); if(tmp) { - g_string_append_printf(str, _("Supports: %s
"), tmp); - g_free((char *) tmp); + gaim_notify_user_info_add_pair(user_info, _("Supports"), tmp); + g_free(tmp); } if(b) { - tmp = status_text(b); - g_string_append_printf(str, _("Status: %s"), tmp); - - g_string_append(str, "
"); - - tmp = mwServiceAware_getText(pd->srvc_aware, &idb); - if(tmp) { - tmp = g_markup_escape_text(tmp, -1); - g_string_append(str, tmp); - g_free((char *) tmp); + gaim_notify_user_info_add_pair(user_info, _("Status"), status_text(b)); + + /* XXX Is this adding a status message in its own section rather than with the "Status" label? */ + tmp2 = mwServiceAware_getText(pd->srvc_aware, &idb); + if(tmp2) { + tmp = g_markup_escape_text(tmp2, -1); + gaim_notify_user_info_add_section_break(user_info); + gaim_notify_user_info_add_pair(user_info, NULL, tmp); + g_free(tmp); } } /* @todo emit a signal to allow a plugin to override the display of this notification, so that it can create its own */ - gaim_notify_userinfo(gc, who, str->str, NULL, NULL); - - g_string_free(str, TRUE); + gaim_notify_userinfo(gc, who, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/yahoo/yahoo.c --- a/libgaim/protocols/yahoo/yahoo.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/yahoo/yahoo.c Sun Dec 10 02:53:09 2006 +0000 @@ -2983,7 +2983,7 @@ } } -void yahoo_tooltip_text(GaimBuddy *b, GString *str, gboolean full) +void yahoo_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full) { YahooFriend *f; char *escaped; @@ -3024,14 +3024,13 @@ if (status != NULL) { escaped = g_markup_escape_text(status, strlen(status)); - g_string_append_printf(str, _("\n%s: %s"), _("Status"), escaped); + gaim_notify_user_info_add_pair(user_info, _("Status"), escaped); g_free(status); g_free(escaped); } if (presence != NULL) - g_string_append_printf(str, _("\n%s: %s"), - _("Presence"), presence); + gaim_notify_user_info_add_pair(user_info, _("Presence"), presence); } static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data) diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/yahoo/yahoo.h --- a/libgaim/protocols/yahoo/yahoo.h Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/yahoo/yahoo.h Sun Dec 10 02:53:09 2006 +0000 @@ -199,7 +199,7 @@ char *yahoo_string_decode(GaimConnection *gc, const char *str, gboolean utf8); /* previously-static functions, now needed for yahoo_profile.c */ -void yahoo_tooltip_text(GaimBuddy *b, GString *str, gboolean full); +void yahoo_tooltip_text(GaimBuddy *b, GaimNotifyUserInfo *user_info, gboolean full); /* yahoo_profile.c */ void yahoo_get_info(GaimConnection *gc, const char *name); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/yahoo/yahoo_profile.c --- a/libgaim/protocols/yahoo/yahoo_profile.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/yahoo/yahoo_profile.c Sun Dec 10 02:53:09 2006 +0000 @@ -89,11 +89,10 @@ typedef struct { YahooGetInfoData *info_data; + GaimNotifyUserInfo *user_info; char *url_buffer; - GString *s; char *photo_url_text; char *profile_url_text; - char *tooltip_text; const profile_strings_node_t *strings; const char *last_updated_string; const char *title; @@ -668,8 +667,7 @@ return str; } -static char *yahoo_tooltip_info_text(YahooGetInfoData *info_data) { - GString *s = g_string_sized_new(80); /* wild guess */ +static void yahoo_extract_user_info_text(GaimNotifyUserInfo *user_info, YahooGetInfoData *info_data) { GaimBuddy *b; YahooFriend *f; @@ -677,37 +675,28 @@ info_data->name); if (b) { - GString *str = g_string_new(""); - char *tmp; - if(b->alias && b->alias[0]) { char *aliastext = g_markup_escape_text(b->alias, -1); - g_string_append_printf(s, _("Alias: %s
"), aliastext); + gaim_notify_user_info_add_pair(user_info, _("Alias"), aliastext); g_free(aliastext); } #if 0 if (b->idle > 0) { char *idletime = gaim_str_seconds_to_string(time(NULL) - b->idle); - g_string_append_printf(s, _("%s: %s
"), _("Idle"), - idletime); + gaim_notify_user_info_add_pair(user_info, _("Idle"), idletime); g_free(idletime); } #endif - yahoo_tooltip_text(b, str, TRUE); - tmp = gaim_strreplace((*str->str == '\n' ? str->str + 1 : str->str), - "\n", "
"); - g_string_free(str, TRUE); - g_string_append_printf(s, "%s
", tmp); - g_free(tmp); + /* Add the normal tooltip pairs */ + yahoo_tooltip_text(b, user_info, TRUE); if ((f = yahoo_friend_find(info_data->gc, b->name))) { const char *ip; if ((ip = yahoo_friend_get_ip(f))) - g_string_append_printf(s, _("IP Address: %s
"), ip); + gaim_notify_user_info_add_pair(user_info, _("IP Address"), ip); } } - return g_string_free(s, FALSE); } #if PHOTO_SUPPORT @@ -752,6 +741,7 @@ const gchar *url_text, size_t len, const gchar *error_message) { YahooGetInfoData *info_data = (YahooGetInfoData *)user_data; + GaimNotifyUserInfo *user_info; char *p; char buf[1024]; #if PHOTO_SUPPORT @@ -766,7 +756,7 @@ const char *last_updated_string = NULL; char *url_buffer; GString *s; - char *tooltip_text = NULL; + char *tmp; char *profile_url_text = NULL; int lang, strid; struct yahoo_data *yd; @@ -779,25 +769,24 @@ yd = info_data->gc->proto_data; yd->url_datas = g_slist_remove(yd->url_datas, url_data); + user_info = gaim_notify_user_info_new(); + title = yd->jp ? _("Yahoo! Japan Profile") : _("Yahoo! Profile"); /* Get the tooltip info string */ - tooltip_text = yahoo_tooltip_info_text(info_data); + yahoo_extract_user_info_text(user_info, info_data); /* We failed to grab the profile URL. This is not expected to actually * happen except under unusual error conditions, as Yahoo is observed * to send back HTML, with a 200 status code. */ if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) { - g_snprintf(buf, 1024, "%s%s", - tooltip_text, _("Error retrieving profile")); - + gaim_notify_user_info_add_pair(user_info, _("Error retrieving profile"), NULL); gaim_notify_userinfo(info_data->gc, info_data->name, - buf, NULL, NULL); - + user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); g_free(profile_url_text); - g_free(tooltip_text); g_free(info_data->name); g_free(info_data); return; @@ -821,20 +810,21 @@ p = strstr(url_text, "Adult Content Warning"); /* TITLE element */ } if (p) { - g_snprintf(buf, 1024, "%s%s

" - "%s
%s", - tooltip_text, - _("Sorry, profiles marked as containing adult content " - "are not supported at this time."), - _("If you wish to view this profile, " - "you will need to visit this link in your web browser"), - profile_url_text, profile_url_text); + tmp = g_strdup_printf("%s

" + "%s
%s", + _("Sorry, profiles marked as containing adult content " + "are not supported at this time."), + _("If you wish to view this profile, " + "you will need to visit this link in your web browser:"), + profile_url_text, profile_url_text); + gaim_notify_user_info_add_pair(user_info, NULL, tmp); + g_free(tmp); gaim_notify_userinfo(info_data->gc, info_data->name, - buf, NULL, NULL); + user_info, NULL, NULL); g_free(profile_url_text); - g_free(tooltip_text); + gaim_notify_user_info_destroy(user_info); g_free(info_data->name); g_free(info_data); return; @@ -908,14 +898,13 @@ info2_data = g_malloc(sizeof(YahooGetInfoStepTwoData)); info2_data->info_data = info_data; info2_data->url_buffer = url_buffer; - info2_data->s = s; info2_data->photo_url_text = photo_url_text; info2_data->profile_url_text = profile_url_text; - info2_data->tooltip_text = tooltip_text; info2_data->strings = strings; info2_data->last_updated_string = last_updated_string; info2_data->title = title; info2_data->profile_state = profile_state; + info2_data->user_info = user_info; /* Try to put the photo in there too, if there's one */ if (photo_url_text) { @@ -953,14 +942,14 @@ char *stripped; int stripped_len; char *last_updated_utf8_string = NULL; + char *tmp; /* Unmarshall the saved state */ YahooGetInfoData *info_data = info2_data->info_data; char *url_buffer = info2_data->url_buffer; - GString *s = info2_data->s; + GaimNotifyUserInfo *user_info = info2_data->user_info; char *photo_url_text = info2_data->photo_url_text; char *profile_url_text = info2_data->profile_url_text; - char *tooltip_text = info2_data->tooltip_text; const profile_strings_node_t *strings = info2_data->strings; const char *last_updated_string = info2_data->last_updated_string; profile_state_t profile_state = info2_data->profile_state; @@ -1013,15 +1002,11 @@ gaim_debug_misc("yahoo", "after utf8 conversion: stripped = (%s)\n", stripped); } - /* gonna re-use the memory we've already got for url_buffer */ - /* no we're not */ - s = g_string_sized_new(strlen(url_buffer)); - if (profile_state == PROFILE_STATE_DEFAULT) { #if 0 /* extract their Yahoo! ID and put it in. Don't bother marking has_info as * true, since the Yahoo! ID will always be there */ - if (!gaim_markup_extract_info_field(stripped, stripped_len, s, + if (!gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->yahoo_id_string, 10, "\n", 0, NULL, _("Yahoo! ID"), 0, NULL, NULL)) ; @@ -1039,48 +1024,51 @@ } else { gaim_debug_info("yahoo", "%s is %d bytes\n", photo_url_text, len); id = gaim_imgstore_add(url_text, len, NULL); - g_string_append_printf(s, "
", id); + + tmp = g_strdup_printf("
", id); + gaim_notify_user_info_add_pair(user_info, NULL, tmp); + g_free(tmp); } } #endif /* PHOTO_SUPPORT */ /* extract their Email address and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->my_email_string, 1, " ", 0, strings->private_string, _("E-Mail"), 0, NULL, NULL); /* extract the Nickname if it exists */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, "Nickname:", 1, "\n", '\n', NULL, _("Nickname"), 0, NULL, NULL); /* extract their RealName and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->realname_string, 1, "\n", '\n', NULL, _("Real Name"), 0, NULL, NULL); /* extract their Location and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->location_string, 2, "\n", '\n', NULL, _("Location"), 0, NULL, NULL); /* extract their Age and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->age_string, 3, "\n", '\n', NULL, _("Age"), 0, NULL, NULL); /* extract their MaritalStatus and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->maritalstatus_string, 3, "\n", '\n', strings->no_answer_string, _("Marital Status"), 0, NULL, NULL); /* extract their Gender and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->gender_string, 3, "\n", '\n', strings->no_answer_string, _("Gender"), 0, NULL, NULL); /* extract their Occupation and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->occupation_string, 2, "\n", '\n', NULL, _("Occupation"), 0, NULL, NULL); @@ -1093,15 +1081,15 @@ * the "Description" ("Self PR") heading instead of "Links".) */ - if (!gaim_markup_extract_info_field(stripped, stripped_len, s, + if (!gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->hobbies_string, 1, strings->latest_news_string, '\n', "\n", _("Hobbies"), 0, NULL, NULL)) { - if (!gaim_markup_extract_info_field(stripped, stripped_len, s, + if (!gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->hobbies_string, 1, strings->favorite_quote_string, '\n', "\n", _("Hobbies"), 0, NULL, NULL)) { - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->hobbies_string, 1, strings->links_string, '\n', "\n", _("Hobbies"), 0, NULL, NULL); } @@ -1111,18 +1099,18 @@ else found = TRUE; - if (!gaim_markup_extract_info_field(stripped, stripped_len, s, + if (!gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->latest_news_string, 1, strings->favorite_quote_string, '\n', "\n", _("Latest News"), 0, NULL, NULL)) { - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->latest_news_string, 1, strings->links_string, '\n', "\n", _("Latest News"), 0, NULL, NULL); } else found = TRUE; - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->favorite_quote_string, 1, strings->links_string, '\n', "\n", _("Favorite Quote"), 0, NULL, NULL); @@ -1136,7 +1124,7 @@ strstr(stripped, strings->no_home_page_specified_string); if(!p) { - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->home_page_string, 1, "\n", 0, NULL, _("Home Page"), 1, NULL, NULL); } @@ -1151,16 +1139,16 @@ strstr(stripped,strings->no_cool_link_specified_string); if (!p) { - if (gaim_markup_extract_info_field(stripped, stripped_len, s, + if (gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->cool_link_1_string, 1, "\n", 0, NULL, _("Cool Link 1"), 1, NULL, NULL)) { found = TRUE; - if (gaim_markup_extract_info_field(stripped, stripped_len, s, + if (gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->cool_link_2_string, 1, "\n", 0, NULL, _("Cool Link 2"), 1, NULL, NULL)) { - gaim_markup_extract_info_field(stripped, stripped_len, s, + gaim_markup_extract_info_field(stripped, stripped_len, user_info, strings->cool_link_3_string, 1, "\n", 0, NULL, _("Cool Link 3"), 1, NULL, NULL); } @@ -1169,12 +1157,12 @@ if (last_updated_utf8_string != NULL) { /* see if Member Since is there, and if so, extract it. */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, "Member Since:", 1, last_updated_utf8_string, '\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat); /* extract the Last Updated date and put it in */ - found |= gaim_markup_extract_info_field(stripped, stripped_len, s, + found |= gaim_markup_extract_info_field(stripped, stripped_len, user_info, last_updated_utf8_string, 1, " ", '\n', NULL, _("Last Update"), 0, NULL, yahoo_info_date_reformat); } @@ -1182,13 +1170,15 @@ if(!found) { - g_string_append_printf(s, "
"); - g_string_append_printf(s, _("User information for %s unavailable"), + GString *str = g_string_new(""); + + g_string_append_printf(str, "
"); + g_string_append_printf(str, _("User information for %s unavailable"), info_data->name); - g_string_append_printf(s, "
"); + g_string_append_printf(str, "

"); if (profile_state == PROFILE_STATE_UNKNOWN_LANGUAGE) { - g_string_append_printf(s, "%s

", + g_string_append_printf(str, "%s

", _("Sorry, this profile seems to be in a language " "or format that is not supported at this time.")); @@ -1204,7 +1194,7 @@ */ f = yahoo_friend_find(b->account->gc, b->name); } - g_string_append_printf(s, "%s

", + g_string_append_printf(str, "%s

", f? _("Could not retrieve the user's profile. " "This most likely is a temporary server-side problem. " "Please try again later."): @@ -1214,36 +1204,30 @@ "profile. If you know that the user exists, " "please try again later.")); } else { - g_string_append_printf(s, "%s

", + g_string_append_printf(str, "%s

", _("The user's profile is empty.")); } + + gaim_notify_user_info_add_pair(user_info, NULL, str->str); + g_string_free(str, TRUE); } /* put a link to the actual profile URL */ - g_string_append_printf(s, _("%s: "), _("Profile URL")); - g_string_append_printf(s, "
%s
", - profile_url_text, profile_url_text); + tmp = g_strdup_printf("%s", profile_url_text, profile_url_text); + gaim_notify_user_info_add_pair(user_info, _("Profile URL"), tmp); + g_free(tmp); - /* finish off the html at the end */ - g_string_append(s, ""); g_free(stripped); - /* Put the Yahoo! ID, nickname, idle time, and status message in */ - g_string_prepend(s, tooltip_text); - - /* finish off the html at the beginning */ - g_string_prepend(s, ""); - /* show it to the user */ gaim_notify_userinfo(info_data->gc, info_data->name, - s->str, NULL, NULL); + user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); g_free(last_updated_utf8_string); g_free(url_buffer); g_free(fudged_buffer); - g_string_free(s, TRUE); g_free(profile_url_text); - g_free(tooltip_text); g_free(info_data->name); g_free(info_data); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/protocols/zephyr/zephyr.c --- a/libgaim/protocols/zephyr/zephyr.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/protocols/zephyr/zephyr.c Sun Dec 10 02:53:09 2006 +0000 @@ -781,22 +781,27 @@ if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user)) { ZLocations_t locs; int one = 1; - GString *str = g_string_new(""); + GaimNotifyUserInfo *user_info = gaim_notify_user_info_new(); + char *tmp; - g_string_append_printf(str, _("User: %s
"), b ? b->name : user); + gaim_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user)); if (b && b->alias) - g_string_append_printf(str, _("Alias: %s
"), b->alias); + gaim_notify_user_info_add_pair(user_info, _("Alias"), b->alias); + if (!nlocs) { - g_string_append_printf(str, _("
Hidden or not logged-in")); + gaim_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); } for (; nlocs > 0; nlocs--) { /* XXX add real error reporting */ + ZGetLocations(&locs, &one); - g_string_append_printf(str, _("
At %s since %s"), locs.host, locs.time); + tmp = g_strdup_printf(_("
At %s since %s"), locs.host, locs.time); + gaim_notify_user_info_add_pair(user_info, _("Location"), tmp); + g_free(tmp); } - gaim_notify_userinfo(gc, b ? b->name : user, - str->str, NULL, NULL); - g_string_free(str, TRUE); + gaim_notify_userinfo(gc, (b ? b->name : user), + user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); } else { if (nlocs>0) gaim_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL); @@ -1198,23 +1203,27 @@ } if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user) || pending_zloc(zephyr,local_zephyr_normalize(zephyr,user))){ - GString *str = g_string_new(""); + GaimNotifyUserInfo *user_info = gaim_notify_user_info_new(); + char *tmp; - g_string_append_printf(str, _("User: %s
"), b ? b->name : user); + gaim_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user)); + if (b && b->alias) - g_string_append_printf(str, _("Alias: %s
"), b->alias); + gaim_notify_user_info_add_pair(user_info, _("Alias"), b->alias); if (!nlocs) { - g_string_append_printf(str, _("
Hidden or not logged-in")); + gaim_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); } else { - g_string_append_printf(str, _("
At %s since %s"), - tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents, - tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents); + tmp = g_strdup_printf(_("
At %s since %s"), + tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents, + tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents); + gaim_notify_user_info_add_pair(user_info, _("Location"), tmp); + g_free(tmp); } gaim_notify_userinfo(gc, b ? b->name : user, - str->str, NULL, NULL); - g_string_free(str, TRUE); + user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); } else { if (nlocs>0) gaim_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL); diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/prpl.h --- a/libgaim/prpl.h Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/prpl.h Sun Dec 10 02:53:09 2006 +0000 @@ -66,6 +66,7 @@ #include "blist.h" #include "conversation.h" #include "ft.h" +#include "notify.h" #include "proxy.h" #include "plugin.h" #include "roomlist.h" @@ -190,7 +191,7 @@ /** * Allows the prpl to add text to a buddy's tooltip. */ - void (*tooltip_text)(GaimBuddy *buddy, GString *str, gboolean full); + void (*tooltip_text)(GaimBuddy *buddy, GaimNotifyUserInfo *user_info, gboolean full); /** * This must be implemented, and must add at least the offline diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/util.c --- a/libgaim/util.c Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/util.c Sun Dec 10 02:53:09 2006 +0000 @@ -1061,7 +1061,7 @@ } gboolean -gaim_markup_extract_info_field(const char *str, int len, GString *dest, +gaim_markup_extract_info_field(const char *str, int len, GaimNotifyUserInfo *user_info, const char *start_token, int skip, const char *end_token, char check_value, const char *no_value_token, @@ -1072,7 +1072,7 @@ const char *p, *q; g_return_val_if_fail(str != NULL, FALSE); - g_return_val_if_fail(dest != NULL, FALSE); + g_return_val_if_fail(user_info != NULL, FALSE); g_return_val_if_fail(start_token != NULL, FALSE); g_return_val_if_fail(end_token != NULL, FALSE); g_return_val_if_fail(display_name != NULL, FALSE); @@ -1110,11 +1110,11 @@ (no_value_token && strncmp(p, no_value_token, strlen(no_value_token))))) { - g_string_append_printf(dest, _("%s: "), display_name); + GString *dest = g_string_new(""); if (is_link) { - g_string_append(dest, "
\n"); + gaim_notify_user_info_add_pair(user_info, display_name, dest->str); + g_string_free(dest, TRUE); return TRUE; } diff -r 4b319b19aa24 -r b81e4e44b509 libgaim/util.h --- a/libgaim/util.h Sat Dec 09 20:20:17 2006 +0000 +++ b/libgaim/util.h Sun Dec 10 02:53:09 2006 +0000 @@ -365,8 +365,8 @@ * * @param str The string to parse. * @param len The size of str. - * @param dest The destination GString to append the new - * field info to. + * @param user_info The destination GaimNotifyUserInfo to which the new + * field info should be added. * @param start_token The beginning token. * @param skip The number of characters to skip after the * start token. @@ -380,7 +380,7 @@ * * @return TRUE if successful, or FALSE otherwise. */ -gboolean gaim_markup_extract_info_field(const char *str, int len, GString *dest, +gboolean gaim_markup_extract_info_field(const char *str, int len, GaimNotifyUserInfo *user_info, const char *start_token, int skip, const char *end_token, char check_value, const char *no_value_token,