Mercurial > pidgin
changeset 14935:ef80d4c30a90
[gaim-migrate @ 17707]
Change the way tooltips are displayed. This fixes crashes when the tooltip for
a contact grows too large.
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Thu, 09 Nov 2006 00:20:18 +0000 |
parents | 4504a21b1d8f |
children | 5025e146a876 |
files | console/gntblist.c |
diffstat | 1 files changed, 48 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/console/gntblist.c Wed Nov 08 10:22:00 2006 +0000 +++ b/console/gntblist.c Thu Nov 09 00:20:18 2006 +0000 @@ -43,6 +43,7 @@ #include "gntmenuitem.h" #include "gntmenuitemcheck.h" #include "gnttree.h" +#include "gntutils.h" #include "gntwindow.h" #include "gntblist.h" @@ -163,13 +164,6 @@ ggblist->tnode = NULL; } -static gboolean -_draw_tooltip(gpointer data) -{ - draw_tooltip(data); - return FALSE; -} - static void node_remove(GaimBuddyList *list, GaimBlistNode *node) { @@ -193,12 +187,7 @@ node_remove(list, node->parent); } - /* When an account has signed off, it removes one buddy at a time. - * Drawing the tooltip after removing each buddy is expensive. On - * top of that, if the selected buddy belongs to the disconnected - * account, then retreiving the tooltip for that causes crash. So - * let's make sure we wait for all the buddies to be removed first.*/ - g_timeout_add(0, _draw_tooltip, ggblist); + draw_tooltip(ggblist); } static void @@ -1149,14 +1138,24 @@ } } -static void -draw_tooltip(GGBlist *ggblist) +static GString* +make_sure_text_fits(GString *string) +{ + int maxw = getmaxx(stdscr) - 3; + char *str = gnt_util_onscreen_fit_string(string->str, maxw); + string = g_string_assign(string, str); + g_free(str); + return string; +} + +static gboolean +draw_tooltip_real(GGBlist *ggblist) { GaimBlistNode *node; - int x, y, top, width; + int x, y, top, width, w, h; GString *str; GntTree *tree; - GntWidget *widget, *box; + GntWidget *widget, *box, *tv; char *title = NULL; int lastseen = 0; @@ -1165,7 +1164,7 @@ if (!gnt_widget_has_focus(ggblist->tree) || (ggblist->context && !GNT_WIDGET_IS_FLAG_SET(ggblist->context, GNT_WIDGET_INVISIBLE))) - return; + return FALSE; if (ggblist->tooltip) { @@ -1176,7 +1175,7 @@ node = gnt_tree_get_selection_data(tree); if (!node) - return; + return FALSE; str = g_string_new(""); @@ -1192,6 +1191,7 @@ g_string_append_printf(str, _("Nickname: %s\n"), gaim_buddy_get_name(pr)); tooltip_for_buddy(pr, str); for (node = node->child; node; node = node->next) { + GaimBuddy *buddy = (GaimBuddy*)node; if (offline) { int value = gaim_blist_node_get_int(node, "last_seen"); if (value > lastseen) @@ -1199,11 +1199,13 @@ } if (node == (GaimBlistNode*)pr) continue; - if (!showoffline && !GAIM_BUDDY_IS_ONLINE((GaimBuddy*)node)) + if (!gaim_account_is_connected(buddy->account)) + continue; + if (!showoffline && !GAIM_BUDDY_IS_ONLINE(buddy)) continue; str = g_string_append(str, "\n----------\n"); - g_string_append_printf(str, _("Nickname: %s\n"), gaim_buddy_get_name((GaimBuddy*)node)); - tooltip_for_buddy((GaimBuddy*)node, str); + g_string_append_printf(str, _("Nickname: %s\n"), gaim_buddy_get_name(buddy)); + tooltip_for_buddy(buddy, str); } } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { GaimBuddy *buddy = (GaimBuddy *)node; @@ -1230,7 +1232,7 @@ title = g_strdup(gaim_chat_get_name(chat)); } else { g_string_free(str, TRUE); - return; + return FALSE; } if (lastseen > 0) { @@ -1251,19 +1253,41 @@ GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); gnt_box_set_title(GNT_BOX(box), title); - gnt_box_add_widget(GNT_BOX(box), gnt_label_new(str->str)); + str = make_sure_text_fits(str); + gnt_util_get_text_bound(str->str, &w, &h); + h = MAX(2, h); + tv = gnt_text_view_new(); + gnt_widget_set_size(tv, w + 1, h); + gnt_box_add_widget(GNT_BOX(box), tv); gnt_widget_set_position(box, x, y); GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS); GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); gnt_widget_draw(box); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(tv), str->str, GNT_TEXT_FLAG_NORMAL); + gnt_text_view_scroll(GNT_TEXT_VIEW(tv), 0); + g_free(title); g_string_free(str, TRUE); ggblist->tooltip = box; ggblist->tnode = node; gnt_widget_set_name(ggblist->tooltip, "tooltip"); + return FALSE; +} + +static void +draw_tooltip(GGBlist *ggblist) +{ + /* When an account has signed off, it removes one buddy at a time. + * Drawing the tooltip after removing each buddy is expensive. On + * top of that, if the selected buddy belongs to the disconnected + * account, then retreiving the tooltip for that causes crash. So + * let's make sure we wait for all the buddies to be removed first.*/ + int id = g_timeout_add(0, draw_tooltip_real, ggblist); + g_object_set_data_full(G_OBJECT(ggblist->window), "draw_tooltip_calback", + GINT_TO_POINTER(id), (GDestroyNotify)g_source_remove); } static void