From a42fda42abad6af64ac9a905856ee9a3095954cd Mon Sep 17 00:00:00 2001 From: dequis Date: Tue, 8 Dec 2015 19:31:05 -0300 Subject: [PATCH] Add imcb_buddy_nick_change(), like nick_hint but stronger nick_hint only works when creating new users, it's a no-op after the user is online. This new function takes care of nick changes after that. It also helps clean up couple of hacks in irc_im.c \o/ --- irc_im.c | 40 +++++++++++++++------------------------- protocols/bee.h | 1 + protocols/nogaim.c | 20 ++++++++++++++++---- protocols/nogaim.h | 1 + 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/irc_im.c b/irc_im.c index 3b0494629..614819ddd 100644 --- a/irc_im.c +++ b/irc_im.c @@ -341,7 +341,7 @@ static gboolean bee_irc_user_action_response(bee_t *bee, bee_user_t *bu, const c return TRUE; } -static gboolean bee_irc_user_nick_update(irc_user_t *iu); +static gboolean bee_irc_user_nick_update(irc_user_t *iu, gboolean offline_only); static gboolean bee_irc_user_fullname(bee_t *bee, bee_user_t *bu) { @@ -369,14 +369,21 @@ static gboolean bee_irc_user_fullname(bee_t *bee, bee_user_t *bu) imcb_log(bu->ic, "User `%s' changed name to `%s'", iu->nick, iu->fullname); } - bee_irc_user_nick_update(iu); + bee_irc_user_nick_update(iu, TRUE); return TRUE; } static gboolean bee_irc_user_nick_hint(bee_t *bee, bee_user_t *bu, const char *hint) { - bee_irc_user_nick_update((irc_user_t *) bu->ui_data); + bee_irc_user_nick_update((irc_user_t *) bu->ui_data, TRUE); + + return TRUE; +} + +static gboolean bee_irc_user_nick_change(bee_t *bee, bee_user_t *bu, const char *nick) +{ + bee_irc_user_nick_update((irc_user_t *) bu->ui_data, FALSE); return TRUE; } @@ -385,30 +392,19 @@ static gboolean bee_irc_user_group(bee_t *bee, bee_user_t *bu) { irc_user_t *iu = (irc_user_t *) bu->ui_data; irc_t *irc = (irc_t *) bee->ui_data; - bee_user_flags_t online; - - /* Take the user offline temporarily so we can change the nick (if necessary). */ - if ((online = bu->flags & BEE_USER_ONLINE)) { - bu->flags &= ~BEE_USER_ONLINE; - } bee_irc_channel_update(irc, NULL, iu); - bee_irc_user_nick_update(iu); - - if (online) { - bu->flags |= online; - bee_irc_channel_update(irc, NULL, iu); - } + bee_irc_user_nick_update(iu, FALSE); return TRUE; } -static gboolean bee_irc_user_nick_update(irc_user_t *iu) +static gboolean bee_irc_user_nick_update(irc_user_t *iu, gboolean offline_only) { bee_user_t *bu = iu->bu; char *newnick; - if (bu->flags & BEE_USER_ONLINE) { + if (offline_only && bu->flags & BEE_USER_ONLINE) { /* Ignore if the user is visible already. */ return TRUE; } @@ -431,21 +427,14 @@ static gboolean bee_irc_user_nick_update(irc_user_t *iu) void bee_irc_user_nick_reset(irc_user_t *iu) { bee_user_t *bu = iu->bu; - bee_user_flags_t online; if (bu == FALSE) { return; } - /* In this case, pretend the user is offline. */ - if ((online = bu->flags & BEE_USER_ONLINE)) { - bu->flags &= ~BEE_USER_ONLINE; - } - nick_del(bu); - bee_irc_user_nick_update(iu); + bee_irc_user_nick_update(iu, FALSE); - bu->flags |= online; } /* IRC->IM calls */ @@ -1145,4 +1134,5 @@ const struct bee_ui_funcs irc_ui_funcs = { bee_irc_ft_finished, bee_irc_log, + bee_irc_user_nick_change, }; diff --git a/protocols/bee.h b/protocols/bee.h index 4a053845d..d22e4d851 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -130,6 +130,7 @@ typedef struct bee_ui_funcs { void (*ft_finished)(struct im_connection *ic, struct file_transfer *ft); void (*log)(bee_t *bee, const char *tag, const char *msg); + gboolean (*user_nick_change)(bee_t *bee, bee_user_t *bu, const char *hint); } bee_ui_funcs_t; diff --git a/protocols/nogaim.c b/protocols/nogaim.c index a5eda2e03..a1aba51f2 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -478,9 +478,8 @@ void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group bee_user_free(ic->bee, bee_user_by_handle(ic->bee, ic, handle)); } -/* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM - modules to suggest a nickname for a handle. */ -void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick) +/* Implements either imcb_buddy_nick_hint() or imcb_buddy_nick_change() depending on the value of 'change' */ +static void buddy_nick_hint_or_change(struct im_connection *ic, const char *handle, const char *nick, gboolean change) { bee_t *bee = ic->bee; bee_user_t *bu = bee_user_by_handle(bee, ic, handle); @@ -492,11 +491,24 @@ void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const ch g_free(bu->nick); bu->nick = g_strdup(nick); - if (bee->ui->user_nick_hint) { + if (change && bee->ui->user_nick_change) { + bee->ui->user_nick_change(bee, bu, nick); + } else if (!change && bee->ui->user_nick_hint) { bee->ui->user_nick_hint(bee, bu, nick); } } +/* Soft variant, for newly created users. Does nothing if it's already online */ +void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick) +{ + buddy_nick_hint_or_change(ic, handle, nick, FALSE); +} + +/* Hard variant, always changes the nick */ +void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick) +{ + buddy_nick_hint_or_change(ic, handle, nick, TRUE); +} struct imcb_ask_cb_data { struct im_connection *ic; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 3b271b453..40b1ed7bb 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -323,6 +323,7 @@ G_MODULE_EXPORT void imcb_add_buddy(struct im_connection *ic, const char *handle G_MODULE_EXPORT void imcb_remove_buddy(struct im_connection *ic, const char *handle, char *group); G_MODULE_EXPORT void imcb_rename_buddy(struct im_connection *ic, const char *handle, const char *realname); G_MODULE_EXPORT void imcb_buddy_nick_hint(struct im_connection *ic, const char *handle, const char *nick); +G_MODULE_EXPORT void imcb_buddy_nick_change(struct im_connection *ic, const char *handle, const char *nick); G_MODULE_EXPORT void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data); G_MODULE_EXPORT void imcb_buddy_typing(struct im_connection *ic, const char *handle, guint32 flags);