From: <ev...@us...> - 2006-12-10 02:53:12
|
Revision: 17929 http://svn.sourceforge.net/gaim/?rev=17929&view=rev Author: evands Date: 2006-12-09 18:53:09 -0800 (Sat, 09 Dec 2006) Log Message: ----------- 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: <b>label</b>: value <b>label</b>: value format as was passed by convention from prpls in the past. Modified Paths: -------------- trunk/libgaim/notify.c trunk/libgaim/notify.h trunk/libgaim/protocols/gg/gg.c trunk/libgaim/protocols/irc/msgs.c trunk/libgaim/protocols/jabber/buddy.c trunk/libgaim/protocols/jabber/jabber.c trunk/libgaim/protocols/msn/msn.c trunk/libgaim/protocols/novell/novell.c trunk/libgaim/protocols/oscar/oscar.c trunk/libgaim/protocols/oscar/oscarcommon.h trunk/libgaim/protocols/qq/buddy_info.c trunk/libgaim/protocols/qq/qq.c trunk/libgaim/protocols/sametime/sametime.c trunk/libgaim/protocols/yahoo/yahoo.c trunk/libgaim/protocols/yahoo/yahoo.h trunk/libgaim/protocols/yahoo/yahoo_profile.c trunk/libgaim/protocols/zephyr/zephyr.c trunk/libgaim/prpl.h trunk/libgaim/util.c trunk/libgaim/util.h Modified: trunk/libgaim/notify.c =================================================================== --- trunk/libgaim/notify.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/notify.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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, "<b>%s</b>", 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, "<HR>"); +} + void * gaim_notify_uri(void *handle, const char *uri) { Modified: trunk/libgaim/notify.h =================================================================== --- trunk/libgaim/notify.h 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/notify.h 2006-12-10 02:53:09 UTC (rev 17929) @@ -29,9 +29,11 @@ #include <glib-object.h> #include <glib.h> +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. Modified: trunk/libgaim/protocols/gg/gg.c =================================================================== --- trunk/libgaim/protocols/gg/gg.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/gg/gg.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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<b>%s:</b> %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<b>%s:</b>: %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<b>%s:</b> %s", - _("Status"), name); + } else { + gaim_notify_user_info_add_pair(user_info, _("Status"), name); } } /* }}} */ Modified: trunk/libgaim/protocols/irc/msgs.c =================================================================== --- trunk/libgaim/protocols/irc/msgs.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/irc/msgs.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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, _("<b>%s:</b> %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 ? _(" <i>(ircop)</i>") : ""), + (irc->whois.identified ? _(" <i>(identified)</i>") : "")); + gaim_notify_user_info_add_pair(user_info, _("Nick"), tmp); + g_free(tmp2); g_free(tmp); - g_string_append_printf(info, "%s%s<br>", - irc->whois.ircop ? _(" <i>(ircop)</i>") : "", - irc->whois.identified ? _(" <i>(identified)</i>") : ""); + 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, _("<b>%s:</b> %s<br>"), _("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, _("<b>%s:</b> %s<br>"), _("Username"), irc->whois.userhost); - g_string_append_printf(info, _("<b>%s:</b> %s<br>"), _("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, _("<b>%s:</b> %s"), _("Server"), irc->whois.server); - g_string_append_printf(info, " (%s)<br>", 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, _("<b>%s:</b> %s<br>"), _("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, _("<b>Idle for:</b> %s<br>"), timex); + gaim_notify_user_info_add_pair(user_info, _("Idle for"), timex); g_free(timex); - g_string_append_printf(info, _("<b>%s:</b> %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, _("<br><b>Defining adjective:</b> Glorious<br>")); + gaim_notify_user_info_add_pair(user_info, + _("<b>Defining adjective:</b>"), _("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)); } Modified: trunk/libgaim/protocols/jabber/buddy.c =================================================================== --- trunk/libgaim/protocols/jabber/buddy.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/jabber/buddy.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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, "<b>%s:</b> %s%s%s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("Resource"), jbr->name); - g_string_append_printf(info_text, "<b>%s:</b> %d<br/>", - _("Priority"), jbr->priority); - g_string_append_printf(info_text, "<b>%s:</b> %s%s%s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("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, "<b>%s:</b> %s %s<br/>", - _("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, "<b>%s:</b> %s<br/>", - _("Operating System"), jbr->client.os); + gaim_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os); } } - - g_string_append_printf(info_text, "<br/>"); } } 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); Modified: trunk/libgaim/protocols/jabber/jabber.c =================================================================== --- trunk/libgaim/protocols/jabber/jabber.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/jabber/jabber.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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<b>%s:</b> %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<b>%s%s:</b> %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<b>%s:</b> %s", - _("Error"), jb->error_msg); + gaim_notify_user_info_add_pair(user_info, _("Error"), jb->error_msg); } } } Modified: trunk/libgaim/protocols/msn/msn.c =================================================================== --- trunk/libgaim/protocols/msn/msn.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/msn/msn.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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<b>%s:</b> %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<b>%s:</b> %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<b>%s:</b> %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, _("<b>Alias:</b> %s<br>"), 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, _("<b>%s:</b> "), _("Nickname")); - g_string_append_printf(s, "<font sml=\"msn\">%s</font><br>", - nicktext); + tmp = g_strdup_printf("<font sml=\"msn\">%s</font><br>", 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", "<br>"); - g_string_free(str, TRUE); - g_string_append_printf(s, "%s<br>", 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, "<html><body>%s<b>%s</b></body></html>", - tooltip_text, _("Error retrieving profile")); + tmp = g_strdup_printf("<b>%s</b>", _("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 "<br>\n" */ - g_string_truncate(s, strlen(s->str) - 5); - g_string_append_printf(s2, _("%s<b>General</b><br>%s"), - (*tooltip_text) ? "<hr>" : "", 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, _("%s<b>Social</b><br>%s"), has_info ? "<br><hr>" : "", 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(_("<br><b>Personal</b><br>%s"), s->str); - s = g_string_truncate(s, 0); - sect_info = FALSE; has_info = TRUE; + sect_info = FALSE; + 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(_("<br><b>Business</b><br>%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 "<br>\n" */ - g_string_truncate(s, strlen(s->str) - 5); - - has_info = TRUE; - g_string_append_printf(s2, _("<hr><b>Contact Info</b>%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), - "<b>%s:</b><br><a href=\"%s\">%s</a><br>\n", - _("Homepage"), user_url, user_url); - - g_string_append(s, buf); - + tmp = g_strdup_printf("<a href=\"%s\">%s</a>", 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,26 +1801,23 @@ 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, "<br><b>%s</b><br>%s<br><br>", - _("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, _("<hr><b>%s:</b> "), _("Profile URL")); - g_string_append_printf(s, "<br><a href=\"%s%s\">%s%s</a><br>", - PROFILE_URL, info_data->name, PROFILE_URL, info_data->name); + tmp = g_strdup_printf("<a href=\"%s%s\">%s%s</a>", + PROFILE_URL, info_data->name, PROFILE_URL, info_data->name); + gaim_notify_user_info_add_pair(user_info, _("Profile URL"), tmp); + g_free(tmp); - /* Finish it off, and show it to them */ - g_string_append(s, "</body></html>\n"); - #if PHOTO_SUPPORT /* Find the URL to the photo; must be before the marshalling [Bug 994207] */ photo_url_text = msn_get_photo_url(url_text); @@ -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), "<img id=\"%d\"><br>", 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 + gaim_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL); - g_string_prepend(s, tooltip_text); - gaim_notify_userinfo(info_data->gc, info_data->name, s->str, 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 Modified: trunk/libgaim/protocols/novell/novell.c =================================================================== --- trunk/libgaim/protocols/novell/novell.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/novell/novell.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -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, "<b>%s:</b> %s<br>", 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, "<b>%s:</b> %s<br>", - 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, "<b>%s:</b> %s<br>", 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, "<b>%s:</b> %s<br>", - 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<b>%s:</b> %s" - "\n<b>%s:</b> %s", - _("Status"), status_str, - _("Message"), text); - else - g_string_append_printf(str, "\n<b>%s:</b> %s", - _("Status"), status_str); + gaim_notify_user_info_add_pair(user_info, _("Message"), text); } } } Modified: trunk/libgaim/protocols/oscar/oscar.c =================================================================== --- trunk/libgaim/protocols/oscar/oscar.c 2006-12-09 20:20:17 UTC (rev 17928) +++ trunk/libgaim/protocols/oscar/oscar.c 2006-12-10 02:53:09 UTC (rev 17929) @@ -705,15 +705,26 @@ } 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<b>%s:</b> %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); + } +} + +static void oscar_string_convert_and_append(GaimAccount *account, GString *str, const char *newline, const char *name, const char *value) { @@ -725,8 +736,20 @@ } } -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; GaimPresence *presence = NULL; @@ -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; + char *statusmsg, **splitmsg; + GaimNotifyUserInfo *user_info; - title = g_strdup_printf(_("Info for %s"), who); - /* 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(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, statusmsg, g_strjoinv("<BR>", 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("<BR>", splitmsg)); + g_free(statusmsg); g_strfreev(splitmsg); - gaim_notify_userinfo(gc, who, dialogmsg, NULL, NULL); + gaim_notify_userinfo(gc, who, user_info, NULL, NULL); + gaim_notify_user_info_destroy(user_info); - g_free(title); - g_free(dialogmsg); } 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, "<b>%s:</b> %s", _("Screen Name"), userinfo->sn); - g_string_append_printf(str, "\n<br><b>%s</b>: %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<br>", _("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<br>", _("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<br>", _("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<br>", _("Idle"), tmp); + oscar_user_info_add_pair(user_info, _("Idle"), tmp); g_free(tmp); } - oscar_string_append_info(gc, str, "\n<br>", 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<br>", _("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<hr>%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<hr>%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, "<b>%s:</b> %s", _("UIN"), who); - oscar_string_convert_and_append(account, str, "\n<br>", _("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<br>", _("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<br>", _("First Name"), info->first); - oscar_string_convert_and_append(account, str, "\n<br>", _("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<br><b>%s:</b> <a href=\"mailto:%s\">%s</a>", _("E-Mail Address"), utf8, utf8); + buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", 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<br><b>%s:</b> <a href=\"mailto:%s\">%s</a>", _("E-Mail Address"), utf8, utf8); + buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", 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<br>", _("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<br>", _("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<br>", _("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<br>", _("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<br><b>%s:</b> <a href=\"%s\">%s</a>", _("Personal Web Page"), utf8, utf8); + buf = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8); + gaim_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf); + g_free(buf); g_free(utf8); } - if (info->info && info->info[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->info))) { - g_string_append_printf(str, "<hr><b>%s:</b><br>%s", _("Additional Information"), utf8); - g_free(utf8); - } - g_string_append_printf(str, "<hr>"); + + oscar_user_info_convert_and_add(account, user_info, _("Additional Information"), info->info); + +/* g_string_append_printf(str, "<hr>"); */ + 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, "<b>%s:</b>", _("Home Address")); - oscar_string_convert_and_append(account, str, "\n<br>", _("Address"), info->homeaddr); - oscar_string_convert_and_append(account, str, "\n<br>", _("City"), info->homecity); - oscar_string_convert_and_append(account, str, "\n<br>", _("State"), info->homestate); - oscar_string_convert_and_append(account, str, "\n<br>", _("Zip Code"), info->homezip); - g_string_append_printf(str, "\n<hr>"); + tmp = g_string_sized_new(100); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("Address"), info->homeaddr); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("City"), info->homecity); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("State"), info->homestate); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("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, "<b>%s:</b>", _("Work Address")); - oscar_string_convert_and_append(account, str, "\n<br>", _("Address"), info->workaddr); - oscar_string_convert_and_append(account, str, "\n<br>", _("City"), info->workcity); - oscar_string_convert_and_append(account, str, "\n<br>", _("State"), info->workstate); - oscar_string_convert_and_append(account, str, "\n<br>", _("Zip Code"), info->workzip); - g_string_append_printf(str, "\n<hr>"); + tmp = g_string_sized_new(100); + + oscar_string_convert_and_append(account, tmp, "\n<br>", _("Address"), info->workaddr); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("City"), info->workcity); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("State"), info->workstate); + oscar_string_convert_and_append(account, tmp, "\n<br>", _("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, "<b>%s:</b>", _("Work Information")); - oscar_string_convert_and_append(account... [truncated message content] |