Mercurial > pidgin.yaz
changeset 9554:8b2451878e26
[gaim-migrate @ 10387]
" This patch adds chat user status icons (voice / halfop
/ op / founder) to chats
There's a screenshot here, showing ops, voices and
ignored ops and voices
http://nosnilmot.com/gaim/chatusers.png
This required some changes in how the core stores the
list of users in chats to be able to store the status
too, which are detailed below.
I also fixed up some memory leaks as I came across them
(string values returned by gtk_tree_model_get() not
being g_free()'d) and a minor bug in signals-test.c
Conversation API:
Changed:
gaim_conv_chat_add_user() (added flags parameter)
gaim_conv_chat_add_users() now (added GList of flags
parameter)
gaim_conv_chat_get_users() now returns a GList of
GaimChatBuddy's
gaim_conv_chat_set_users() now expects a GList of
GaimChatBuddy's
Added:
gaim_conv_chat_set_user_flags()
gaim_conv_chat_get_user_flags()
gaim_conv_chat_find_user()
gaim_conv_chat_cb_new()
gaim_conv_chat_cb_find()
gaim_conv_chat_cb_destroy()
gaim_conv_chat_cb_get_name()
Conversation UI ops:
added: chat_update_user()
Signals:
Changed: chat-buddy-joining & chat-buddy-joined now
include the user's flags
Added: chat-buddy-flags for when user's flags change
Added:
gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT
(required for the new chat-buddy-flags signal)
Protocol Plugins:
All updated to work with above changes (obviously)
User flags support added to IRC, Jabber and SILC
New Files:
pixmaps/status/default/ voice.svg halfop.svg op.svg
founder.svg
" --Stu Tomlinson
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sat, 17 Jul 2004 18:11:12 +0000 |
parents | 8a64666476e6 |
children | a79e03ef63f6 |
files | ChangeLog doc/conversation-signals.dox pixmaps/status/default/Makefile.am pixmaps/status/default/founder.svg pixmaps/status/default/halfop.svg pixmaps/status/default/ignored.svg pixmaps/status/default/op.svg pixmaps/status/default/voice.svg plugins/ChangeLog.API plugins/signals-test.c src/conversation.c src/conversation.h src/gtkconv.c src/gtkconv.h src/protocols/irc/msgs.c src/protocols/jabber/chat.c src/protocols/jabber/presence.c src/protocols/msn/msn.c src/protocols/msn/switchboard.c src/protocols/napster/napster.c src/protocols/novell/novell.c src/protocols/oscar/oscar.c src/protocols/silc/chat.c src/protocols/silc/ops.c src/protocols/toc/toc.c src/protocols/yahoo/yahoochat.c src/protocols/yahoo/ycht.c src/protocols/zephyr/zephyr.c src/signals.c src/signals.h |
diffstat | 30 files changed, 881 insertions(+), 373 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sat Jul 17 17:08:24 2004 +0000 +++ b/ChangeLog Sat Jul 17 18:11:12 2004 +0000 @@ -4,6 +4,7 @@ New Features: * The autorecon plugin will somewhat remember state information(Yosef Radchenko) + * Visual display of ops/voice/halfops/so on in Chats (Stu Tomlinson) Bug Fixes: * Long buddy lists with irc should cause flooding disconnects less
--- a/doc/conversation-signals.dox Sat Jul 17 17:08:24 2004 +0000 +++ b/doc/conversation-signals.dox Sat Jul 17 18:11:12 2004 +0000 @@ -331,22 +331,41 @@ @signaldef chat-buddy-joining @signalproto -void (*chat_buddy_joining)(GaimConversation *conv, const char *name); +void (*chat_buddy_joining)(GaimConversation *conv, const char *name, + GaimConvChatBuddyFlags flags); @endsignalproto @signaldesc Emitted when a buddy is joining a chat, before the list of users in the chat updates to include the new user. @param conv The chat conversation. @param name The name of the user that is joining the conversation. + @param flags The flags of the user that is joining the conversation. @endsignaldef @signaldef chat-buddy-joined @signalproto -void (*chat_buddy_joined)(GaimConversation *conv, const char *name); +void (*chat_buddy_joined)(GaimConversation *conv, const char *name, + GaimConvChatBuddyFlags flags); @endsignalproto @signaldesc Emitted when a buddy joined a chat, after the users list is updated. @param conv The chat conversation. + @param name The name of the user that has joined the conversation. + @param flags The flags of the user that has joined the conversation. + @endsignaldef + + @signaldef chat-buddy-flags + @signalproto +void (*chat_buddy_flags)(GaimConversation *conv, const char *name, + GaimConvChatBuddyFlags oldflags, + GaimConvChatBuddyFlags newflags); + @endsignalproto + @signaldesc + Emitted when a user in a chat changes flags. + @param conv The chat conversation. + @param name The name of the user. + @param oldflags The old flags. + @param newflags The new flags. @endsignaldef @signaldef chat-buddy-leaving
--- a/pixmaps/status/default/Makefile.am Sat Jul 17 17:08:24 2004 +0000 +++ b/pixmaps/status/default/Makefile.am Sat Jul 17 18:11:12 2004 +0000 @@ -7,9 +7,11 @@ dnd.png \ extendedaway.png \ female.png \ + founder.svg \ freeforchat.png \ gadu-gadu.png \ game.png \ + halfop.svg \ hiptop.png \ icq.png \ ignored.svg \ @@ -26,10 +28,12 @@ novell.png \ occupied.png \ offline.png \ + op.svg \ rendezvous.png \ secure.png \ silc.png \ trepia.png \ + voice.svg \ wireless.png \ yahoo.png \ zephyr.png
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/status/default/founder.svg Sat Jul 17 18:11:12 2004 +0000 @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + id="svg656" + sodipodi:version="0.34" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="32pt" + height="32pt" + xml:space="preserve" + sodipodi:docbase="/home/build" + sodipodi:docname="/home/build/founder.svg"><defs + id="defs658"><linearGradient + id="linearGradient665"><stop + style="stop-color:#e50000;stop-opacity:1;" + offset="0" + id="stop666" /><stop + style="stop-color:#fffd00;stop-opacity:1;" + offset="1" + id="stop667" /></linearGradient><linearGradient + id="linearGradient660"><stop + style="stop-color:#ffff2f;stop-opacity:1;" + offset="0" + id="stop661" /><stop + style="stop-color:#e50000;stop-opacity:1;" + offset="1" + id="stop662" /></linearGradient><linearGradient + xlink:href="#linearGradient665" + id="linearGradient663" + x1="8.26311464e-8" + y1="-1.55637082e-7" + x2="1.00000024" + y2="-1.55637082e-7" + spreadMethod="pad" + gradientUnits="objectBoundingBox" /><radialGradient + xlink:href="#linearGradient665" + id="radialGradient664" + cx="0.5" + cy="0.5" + r="0.5" + fx="0.5" + fy="0.5" /><radialGradient + xlink:href="#linearGradient665" + id="radialGradient668" + cx="0.42774564" + cy="0.47096771" + r="0.55007958" + fx="0.42774564" + fy="0.47096771" + spreadMethod="pad" /></defs><sodipodi:namedview + id="base" + showgrid="false" + snaptogrid="false" + snaptoguides="false" /><path + sodipodi:type="spiral" + style="font-size:12;fill:url(#radialGradient664);fill-rule:evenodd;stroke:#000000;stroke-width:1.9759;fill-opacity:1;stroke-dasharray:none;stroke-linejoin:bevel;stroke-linecap:round;stroke-opacity:1;" + id="path659" + sodipodi:cx="4.48084641" + sodipodi:cy="5.90660334" + sodipodi:expansion="1" + sodipodi:revolution="3" + sodipodi:radius="17.6416454" + sodipodi:argument="-18.0953979" + sodipodi:t0="0" + d="M 4.480846 5.906603 C 4.935488 6.582345 4.122899 7.106161 3.47428 6.97811 C 2.10434 6.707657 1.812772 4.978034 2.337832 3.893471 C 3.267143 1.97389 5.798381 1.652043 7.500546 2.692082 C 9.982851 4.208796 10.33764 7.631665 8.766874 9.932869 C 6.682602 12.98637 2.341894 13.37245 -0.551986 11.26414 C -4.181049 8.620212 -4.597599 3.350751 -1.948195 -0.132795 C 1.251495 -4.339882 7.45529 -4.786495 11.52681 -1.593945 C 16.31342 2.159319 16.78989 9.300695 13.0529 13.95914 C 8.747414 19.32625 0.666401 19.83246 -4.578251 15.55017 C -10.52654 10.69335 -11.06243 1.671308 -6.234223 -4.159061 C -0.826688 -10.68901 9.137353 -11.25453 15.55308 -5.879973 C 22.66503 0.077829 23.26017 10.9846 17.33893 17.9854 " + transform="matrix(-1.195682,0,0,1.195682,26.97744,14.72193)" /></svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/status/default/halfop.svg Sat Jul 17 18:11:12 2004 +0000 @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.0" + x="0" + y="0" + width="40" + height="40" + id="svg644" + xml:space="preserve"><defs + id="defs646"><linearGradient + id="linearGradient651"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop652" /><stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop653" /></linearGradient><radialGradient + cx="0.5" + cy="0.5" + r="0.5" + fx="0.5" + fy="0.5" + id="radialGradient654" + xlink:href="#linearGradient651" /><linearGradient + x1="-6.36533315e-9" + y1="-1.07861e-8" + x2="1.00000012" + y2="-1.07861e-8" + id="linearGradient655" + xlink:href="#linearGradient651" + gradientUnits="objectBoundingBox" + spreadMethod="pad" /></defs><path + d="M 20.28064 30.48507 L 8.797826 36.6693 L 10.87388 23.79337 L 1.443943 14.7836 L 14.33122 12.77916 L 19.98601 1.026587 L 20.28064 30.48507 z " + transform="translate(2.384186e-6,1.696012)" + style="font-size:12;fill:#01ff00;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;" + id="path710" /></svg>
--- a/pixmaps/status/default/ignored.svg Sat Jul 17 17:08:24 2004 +0000 +++ b/pixmaps/status/default/ignored.svg Sat Jul 17 18:11:12 2004 +0000 @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" @@ -12,6 +13,9 @@ id="svg602" xml:space="preserve"><defs id="defs604" /><path - d="M 37.36908 20.13459 C 37.36908 29.5592 29.7289 37.19937 20.30434 37.19937 C 10.8797 37.19937 3.239555 29.5592 3.239555 20.13459 C 3.239555 10.70999 10.8797 3.069842 20.30434 3.069842 C 29.7289 3.069842 37.36908 10.70999 37.36908 20.13459 z M 7.462905 32.42286 L 33.06009 6.825752 " + d="M 37.36908 20.13459 C 37.36908 29.5592 29.7289 37.19937 20.30434 37.19937 C 10.8797 37.19937 3.239555 29.5592 3.239555 20.13459 C 3.239555 10.70999 10.8797 3.069842 20.30434 3.069842 C 29.7289 3.069842 37.36908 10.70999 37.36908 20.13459 z " style="font-size:12;fill:none;stroke:#000000;stroke-width:3.83957;" - id="path631" /></svg> + id="path635" /><path + d="M 7.462905 32.42286 L 33.06009 6.825752 " + style="font-size:12;fill:none;stroke:#000000;stroke-width:7.5;" + id="path636" /></svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/status/default/op.svg Sat Jul 17 18:11:12 2004 +0000 @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.0" + x="0" + y="0" + width="40" + height="40" + id="svg644" + xml:space="preserve"><defs + id="defs646"><linearGradient + id="linearGradient651"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop652" /><stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop653" /></linearGradient><radialGradient + cx="0.5" + cy="0.5" + r="0.5" + fx="0.5" + fy="0.5" + id="radialGradient654" + xlink:href="#linearGradient651" /><linearGradient + x1="-6.36533315e-9" + y1="-1.07861e-8" + x2="1.00000012" + y2="-1.07861e-8" + id="linearGradient655" + xlink:href="#linearGradient651" + gradientUnits="objectBoundingBox" + spreadMethod="pad" /></defs><polygon + points="31.88484,36.4384 20.28064,30.48507 8.797826,36.6693 10.87388,23.79337 1.443943,14.7836 14.33122,12.77916 19.98601,1.026588 25.87473,12.66371 38.79951,14.40999 29.55167,23.60656 31.88484,36.4384 " + transform="translate(2.384186e-6,1.696012)" + style="font-size:12;fill:#01ff00;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;" + id="polygon650" /></svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixmaps/status/default/voice.svg Sat Jul 17 18:11:12 2004 +0000 @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.0" + x="0" + y="0" + width="40" + height="40" + id="svg669" + xml:space="preserve"><defs + id="defs671" /><path + d="M 7.301596 3.746032 L 7.301596 36.00001 L 37.39683 19.87303 L 7.301596 3.746032 z " + style="font-size:12;fill:#ffc600;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;" + id="path673" /></svg>
--- a/plugins/ChangeLog.API Sat Jul 17 17:08:24 2004 +0000 +++ b/plugins/ChangeLog.API Sat Jul 17 18:11:12 2004 +0000 @@ -1,5 +1,28 @@ Gaim: The Pimpin' Penguin IM Client that's good for the soul! +version 0.81cvs + Conversation API: + * Changed: gaim_conv_chat_add_user() (added flags parameter) + gaim_conv_chat_add_users() now (added GList of flags parameter) + gaim_conv_chat_get_users() now returns a GList of GaimChatBuddy's + gaim_conv_chat_set_users() now expects a GList of GaimChatBuddy's + * Added: gaim_conv_chat_set_user_flags() + gaim_conv_chat_get_user_flags() + gaim_conv_chat_find_user() + gaim_conv_chat_cb_new() + gaim_conv_chat_cb_find() + gaim_conv_chat_cb_destroy() + gaim_conv_chat_cb_get_name() + + Conversation UI ops: + * Added: chat_update_user() + + Signals: + * Changed: chat-buddy-joining & chat-buddy-joined now include the user's flags + * Added: chat-buddy-flags for when user's flags change + gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT (required for the new + chat-buddy-flags signal) + version 0.80 (07/15/2004): Gaim API: * Removed: PRPL numbers : gaim_account_set_protocol(), @@ -10,7 +33,7 @@ * Added: can_receive_file & send_file to the GaimPluginProtocolInfo struct Signals: - * Changed "chat-invited" to also include the components hash table so + * Changed "chat-invited" to also include the components hash table so plugins can use serv_join_chat when the signal is emitted. * Added "chat-topic-changed" signal plugins know when a topic is changed.
--- a/plugins/signals-test.c Sat Jul 17 17:08:24 2004 +0000 +++ b/plugins/signals-test.c Sat Jul 17 18:11:12 2004 +0000 @@ -345,17 +345,27 @@ } static void -chat_buddy_joining_cb(GaimConversation *conv, const char *user, void *data) +chat_buddy_joining_cb(GaimConversation *conv, const char *user, + GaimConvChatBuddyFlags flags, void *data) { - gaim_debug_misc("signals test", "chat-buddy-joining (%s, %s)\n", - gaim_conversation_get_name(conv), user); + gaim_debug_misc("signals test", "chat-buddy-joining (%s, %s, %d)\n", + gaim_conversation_get_name(conv), user, flags); } static void -chat_buddy_joined_cb(GaimConversation *conv, const char *user, void *data) +chat_buddy_joined_cb(GaimConversation *conv, const char *user, + GaimConvChatBuddyFlags flags, void *data) { - gaim_debug_misc("signals test", "chat-buddy-joined (%s, %s)\n", - gaim_conversation_get_name(conv), user); + gaim_debug_misc("signals test", "chat-buddy-joined (%s, %s, %d)\n", + gaim_conversation_get_name(conv), user, flags); +} + +static void +chat_buddy_flags_cb(GaimConversation *conv, const char *user, + GaimConvChatBuddyFlags oldflags, GaimConvChatBuddyFlags newflags, void *data) +{ + gaim_debug_misc("signals test", "chat-buddy-flags (%s, %s, %d, %d)\n", + gaim_conversation_get_name(conv), user, oldflags, newflags); } static void @@ -376,10 +386,10 @@ static void chat_inviting_user_cb(GaimConversation *conv, const char *name, - const char *reason, void *data) + char **reason, void *data) { gaim_debug_misc("signals test", "chat-inviting-user (%s, %s, %s)\n", - gaim_conversation_get_name(conv), name, reason); + gaim_conversation_get_name(conv), name, *reason); } static void @@ -529,6 +539,8 @@ plugin, GAIM_CALLBACK(chat_buddy_joining_cb), NULL); gaim_signal_connect(conv_handle, "chat-buddy-joined", plugin, GAIM_CALLBACK(chat_buddy_joined_cb), NULL); + gaim_signal_connect(conv_handle, "chat-buddy-flags", + plugin, GAIM_CALLBACK(chat_buddy_flags_cb), NULL); gaim_signal_connect(conv_handle, "chat-buddy-leaving", plugin, GAIM_CALLBACK(chat_buddy_leaving_cb), NULL); gaim_signal_connect(conv_handle, "chat-buddy-left",
--- a/src/conversation.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/conversation.c Sat Jul 17 18:11:12 2004 +0000 @@ -30,10 +30,6 @@ #include "signals.h" #include "util.h" -/* XXX CORE/UI, waiting for away splittage */ -#include "gtkinternal.h" -#include "ui.h" - typedef struct { char *id; @@ -56,34 +52,6 @@ static void ensure_default_funcs(void); static void conv_placement_last_created_win(GaimConversation *conv); -static gint -insertname_compare(gconstpointer one, gconstpointer two) -{ - const char *a = (const char *)one; - const char *b = (const char *)two; - - if (*a == '@') { - if (*b != '@') return -1; - - return g_ascii_strcasecmp(a + 1, b + 1); - - } else if (*a == '%') { - if (*b != '%') return -1; - - return g_ascii_strcasecmp(a + 1, b + 1); - - } else if (*a == '+') { - if (*b == '@') return 1; - if (*b != '+') return -1; - - return g_ascii_strcasecmp(a + 1, b + 1); - - } else if (*b == '@' || *b == '%' || *b == '+') - return 1; - - return g_ascii_strcasecmp(a, b); -} - static gboolean find_nick(const char *nick, const char *message) { @@ -1927,10 +1895,12 @@ } void -gaim_conv_chat_add_user(GaimConvChat *chat, const char *user, const char *extra_msg) +gaim_conv_chat_add_user(GaimConvChat *chat, const char *user, const char *extra_msg, + GaimConvChatBuddyFlags flags) { GaimConversation *conv; GaimConversationUiOps *ops; + GaimConvChatBuddy *cb; char tmp[BUF_LONG]; g_return_if_fail(chat != NULL); @@ -1942,9 +1912,10 @@ gaim_signal_emit(gaim_conversations_get_handle(), "chat-buddy-joining", conv, user); + cb = gaim_conv_chat_cb_new(user, flags); + gaim_conv_chat_set_users(chat, - g_list_insert_sorted(gaim_conv_chat_get_users(chat), g_strdup(user), - insertname_compare)); + g_list_append(gaim_conv_chat_get_users(chat), cb)); if (ops != NULL && ops->chat_add_user != NULL) ops->chat_add_user(conv, user); @@ -1963,11 +1934,12 @@ } void -gaim_conv_chat_add_users(GaimConvChat *chat, GList *users) +gaim_conv_chat_add_users(GaimConvChat *chat, GList *users, GList *flags) { GaimConversation *conv; GaimConversationUiOps *ops; - GList *l; + GaimConvChatBuddy *cb; + GList *ul, *fl; g_return_if_fail(chat != NULL); g_return_if_fail(users != NULL); @@ -1975,19 +1947,23 @@ conv = gaim_conv_chat_get_conversation(chat); ops = gaim_conversation_get_ui_ops(conv); - for (l = users; l != NULL; l = l->next) { - const char *user = (const char *)l->data; + ul = users; + fl = flags; + while ((ul != NULL) && (fl != NULL)) { + const char *user = (const char *)ul->data; + GaimConvChatBuddyFlags f = GPOINTER_TO_INT(fl->data); gaim_signal_emit(gaim_conversations_get_handle(), - "chat-buddy-joining", conv, user); - + "chat-buddy-joining", conv, user, f); + + cb = gaim_conv_chat_cb_new(user, f); gaim_conv_chat_set_users(chat, - g_list_insert_sorted(gaim_conv_chat_get_users(chat), - g_strdup((char *)l->data), - insertname_compare)); + g_list_append(gaim_conv_chat_get_users(chat), cb)); gaim_signal_emit(gaim_conversations_get_handle(), - "chat-buddy-joined", conv, user); + "chat-buddy-joined", conv, user, f); + ul = ul->next; + fl = fl->next; } if (ops != NULL && ops->chat_add_users != NULL) @@ -2000,8 +1976,9 @@ { GaimConversation *conv; GaimConversationUiOps *ops; + GaimConvChatBuddy *cb; + GaimConvChatBuddyFlags flags; char tmp[BUF_LONG]; - GList *names; gboolean its_me = FALSE; g_return_if_fail(chat != NULL); @@ -2011,22 +1988,20 @@ conv = gaim_conv_chat_get_conversation(chat); ops = gaim_conversation_get_ui_ops(conv); + flags = gaim_conv_chat_user_get_flags(chat, old_user); + cb = gaim_conv_chat_cb_new(new_user, flags); gaim_conv_chat_set_users(chat, - g_list_insert_sorted(gaim_conv_chat_get_users(chat), g_strdup(new_user), - insertname_compare)); + g_list_append(gaim_conv_chat_get_users(chat), cb)); if (ops != NULL && ops->chat_rename_user != NULL) ops->chat_rename_user(conv, old_user, new_user); - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - if (!gaim_utf8_strcasecmp((char *)names->data, old_user)) { - gaim_conv_chat_set_users(chat, - g_list_remove(gaim_conv_chat_get_users(chat), names->data)); - break; - } + cb = gaim_conv_chat_cb_find(chat, old_user); + + if (cb) { + gaim_conv_chat_set_users(chat, + g_list_remove(gaim_conv_chat_get_users(chat), cb)); + gaim_conv_chat_cb_destroy(cb); } if (gaim_conv_chat_is_user_ignored(chat, old_user)) { @@ -2059,8 +2034,8 @@ { GaimConversation *conv; GaimConversationUiOps *ops; + GaimConvChatBuddy *cb; char tmp[BUF_LONG]; - GList *names; g_return_if_fail(chat != NULL); g_return_if_fail(user != NULL); @@ -2074,15 +2049,12 @@ if (ops != NULL && ops->chat_remove_user != NULL) ops->chat_remove_user(conv, user); - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - if (!gaim_utf8_strcasecmp((char *)names->data, user)) { - gaim_conv_chat_set_users(chat, - g_list_remove(gaim_conv_chat_get_users(chat), names->data)); - break; - } + cb = gaim_conv_chat_cb_find(chat, user); + + if (cb) { + gaim_conv_chat_set_users(chat, + g_list_remove(gaim_conv_chat_get_users(chat), cb)); + gaim_conv_chat_cb_destroy(cb); } /* NOTE: Don't remove them from ignored in case they re-enter. */ @@ -2104,8 +2076,9 @@ { GaimConversation *conv; GaimConversationUiOps *ops; + GaimConvChatBuddy *cb; char tmp[BUF_LONG]; - GList *names, *l; + GList *l; g_return_if_fail(chat != NULL); g_return_if_fail(users != NULL); @@ -2126,17 +2099,12 @@ for (l = users; l != NULL; l = l->next) { const char *user = (const char *)l->data; - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - if (!gaim_utf8_strcasecmp((char *)names->data, user)) - { - gaim_conv_chat_set_users(chat, - g_list_remove(gaim_conv_chat_get_users(chat), names->data)); - - break; - } + cb = gaim_conv_chat_cb_find(chat, user); + + if (cb) { + gaim_conv_chat_set_users(chat, + g_list_remove(gaim_conv_chat_get_users(chat), cb)); + gaim_conv_chat_cb_destroy(cb); } gaim_signal_emit(gaim_conversations_get_handle(), "chat-buddy-left", @@ -2176,8 +2144,8 @@ { GaimConversation *conv; GaimConversationUiOps *ops; - GList *users; - GList *l, *l_next; + GList *users, *names = NULL; + GList *l; g_return_if_fail(chat != NULL); @@ -2185,27 +2153,90 @@ ops = gaim_conversation_get_ui_ops(conv); users = gaim_conv_chat_get_users(chat); - if (ops != NULL && ops->chat_remove_users != NULL) - ops->chat_remove_users(conv, users); - - for (l = users; l != NULL; l = l_next) + if (ops != NULL && ops->chat_remove_users != NULL) { + for (l = users; l; l = l->next) { + GaimConvChatBuddy *cb = l->data; + names = g_list_append(names, cb->name); + } + ops->chat_remove_users(conv, names); + g_list_free(names); + } + + for (l = users; l; l = l->next) { - char *user = (char *)l->data; - - l_next = l->next; + GaimConvChatBuddy *cb = l->data; gaim_signal_emit(gaim_conversations_get_handle(), - "chat-buddy-leaving", conv, user, NULL); + "chat-buddy-leaving", conv, cb->name, NULL); gaim_signal_emit(gaim_conversations_get_handle(), - "chat-buddy-left", conv, user, NULL); - - g_free(user); + "chat-buddy-left", conv, cb->name, NULL); + + gaim_conv_chat_cb_destroy(cb); } g_list_free(users); gaim_conv_chat_set_users(chat, NULL); } + +gboolean +gaim_conv_chat_find_user(GaimConvChat *chat, const char *user) +{ + g_return_val_if_fail(chat != NULL, FALSE); + g_return_val_if_fail(user != NULL, FALSE); + + return (gaim_conv_chat_cb_find(chat, user) != NULL); +} + +void +gaim_conv_chat_user_set_flags(GaimConvChat *chat, const char *user, + GaimConvChatBuddyFlags flags) +{ + GaimConversation *conv; + GaimConversationUiOps *ops; + GaimConvChatBuddy *cb; + GaimConvChatBuddyFlags oldflags; + + g_return_if_fail(chat != NULL); + g_return_if_fail(user != NULL); + + cb = gaim_conv_chat_cb_find(chat, user); + + if (!cb) + return; + + if (flags == cb->flags) + return; + + oldflags = cb->flags; + cb->flags = flags; + + conv = gaim_conv_chat_get_conversation(chat); + ops = gaim_conversation_get_ui_ops(conv); + + if (ops != NULL && ops->chat_update_user != NULL) + ops->chat_update_user(conv, user); + + gaim_signal_emit(gaim_conversations_get_handle(), + "chat-buddy-flags", conv, user, oldflags, flags); +} + +GaimConvChatBuddyFlags +gaim_conv_chat_user_get_flags(GaimConvChat *chat, const char *user) +{ + GaimConvChatBuddy *cb; + + g_return_val_if_fail(chat != NULL, 0); + g_return_val_if_fail(user != NULL, 0); + + cb = gaim_conv_chat_cb_find(chat, user); + + if (!cb) + return GAIM_CBFLAGS_NONE; + + return cb->flags; +} + void gaim_conv_chat_set_nick(GaimConvChat *chat, const char *nick) { g_return_if_fail(chat != NULL); @@ -2254,6 +2285,58 @@ return chat->left; } +GaimConvChatBuddy * +gaim_conv_chat_cb_new(const char *name, GaimConvChatBuddyFlags flags) +{ + GaimConvChatBuddy *cb; + + g_return_val_if_fail(name != NULL, NULL); + + cb = g_new0(GaimConvChatBuddy, 1); + cb->name = g_strdup(name); + cb->flags = flags; + + return cb; +} + +GaimConvChatBuddy * +gaim_conv_chat_cb_find(GaimConvChat *chat, const char *name) +{ + GList *l; + GaimConvChatBuddy *cb = NULL; + + g_return_val_if_fail(chat != NULL, NULL); + g_return_val_if_fail(name != NULL, NULL); + + for (l = gaim_conv_chat_get_users(chat); l; l = l->next) { + cb = l->data; + if (!gaim_utf8_strcasecmp(cb->name, name)) + return cb; + } + + return NULL; +} + +void +gaim_conv_chat_cb_destroy(GaimConvChatBuddy *cb) +{ + g_return_if_fail(cb != NULL); + + if (cb->name) + g_free(cb->name); + cb->name = NULL; + cb->flags = 0; + g_free(cb); +} + +const char * +gaim_conv_chat_cb_get_name(GaimConvChatBuddy *cb) +{ + g_return_val_if_fail(cb != NULL, NULL); + + return cb->name; +} + /************************************************************************** * Conversation placement functions **************************************************************************/ @@ -2798,16 +2881,26 @@ GAIM_SUBTYPE_CONVERSATION)); gaim_signal_register(handle, "chat-buddy-joining", - gaim_marshal_VOID__POINTER_POINTER, NULL, 2, + gaim_marshal_VOID__POINTER_POINTER_UINT, NULL, 3, + gaim_value_new(GAIM_TYPE_SUBTYPE, + GAIM_SUBTYPE_CONVERSATION), + gaim_value_new(GAIM_TYPE_STRING), + gaim_value_new(GAIM_TYPE_UINT)); + + gaim_signal_register(handle, "chat-buddy-joined", + gaim_marshal_VOID__POINTER_POINTER_UINT, NULL, 3, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONVERSATION), - gaim_value_new(GAIM_TYPE_STRING)); - - gaim_signal_register(handle, "chat-buddy-joined", - gaim_marshal_VOID__POINTER_POINTER, NULL, 2, + gaim_value_new(GAIM_TYPE_STRING), + gaim_value_new(GAIM_TYPE_UINT)); + + gaim_signal_register(handle, "chat-buddy-flags", + gaim_marshal_VOID__POINTER_POINTER_UINT_UINT, NULL, 4, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONVERSATION), - gaim_value_new(GAIM_TYPE_STRING)); + gaim_value_new(GAIM_TYPE_STRING), + gaim_value_new(GAIM_TYPE_UINT), + gaim_value_new(GAIM_TYPE_UINT)); gaim_signal_register(handle, "chat-buddy-leaving", gaim_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3,
--- a/src/conversation.h Sat Jul 17 17:08:24 2004 +0000 +++ b/src/conversation.h Sat Jul 17 18:11:12 2004 +0000 @@ -37,6 +37,7 @@ typedef struct _GaimConversation GaimConversation; typedef struct _GaimConvIm GaimConvIm; typedef struct _GaimConvChat GaimConvChat; +typedef struct _GaimConvChatBuddy GaimConvChatBuddy; /** * A type of conversation. @@ -118,6 +119,18 @@ GAIM_MESSAGE_ERROR = 0x0200 /**< Error message. */ } GaimMessageFlags; +/** + * Flags applicable to users in Chats. + */ +typedef enum +{ + GAIM_CBFLAGS_NONE = 0x0000, /**< No flags */ + GAIM_CBFLAGS_VOICE = 0x0001, /**< Voiced user or "Participant" */ + GAIM_CBFLAGS_HALFOP = 0x0002, /**< Half-op */ + GAIM_CBFLAGS_OP = 0x0004, /**< Channel Op or Moderator */ + GAIM_CBFLAGS_FOUNDER = 0x0008 /**< Channel Founder */ +} GaimConvChatBuddyFlags; + #include "account.h" #include "log.h" #include "buddyicon.h" @@ -175,6 +188,7 @@ const char *old_name, const char *new_name); void (*chat_remove_user)(GaimConversation *conv, const char *user); void (*chat_remove_users)(GaimConversation *conv, GList *users); + void (*chat_update_user)(GaimConversation *conv, const char *user); void (*update_progress)(GaimConversation *conv, float percent); @@ -231,6 +245,15 @@ }; /** + * Data for "Chat Buddies" + */ +struct _GaimConvChatBuddy +{ + char *name; /**< The name */ + GaimConvChatBuddyFlags flags; /**< Flags (ops, voice etc.) */ +}; + +/** * A core representation of a conversation between two or more people. * * The conversation can be an IM or a chat. Each conversation is kept @@ -1150,9 +1173,10 @@ * @param chat The chat. * @param user The user to add. * @param extra_msg An extra message to display with the join message. + * @param flags The users flags */ void gaim_conv_chat_add_user(GaimConvChat *chat, const char *user, - const char *extra_msg); + const char *extra_msg, GaimConvChatBuddyFlags flags); /** * Adds a list of users to a chat. @@ -1162,8 +1186,9 @@ * * @param chat The chat. * @param users The list of users to add. + * @param flags The list of flags for each user. */ -void gaim_conv_chat_add_users(GaimConvChat *chat, GList *users); +void gaim_conv_chat_add_users(GaimConvChat *chat, GList *users, GList *flags); /** * Renames a user in a chat. @@ -1198,6 +1223,37 @@ const char *reason); /** + * Finds a user in a chat + * + * @param chat The chat. + * @param user The user to look for. + * + * @return TRUE if the user is in the chat, FALSE if not + */ +gboolean gaim_conv_chat_find_user(GaimConvChat *chat, const char *user); + +/** + * Set a users flags in a chat + * + * @param chat The chat. + * @param user The user to update. + * @param flags The new flags. + */ +void gaim_conv_chat_user_set_flags(GaimConvChat *chat, const char *user, + GaimConvChatBuddyFlags flags); + +/** + * Get the flags for a user in a chat + * + * @param chat The chat. + * @param user The user to find the flags for + * + * @return The flags for the user + */ +GaimConvChatBuddyFlags gaim_conv_chat_user_get_flags(GaimConvChat *chat, + const char *user); + +/** * Clears all users from a chat. * * @param chat The chat. @@ -1249,6 +1305,41 @@ */ gboolean gaim_conv_chat_has_left(GaimConvChat *chat); +/** + * Creates a new chat buddy + * + * @param name The name. + * @param flags The flags. + * + * @return The new chat buddy + */ +GaimConvChatBuddy *gaim_conv_chat_cb_new(const char *name, + GaimConvChatBuddyFlags flags); + +/** + * Find a chat buddy in a chat + * + * @param chat The chat. + * @param name The name of the chat buddy to find. + */ +GaimConvChatBuddy *gaim_conv_chat_cb_find(GaimConvChat *chat, const char *name); + +/** + * Get the name of a chat buddy + * + * @param cb The chat buddy. + * + * @return The name of the chat buddy. + */ +const char *gaim_conv_chat_cb_get_name(GaimConvChatBuddy *cb); + +/** + * Destroys a chat buddy + * + * @param cb The chat buddy to destroy + */ +void gaim_conv_chat_cb_destroy(GaimConvChatBuddy *cb); + /*@}*/ /**************************************************************************/
--- a/src/gtkconv.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/gtkconv.c Sat Jul 17 18:11:12 2004 +0000 @@ -126,7 +126,7 @@ static void got_typing_keypress(GaimConversation *conv, gboolean first); static GList *generate_invite_user_names(GaimConnection *gc); static void add_chat_buddy_common(GaimConversation *conv, - const char *name, int pos); + const char *name); static void tab_complete(GaimConversation *conv); static void update_typing_icon(GaimConversation *conv); static gboolean update_send_as_selection(GaimConvWindow *win); @@ -591,7 +591,7 @@ GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *sel; - const char *name; + char *name; gtkchat = gtkconv->u.chat; @@ -604,6 +604,7 @@ return; chat_do_info(conv, name); + g_free(name); } } @@ -1196,7 +1197,7 @@ GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *sel; - const char *name; + char *name; gtkconv = GAIM_GTK_CONVERSATION(conv); gtkchat = gtkconv->u.chat; @@ -1210,6 +1211,7 @@ return; chat_do_im(conv, name); + g_free(name); } static void @@ -1222,7 +1224,6 @@ GtkTreeModel *model; GtkTreeSelection *sel; const char *name; - int pos; chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); @@ -1238,14 +1239,12 @@ else return; - pos = g_list_index(gaim_conv_chat_get_users(chat), name); - if (gaim_conv_chat_is_user_ignored(chat, name)) gaim_conv_chat_unignore(chat, name); else gaim_conv_chat_ignore(chat, name); - add_chat_buddy_common(conv, name, pos); + add_chat_buddy_common(conv, name); } static void @@ -1480,6 +1479,7 @@ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { chat_do_im(conv, who); + g_free(who); } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { GtkWidget *menu = create_chat_menu (conv, who, prpl_info, gc); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, @@ -3248,23 +3248,41 @@ } static GdkPixbuf * -get_chat_user_status_icon(GaimConvChat *chat, const char *name) +get_chat_buddy_status_icon(GaimConvChat *chat, const char *name, GaimConvChatBuddyFlags flags) { - GdkPixbuf *pixbuf, *scale; + GdkPixbuf *pixbuf, *scale, *scale2; char *filename; - - /* Eventually this should compose the pixbuf based on user status (op, voice, etc.) - * and ignored status and any other fancy things we want to show. For now though, - * it's just ignored users that have the privilege of an icon */ - - if(gaim_conv_chat_is_user_ignored(chat, name)) { - filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "ignored.svg", NULL); + char *image = NULL; + + if (flags & GAIM_CBFLAGS_FOUNDER) { + image = g_strdup("founder.svg"); + } else if (flags & GAIM_CBFLAGS_OP) { + image = g_strdup("op.svg"); + } else if (flags & GAIM_CBFLAGS_HALFOP) { + image = g_strdup("halfop.svg"); + } else if (flags & GAIM_CBFLAGS_VOICE) { + image = g_strdup("voice.svg"); + } else if ((!flags) && gaim_conv_chat_is_user_ignored(chat, name)) { + image = g_strdup("ignored.svg"); + } + if (image) { + filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); + g_free(image); pixbuf = gdk_pixbuf_new_from_file(filename, NULL); g_free(filename); if (!pixbuf) return NULL; scale = gdk_pixbuf_scale_simple(pixbuf, 15, 15, GDK_INTERP_BILINEAR); g_object_unref(pixbuf); + if (flags && gaim_conv_chat_is_user_ignored(chat, name)) { + filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "ignored.svg", NULL); + pixbuf = gdk_pixbuf_new_from_file(filename, NULL); + g_free(filename); + scale2 = gdk_pixbuf_scale_simple(pixbuf, 15, 15, GDK_INTERP_BILINEAR); + g_object_unref(pixbuf); + gdk_pixbuf_composite(scale2, scale, 0, 0, 15, 15, 0, 0, 1, 1, GDK_INTERP_BILINEAR, 192); + g_object_unref(scale2); + } return scale; } @@ -3272,11 +3290,12 @@ } static void -add_chat_buddy_common(GaimConversation *conv, const char *name, int pos) +add_chat_buddy_common(GaimConversation *conv, const char *name) { GaimGtkConversation *gtkconv; GaimGtkChatPane *gtkchat; GaimConvChat *chat; + GaimConvChatBuddyFlags flags; GtkTreeIter iter; GtkListStore *ls; GdkPixbuf *pixbuf; @@ -3287,13 +3306,16 @@ ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list))); - pixbuf = get_chat_user_status_icon(chat, name); + flags = gaim_conv_chat_user_get_flags(chat, name); + pixbuf = get_chat_buddy_status_icon(chat, name, flags); gtk_list_store_append(ls, &iter); gtk_list_store_set(ls, &iter, CHAT_USERS_ICON_COLUMN, pixbuf, - CHAT_USERS_NAME_COLUMN, name, -1); + CHAT_USERS_NAME_COLUMN, name, CHAT_USERS_FLAGS_COLUMN, flags, -1); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), CHAT_USERS_NAME_COLUMN, GTK_SORT_ASCENDING); + if (pixbuf) + g_object_unref(pixbuf); } static void @@ -3356,9 +3378,9 @@ nicks != NULL; nicks = nicks->next) { - char *nick = nicks->data; - - strncpy(nick_partial, nick, strlen(entered)); + GaimConvChatBuddy *cb = nicks->data; + + strncpy(nick_partial, cb->name, strlen(entered)); nick_partial[strlen(entered)] = '\0'; if(gaim_utf8_strcasecmp(nick_partial, entered)) continue; @@ -3370,11 +3392,11 @@ * this will only get called once, since from now * on most_matched is >= 0 */ - most_matched = strlen(nick); - partial = g_strdup(nick); + most_matched = strlen(cb->name); + partial = g_strdup(cb->name); } else if (most_matched) { - char *tmp = g_strdup(nick); + char *tmp = g_strdup(cb->name); while (gaim_utf8_strcasecmp(tmp, partial)) { partial[most_matched] = '\0'; @@ -3387,7 +3409,7 @@ g_free(tmp); } - matches = g_list_append(matches, nick); + matches = g_list_append(matches, cb->name); } g_free(nick_partial); @@ -3662,7 +3684,7 @@ _("Block the user"), NULL); gtk_box_pack_start(GTK_BOX(parent), gtkim->block, FALSE, FALSE, 0); - /* Block button */ + /* Send File button */ gtkim->send_file = gaim_gtk_change_text(_("Send File"), gtkim->send_file, GAIM_STOCK_FILE_TRANSFER, GAIM_CONV_IM); gtk_tooltips_set_tip(gtkconv->tooltips, gtkim->send_file, @@ -3852,6 +3874,32 @@ new_topic); } +static gint +sort_chat_users(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata) +{ + GaimConvChatBuddyFlags f1 = 0, f2 = 0; + char *user1 = NULL, *user2 = NULL; + gint ret = 0; + + gtk_tree_model_get(model, a, CHAT_USERS_NAME_COLUMN, &user1, CHAT_USERS_FLAGS_COLUMN, &f1, -1); + gtk_tree_model_get(model, b, CHAT_USERS_NAME_COLUMN, &user2, CHAT_USERS_FLAGS_COLUMN, &f2, -1); + + if (user1 == NULL || user2 == NULL) { + if (!(user1 == NULL && user2 == NULL)) + ret = (user1 == NULL) ? -1: 1; + } else if (f1 != f2) { + /* sort more important users first */ + ret = (f1 > f2) ? -1 : 1; + } else { + ret = g_utf8_collate(user1, user2); + } + + g_free(user1); + g_free(user2); + + return ret; +} + static GtkWidget * setup_chat_pane(GaimConversation *conv) { @@ -3969,7 +4017,10 @@ gtk_box_pack_start(GTK_BOX(lbox), sw, TRUE, TRUE, 0); gtk_widget_show(sw); - ls = gtk_list_store_new(CHAT_USERS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING); + ls = gtk_list_store_new(CHAT_USERS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, + G_TYPE_INT); + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ls), CHAT_USERS_NAME_COLUMN, + sort_chat_users, NULL, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), CHAT_USERS_NAME_COLUMN, GTK_SORT_ASCENDING); @@ -3979,6 +4030,8 @@ col = gtk_tree_view_column_new_with_attributes(NULL, rend, "pixbuf", CHAT_USERS_ICON_COLUMN, NULL); + gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(col), TRUE); + gtk_tree_view_append_column(GTK_TREE_VIEW(list), col); g_signal_connect(G_OBJECT(list), "button_press_event", @@ -5016,11 +5069,11 @@ mdate, message); else g_snprintf(buf, BUF_LONG, "<FONT COLOR=\"#ff0000\"><B>%s</B></FONT>", message); - + g_snprintf(buf2, sizeof(buf2), "<FONT %s><FONT SIZE=\"2\"><!--(%s) --></FONT><B>%s</B></FONT>", sml_attrib, mdate, message); - + gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, 0); /* Add the message to a conversations scrollback buffer */ @@ -5157,7 +5210,6 @@ GaimGtkChatPane *gtkchat; char tmp[BUF_LONG]; int num_users; - int pos; chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); @@ -5175,9 +5227,7 @@ if (gtkconv->make_sound) gaim_sound_play_event(GAIM_SOUND_CHAT_JOIN); - pos = g_list_index(gaim_conv_chat_get_users(chat), user); - - add_chat_buddy_common(conv, user, pos); + add_chat_buddy_common(conv, user); } static void @@ -5189,7 +5239,6 @@ GList *l; char tmp[BUF_LONG]; int num_users; - int pos; chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); @@ -5205,9 +5254,7 @@ gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); for (l = users; l != NULL; l = l->next) { - pos = g_list_index(gaim_conv_chat_get_users(chat), (char *)l->data); - - add_chat_buddy_common(conv, (char *)l->data, pos); + add_chat_buddy_common(conv, (char *)l->data); } } @@ -5220,51 +5267,37 @@ GaimGtkChatPane *gtkchat; GtkTreeIter iter; GtkTreeModel *model; - GList *names; - int pos; int f = 1; chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); gtkchat = gtkconv->u.chat; - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - char *u = (char *)names->data; - - if (!gaim_utf8_strcasecmp(u, old_name)) { - model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); - - if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) - break; - - while (f != 0) { - char *val; - - gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1); - - if (!gaim_utf8_strcasecmp(old_name, val)) { - gtk_list_store_remove(GTK_LIST_STORE(model), &iter); - break; - } - - f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); - - g_free(val); - } - + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) + return; + + while (f != 0) { + char *val; + + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1); + + if (!gaim_utf8_strcasecmp(old_name, val)) { + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + g_free(val); break; } + + f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); + + g_free(val); } - if (!names) + if (!gaim_conv_chat_find_user(chat, old_name)) return; - pos = g_list_index(gaim_conv_chat_get_users(chat), new_name); - - add_chat_buddy_common(conv, new_name, pos); + add_chat_buddy_common(conv, new_name); } static void @@ -5275,7 +5308,6 @@ GaimGtkChatPane *gtkchat; GtkTreeIter iter; GtkTreeModel *model; - GList *names; char tmp[BUF_LONG]; int num_users; int f = 1; @@ -5286,41 +5318,33 @@ num_users = g_list_length(gaim_conv_chat_get_users(chat)) - 1; - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - char *u = (char *)names->data; - - if (!gaim_utf8_strcasecmp(u, user)) { - model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); - - if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) - break; - - while (f != 0) { - char *val; - - gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1); - - if (!gaim_utf8_strcasecmp(user, val)) - gtk_list_store_remove(GTK_LIST_STORE(model), &iter); - - f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); - - g_free(val); - } - + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) + return; + + while (f != 0) { + char *val; + + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1); + + if (!gaim_utf8_strcasecmp(user, val)) { + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + g_free(val); break; } + + f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); + + g_free(val); } - if (names == NULL) + if (!gaim_conv_chat_find_user(chat, user)) return; g_snprintf(tmp, sizeof(tmp), - ngettext("%d person in room", "%d people in room", - num_users), num_users); + ngettext("%d person in room", "%d people in room", + num_users), num_users); gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); @@ -5336,7 +5360,6 @@ GaimGtkChatPane *gtkchat; GtkTreeIter iter; GtkTreeModel *model; - GList *names = NULL; GList *l; char tmp[BUF_LONG]; int num_users; @@ -5350,41 +5373,27 @@ g_list_length(users); for (l = users; l != NULL; l = l->next) { - for (names = gaim_conv_chat_get_users(chat); - names != NULL; - names = names->next) { - - char *u = (char *)names->data; - - if (!gaim_utf8_strcasecmp(u, (char *)l->data)) { - model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); - - if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), - &iter)) - break; - - do { - char *val; - - gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, - CHAT_USERS_NAME_COLUMN, &val, -1); - - if (!gaim_utf8_strcasecmp((char *)l->data, val)) - gtk_list_store_remove(GTK_LIST_STORE(model), &iter); - - f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); - - g_free(val); - } while (f); - - break; - } - } + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), + &iter)) + continue; + + do { + char *val; + + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, + CHAT_USERS_NAME_COLUMN, &val, -1); + + if (!gaim_utf8_strcasecmp((char *)l->data, val)) + f = gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + else + f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); + + g_free(val); + } while (f); } - if (names == NULL) - return; - g_snprintf(tmp, sizeof(tmp), ngettext("%d person in room", "%d people in room", num_users), num_users); @@ -5392,6 +5401,47 @@ gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); } +static void +gaim_gtkconv_chat_update_user(GaimConversation *conv, const char *user) +{ + GaimConvChat *chat; + GaimGtkConversation *gtkconv; + GaimGtkChatPane *gtkchat; + GtkTreeIter iter; + GtkTreeModel *model; + int f = 1; + + chat = GAIM_CONV_CHAT(conv); + gtkconv = GAIM_GTK_CONVERSATION(conv); + gtkchat = gtkconv->u.chat; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) + return; + + while (f != 0) { + char *val; + + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1); + + if (!gaim_utf8_strcasecmp(user, val)) { + gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + g_free(val); + break; + } + + f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); + + g_free(val); + } + + if (!gaim_conv_chat_find_user(chat, user)) + return; + + add_chat_buddy_common(conv, user); +} + static gboolean gaim_gtkconv_has_focus(GaimConversation *conv) { @@ -5514,9 +5564,9 @@ topic = gaim_conv_chat_get_topic(chat); - gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text),topic); + gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, - topic, NULL); + topic ? topic : "", NULL); } else if (type == GAIM_CONV_ACCOUNT_ONLINE || type == GAIM_CONV_ACCOUNT_OFFLINE) @@ -5553,6 +5603,7 @@ gaim_gtkconv_chat_rename_user, /* chat_rename_user */ gaim_gtkconv_chat_remove_user, /* chat_remove_user */ gaim_gtkconv_chat_remove_users, /* chat_remove_users */ + gaim_gtkconv_chat_update_user, /* chat_update_user */ NULL, /* update_progress */ gaim_gtkconv_has_focus, /* has_focus */ gaim_gtkconv_updated /* updated */
--- a/src/gtkconv.h Sat Jul 17 17:08:24 2004 +0000 +++ b/src/gtkconv.h Sat Jul 17 18:11:12 2004 +0000 @@ -31,6 +31,7 @@ enum { CHAT_USERS_ICON_COLUMN, CHAT_USERS_NAME_COLUMN, + CHAT_USERS_FLAGS_COLUMN, CHAT_USERS_COLUMNS };
--- a/src/protocols/irc/msgs.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/irc/msgs.c Sat Jul 17 18:11:12 2004 +0000 @@ -56,10 +56,9 @@ static void irc_chat_remove_buddy(GaimConversation *convo, char *data[2]) { - GList *users = gaim_conv_chat_get_users(GAIM_CONV_CHAT(convo)); char *message = g_strdup_printf("quit: %s", data[1]); - if (g_list_find_custom(users, data[0], (GCompareFunc)(strcmp))) + if (gaim_conv_chat_find_user(GAIM_CONV_CHAT(convo), data[0])) gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), data[0], message); g_free(message); @@ -332,15 +331,26 @@ irc->nameconv = NULL; } else { GList *users = NULL; + GList *flags = NULL; while (*cur) { + GaimConvChatBuddyFlags f = GAIM_CBFLAGS_NONE; end = strchr(cur, ' '); if (!end) end = cur + strlen(cur); - if (*cur == '@' || *cur == '%' || *cur == '+') + if (*cur == '@') { + f = GAIM_CBFLAGS_OP; cur++; + } else if (*cur == '%') { + f = GAIM_CBFLAGS_HALFOP; + cur++; + } else if(*cur == '+') { + f = GAIM_CBFLAGS_VOICE; + cur++; + } tmp = g_strndup(cur, end - cur); users = g_list_append(users, tmp); + flags = g_list_append(flags, GINT_TO_POINTER(f)); cur = end; if (*cur) cur++; @@ -349,12 +359,13 @@ if (users != NULL) { GList *l; - gaim_conv_chat_add_users(GAIM_CONV_CHAT(convo), users); + gaim_conv_chat_add_users(GAIM_CONV_CHAT(convo), users, flags); for (l = users; l != NULL; l = l->next) g_free(l->data); g_list_free(users); + g_list_free(flags); } } g_free(names); @@ -574,7 +585,7 @@ } userhost = irc_mask_userhost(from); - gaim_conv_chat_add_user(GAIM_CONV_CHAT(convo), nick, userhost); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(convo), nick, userhost, GAIM_CBFLAGS_NONE); if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) { ib->flag = TRUE; @@ -632,6 +643,45 @@ buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], args[2] ? args[2] : "", nick); gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); g_free(buf); + if(args[2]) { + GaimConvChatBuddyFlags newflag, flags; + char *mcur, *cur, *end, *user; + gboolean add = FALSE; + mcur = args[1]; + cur = args[2]; + while (*cur && *mcur) { + if ((*mcur == '+') || (*mcur == '-')) { + add = (*mcur == '+') ? TRUE : FALSE; + mcur++; + continue; + } + end = strchr(cur, ' '); + if (!end) + end = cur + strlen(cur); + user = g_strndup(cur, end - cur); + flags = gaim_conv_chat_user_get_flags(GAIM_CONV_CHAT(convo), user); + newflag = GAIM_CBFLAGS_NONE; + if (*mcur == 'o') + newflag = GAIM_CBFLAGS_OP; + else if (*mcur =='h') + newflag = GAIM_CBFLAGS_HALFOP; + else if (*mcur == 'v') + newflag = GAIM_CBFLAGS_VOICE; + if (newflag) { + if (add) + flags |= newflag; + else + flags &= ~newflag; + gaim_conv_chat_user_set_flags(GAIM_CONV_CHAT(convo), user, flags); + } + g_free(user); + cur = end; + if (*cur) + cur++; + if (*mcur) + mcur++; + } + } } else { /* User */ } g_free(nick); @@ -655,18 +705,7 @@ while (chats) { GaimConvChat *chat = GAIM_CONV_CHAT(chats->data); - GList *users = gaim_conv_chat_get_users(chat); - - while (users) { - char *user = users->data; - - if (!strcmp(nick, user)) { - gaim_conv_chat_rename_user(chat, user, args[0]); - users = gaim_conv_chat_get_users(chat); - break; - } - users = users->next; - } + gaim_conv_chat_rename_user(chat, nick, args[0]); chats = chats->next; } g_free(nick);
--- a/src/protocols/jabber/chat.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/jabber/chat.c Sat Jul 17 18:11:12 2004 +0000 @@ -261,15 +261,7 @@ gboolean jabber_chat_find_buddy(GaimConversation *conv, const char *name) { - GList *m = gaim_conv_chat_get_users(GAIM_CONV_CHAT(conv)); - - while(m) { - if(!strcmp(m->data, name)) - return TRUE; - m = m->next; - } - - return FALSE; + return gaim_conv_chat_find_user(GAIM_CONV_CHAT(conv), name); } char *jabber_chat_buddy_real_name(GaimConnection *gc, int id, const char *who)
--- a/src/protocols/jabber/presence.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/jabber/presence.c Sat Jul 17 18:11:12 2004 +0000 @@ -199,6 +199,7 @@ JabberChat *chat; JabberBuddy *jb; JabberBuddyResource *jbr = NULL; + GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; GaimBuddy *b; char *buddy_name; int state = 0; @@ -400,9 +401,17 @@ jabber_chat_track_handle(chat, jid->resource, real_jid, affiliation, role); + if (!strcmp(role, "moderator")) + flags = GAIM_CBFLAGS_OP; + else if (!strcmp(role, "participant")) + flags = GAIM_CBFLAGS_VOICE; + if(!jabber_chat_find_buddy(chat->conv, jid->resource)) gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat->conv), jid->resource, - real_jid); + real_jid, flags); + else + gaim_conv_chat_user_set_flags(GAIM_CONV_CHAT(chat->conv), jid->resource, + flags); } g_free(room_jid); } else {
--- a/src/protocols/msn/msn.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/msn/msn.c Sat Jul 17 18:11:12 2004 +0000 @@ -340,7 +340,7 @@ swboard->conv = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat"); gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), - gaim_account_get_username(buddy->account), NULL); + gaim_account_get_username(buddy->account), NULL, GAIM_CBFLAGS_NONE); } static void
--- a/src/protocols/msn/switchboard.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/msn/switchboard.c Sat Jul 17 18:11:12 2004 +0000 @@ -68,7 +68,7 @@ if ((swboard->conv != NULL) && (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_CHAT)) { - gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, GAIM_CBFLAGS_NONE); } else if (swboard->current_users > 1 || swboard->total_users > 1) { @@ -99,14 +99,14 @@ * tmp_user); */ gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), - tmp_user, NULL); + tmp_user, NULL, GAIM_CBFLAGS_NONE); } /* gaim_debug_info("msn", "[chat] We add ourselves.\n"); */ gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), gaim_account_get_username(account), - NULL); + NULL, GAIM_CBFLAGS_NONE); g_free(swboard->im_user); swboard->im_user = NULL;
--- a/src/protocols/napster/napster.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/napster/napster.c Sat Jul 17 18:11:12 2004 +0000 @@ -365,7 +365,7 @@ case 408: /* MSG_SERVER_CHANNEL_USER_LIST */ res = g_strsplit(buf, " ", 4); c = nap_find_chat(gc, res[0]); - gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), res[1], NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), res[1], NULL, GAIM_CBFLAGS_NONE); g_strfreev(res); break;
--- a/src/protocols/novell/novell.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/novell/novell.c Sat Jul 17 18:11:12 2004 +0000 @@ -649,7 +649,7 @@ ur = nm_conference_get_participant(conference, i); if (ur) { name = nm_user_record_get_display_id(ur); - gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL, GAIM_CBFLAGS_NONE); } } } @@ -1858,7 +1858,6 @@ NMUserRecord *ur = NULL; const char *name; const char *conf_name; - GList *list = NULL; gc = gaim_account_get_connection(user->client_data); if (gc == NULL) @@ -1878,7 +1877,7 @@ nm_conference_set_data(conference, (gpointer) chat); name = nm_user_record_get_display_id(ur); - gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL, GAIM_CBFLAGS_NONE); } } @@ -1888,9 +1887,8 @@ ur = nm_find_user_record(user, nm_event_get_source(event)); if (ur) { name = nm_user_record_get_display_id(ur); - list = gaim_conv_chat_get_users(GAIM_CONV_CHAT(chat)); - if (!g_list_find_custom(list, name, (GCompareFunc)nm_utf8_strcasecmp)) { - gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); + if (!gaim_conv_chat_find_user(GAIM_CONV_CHAT(chat), name)) { + gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL, GAIM_CBFLAGS_NONE); } } }
--- a/src/protocols/oscar/oscar.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/oscar/oscar.c Sat Jul 17 18:11:12 2004 +0000 @@ -4189,7 +4189,7 @@ return 1; for (i = 0; i < count; i++) - gaim_conv_chat_add_user(GAIM_CONV_CHAT(c->conv), info[i].sn, NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(c->conv), info[i].sn, NULL, GAIM_CBFLAGS_NONE); return 1; }
--- a/src/protocols/silc/chat.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/silc/chat.c Sat Jul 17 18:11:12 2004 +0000 @@ -941,7 +941,7 @@ SilcUInt32 retry = SILC_PTR_TO_32(channel->context); SilcHashTableList htl; SilcChannelUser chu; - GList *users = NULL; + GList *users = NULL, *flags = NULL; char tmp[256]; if (!clients && retry < 1) { @@ -963,25 +963,17 @@ /* Add all users to channel */ silc_hash_table_list(channel->user_list, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { + GaimConvChatBuddyFlags f = GAIM_CBFLAGS_NONE; if (!chu->client->nickname) continue; chu->context = SILC_32_TO_PTR(sg->channel_ids); -#if 0 /* XXX don't append mode char to nick because Gaim doesn't - give a way to change it afterwards when mode changes. */ - tmp2 = silc_client_chumode_char(chu->mode); - if (tmp2) - g_snprintf(tmp, sizeof(tmp), "%s%s", tmp2, - chu->client->nickname); - else - g_snprintf(tmp, sizeof(tmp), "%s", - chu->client->nickname); - silc_free(tmp2); - - users = g_list_append(users, g_strdup(tmp)); -#else + if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) + f |= GAIM_CBFLAGS_FOUNDER; + if (chu->mode & SILC_CHANNEL_UMODE_CHANOP) + f |= GAIM_CBFLAGS_OP; users = g_list_append(users, g_strdup(chu->client->nickname)); -#endif + flags = g_list_append(flags, GINT_TO_POINTER(f)); if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) { if (chu->client == conn->local_entry) @@ -1000,8 +992,9 @@ } silc_hash_table_list_reset(&htl); - gaim_conv_chat_add_users(GAIM_CONV_CHAT(convo), users); + gaim_conv_chat_add_users(GAIM_CONV_CHAT(convo), users, flags); g_list_free(users); + g_list_free(flags); /* Set topic */ if (channel->topic)
--- a/src/protocols/silc/ops.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/silc/ops.c Sat Jul 17 18:11:12 2004 +0000 @@ -272,7 +272,7 @@ g_snprintf(buf, sizeof(buf), "%s@%s", client_entry->username, client_entry->hostname); gaim_conv_chat_add_user(GAIM_CONV_CHAT(convo), - g_strdup(client_entry->nickname), buf); + g_strdup(client_entry->nickname), buf, GAIM_CBFLAGS_NONE); break; @@ -422,39 +422,47 @@ break; case SILC_NOTIFY_TYPE_CUMODE_CHANGE: - idtype = va_arg(va, int); - entry = va_arg(va, void *); - mode = va_arg(va, SilcUInt32); - client_entry2 = va_arg(va, SilcClientEntry); - channel = va_arg(va, SilcChannelEntry); + { + GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; + idtype = va_arg(va, int); + entry = va_arg(va, void *); + mode = va_arg(va, SilcUInt32); + client_entry2 = va_arg(va, SilcClientEntry); + channel = va_arg(va, SilcChannelEntry); - convo = gaim_find_conversation_with_account(channel->channel_name, - sg->account); - if (!convo) - break; + convo = gaim_find_conversation_with_account(channel->channel_name, + sg->account); + if (!convo) + break; - if (idtype == SILC_ID_CLIENT) - name = ((SilcClientEntry)entry)->nickname; - else if (idtype == SILC_ID_SERVER) - name = ((SilcServerEntry)entry)->server_name; - else - name = ((SilcChannelEntry)entry)->channel_name; - if (!name) - break; + if (idtype == SILC_ID_CLIENT) + name = ((SilcClientEntry)entry)->nickname; + else if (idtype == SILC_ID_SERVER) + name = ((SilcServerEntry)entry)->server_name; + else + name = ((SilcChannelEntry)entry)->channel_name; + if (!name) + break; - if (mode) { - silcgaim_get_chumode_string(mode, buf2, sizeof(buf2)); - g_snprintf(buf, sizeof(buf), - _("<I>%s</I> set <I>%s's</I> modes to: %s"), name, - client_entry2->nickname, buf2); - } else { - g_snprintf(buf, sizeof(buf), - _("<I>%s</I> removed all <I>%s's</I> modes"), name, - client_entry2->nickname); + if (mode) { + silcgaim_get_chumode_string(mode, buf2, sizeof(buf2)); + g_snprintf(buf, sizeof(buf), + _("<I>%s</I> set <I>%s's</I> modes to: %s"), name, + client_entry2->nickname, buf2); + if (mode & SILC_CHANNEL_UMODE_CHANFO) + flags |= GAIM_CBFLAGS_FOUNDER; + if (mode & SILC_CHANNEL_UMODE_CHANOP) + flags |= GAIM_CBFLAGS_OP; + } else { + g_snprintf(buf, sizeof(buf), + _("<I>%s</I> removed all <I>%s's</I> modes"), name, + client_entry2->nickname); + } + gaim_conv_chat_write(GAIM_CONV_CHAT(convo), channel->channel_name, + buf, GAIM_MESSAGE_SYSTEM, time(NULL)); + gaim_conv_chat_user_set_flags(GAIM_CONV_CHAT(convo), client_entry2->nickname, flags); + break; } - gaim_conv_chat_write(GAIM_CONV_CHAT(convo), channel->channel_name, - buf, GAIM_MESSAGE_SYSTEM, time(NULL)); - break; case SILC_NOTIFY_TYPE_MOTD: tmp = va_arg(va, char *);
--- a/src/protocols/toc/toc.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/toc/toc.c Sat Jul 17 18:11:12 2004 +0000 @@ -830,7 +830,7 @@ if (in && (*in == 'T')) while ((buddy = strtok(NULL, ":")) != NULL) - gaim_conv_chat_add_user(chat, buddy, NULL); + gaim_conv_chat_add_user(chat, buddy, NULL, GAIM_CBFLAGS_NONE); else while ((buddy = strtok(NULL, ":")) != NULL) gaim_conv_chat_remove_user(chat, buddy, NULL);
--- a/src/protocols/yahoo/yahoochat.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/yahoo/yahoochat.c Sat Jul 17 18:11:12 2004 +0000 @@ -69,36 +69,24 @@ yahoo_packet_free(pkt); } -static gint _mystrcmpwrapper(gconstpointer a, gconstpointer b) -{ - return strcmp(a, b); -} - /* this is slow, and different from the gaim_* version in that it (hopefully) won't add a user twice */ void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers) { - GList *users, *i, *j; - - users = gaim_conv_chat_get_users(chat); + GList *i; for (i = newusers; i; i = i->next) { - j = g_list_find_custom(users, i->data, _mystrcmpwrapper); - if (j) + if (gaim_conv_chat_find_user(chat, i->data)) continue; - gaim_conv_chat_add_user(chat, i->data, NULL); + gaim_conv_chat_add_user(chat, i->data, NULL, GAIM_CBFLAGS_NONE); } } void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason) { - GList *users; - - users = gaim_conv_chat_get_users(chat); - - if ((g_list_find_custom(users, user, _mystrcmpwrapper))) + if (gaim_conv_chat_find_user(chat, user)) return; - gaim_conv_chat_add_user(chat, user, reason); + gaim_conv_chat_add_user(chat, user, reason, GAIM_CBFLAGS_NONE); } static GaimConversation *yahoo_find_conference(GaimConnection *gc, const char *name) @@ -413,6 +401,10 @@ if (room && (!c || gaim_conv_chat_has_left(GAIM_CONV_CHAT(c))) && members && ((g_list_length(members) > 1) || !g_ascii_strcasecmp(members->data, gaim_connection_get_display_name(gc)))) { + int i; + GList *flags = NULL; + for (i = 0; i < g_list_length(members); i++) + flags = g_list_append(flags, GINT_TO_POINTER(GAIM_CBFLAGS_NONE)); if (c && gaim_conv_chat_has_left(GAIM_CONV_CHAT(c))) { /* this might be a hack, but oh well, it should nicely */ char *tmpmsg; @@ -424,7 +416,7 @@ gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); yd->in_chat = 1; yd->chat_name = g_strdup(room); - gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members); + gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members, flags); tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room); gaim_conv_chat_write(GAIM_CONV_CHAT(c), "", tmpmsg, GAIM_MESSAGE_SYSTEM, time(NULL)); @@ -435,7 +427,7 @@ gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); yd->in_chat = 1; yd->chat_name = g_strdup(room); - gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members); + gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members, flags); } } else if (c) { yahoo_chat_add_users(GAIM_CONV_CHAT(c), members); @@ -600,7 +592,8 @@ yahoo_packet_hash(pkt, 1, dn); for (w = who; w; w = w->next) { - yahoo_packet_hash(pkt, 3, (char *)w->data); + const char *name = gaim_conv_chat_cb_get_name(w->data); + yahoo_packet_hash(pkt, 3, name); } yahoo_packet_hash(pkt, 57, room); @@ -626,8 +619,10 @@ pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 1, dn); - for (who = members; who; who = who->next) - yahoo_packet_hash(pkt, 53, (char *)who->data); + for (who = members; who; who = who->next) { + const char *name = gaim_conv_chat_cb_get_name(who->data); + yahoo_packet_hash(pkt, 53, name); + } yahoo_packet_hash(pkt, 57, room); yahoo_packet_hash(pkt, 14, msg2); if (utf8) @@ -663,7 +658,7 @@ if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn)) continue; yahoo_packet_hash(pkt, 3, memarr[i]); - gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), memarr[i], NULL); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), memarr[i], NULL, GAIM_CBFLAGS_NONE); } } yahoo_send_packet(yd, pkt); @@ -695,10 +690,11 @@ yahoo_packet_hash(pkt, 58, msg?msg2:""); yahoo_packet_hash(pkt, 13, "0"); for(; members; members = members->next) { - if (!strcmp(members->data, dn)) + const char *name = gaim_conv_chat_cb_get_name(members->data); + if (!strcmp(name, dn)) continue; - yahoo_packet_hash(pkt, 52, (char *)members->data); - yahoo_packet_hash(pkt, 53, (char *)members->data); + yahoo_packet_hash(pkt, 52, name); + yahoo_packet_hash(pkt, 53, name); } yahoo_send_packet(yd, pkt);
--- a/src/protocols/yahoo/ycht.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/yahoo/ycht.c Sat Jul 17 18:11:12 2004 +0000 @@ -116,12 +116,9 @@ for (i = 0; members[i]; i++) { if (new_room) { - GList l; /*if (!strcmp(members[i], gaim_connection_get_display_name(ycht->gc))) continue;*/ - l.data = members[i]; - l.next = l.prev = NULL; - gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), &l); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), members[i], NULL, GAIM_CBFLAGS_NONE); } else { yahoo_chat_add_user(GAIM_CONV_CHAT(c), members[i], NULL); }
--- a/src/protocols/zephyr/zephyr.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/protocols/zephyr/zephyr.c Sat Jul 17 18:11:12 2004 +0000 @@ -689,8 +689,6 @@ g_free(stripped_sender); } else { zephyr_triple *zt1, *zt2; - GList *gltmp; - int found = 0; gchar *send_inst_utf8; zt1 = new_triple(notice.z_class, notice.z_class_inst, notice.z_recipient); @@ -722,18 +720,14 @@ gconv1 = gaim_find_conversation_with_account(zt2->name, zgc->account); gcc = gaim_conversation_get_chat_data(gconv1); - for (gltmp = gaim_conv_chat_get_users(gcc); gltmp; gltmp = gltmp->next) { - if (!g_ascii_strcasecmp(gltmp->data, sendertmp)) - found = 1; - } - if (!found) { + if (!gaim_conv_chat_find_user(gcc, sendertmp)) { /* force interpretation in network byte order */ unsigned char *addrs = (unsigned char *)&(notice.z_sender_addr.s_addr); gchar* ipaddr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", (unsigned char)addrs[0], (unsigned char)addrs[1], (unsigned char)addrs[2], (unsigned char) addrs[3]); - gaim_conv_chat_add_user(gcc, sendertmp, ipaddr); + gaim_conv_chat_add_user(gcc, sendertmp, ipaddr, GAIM_CBFLAGS_NONE); g_free(ipaddr); /* fix memory leak? */ }
--- a/src/signals.c Sat Jul 17 17:08:24 2004 +0000 +++ b/src/signals.c Sat Jul 17 18:11:12 2004 +0000 @@ -610,6 +610,18 @@ } void +gaim_marshal_VOID__POINTER_POINTER_UINT_UINT(GaimCallback cb, va_list args, + void *data, void **return_val) +{ + void *arg1 = va_arg(args, void *); + void *arg2 = va_arg(args, void *); + guint arg3 = va_arg(args, guint); + guint arg4 = va_arg(args, guint); + + ((void (*)(void *, void *, guint, guint, void *))cb)(arg1, arg2, arg3, arg4, data); +} + +void gaim_marshal_VOID__POINTER_POINTER_POINTER(GaimCallback cb, va_list args, void *data, void **return_val) {
--- a/src/signals.h Sat Jul 17 17:08:24 2004 +0000 +++ b/src/signals.h Sat Jul 17 18:11:12 2004 +0000 @@ -225,6 +225,8 @@ GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER_POINTER_UINT( GaimCallback cb, va_list args, void *data, void **return_val); +void gaim_marshal_VOID__POINTER_POINTER_UINT_UINT( + GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER_POINTER_POINTER( GaimCallback cb, va_list args, void *data, void **return_val); void gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER(