# HG changeset patch # User Marcus Lundblad # Date 1226605798 0 # Node ID d855ff9cf839aec94b88b017018ae5a1a763a9c5 # Parent f18f37a62971b13b48bf33eb125e33fda28f685f# Parent 1ad01909e99432a913a69e3cb0217b754fcb1791 propagate from branch 'im.pidgin.pidgin' (head 311b4db51b575e1baa7f78d751ff926475edecc3) to branch 'im.pidgin.cpw.attention_ui' (head 97b1a4ad4476369802e26e6ddf7aec5a5e46dc00) diff -r f18f37a62971 -r d855ff9cf839 libpurple/connection.h --- a/libpurple/connection.h Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/connection.h Thu Nov 13 19:49:58 2008 +0000 @@ -45,7 +45,7 @@ PURPLE_CONNECTION_NO_URLDESC = 0x0040, /**< Connection does not support descriptions with links */ PURPLE_CONNECTION_NO_IMAGES = 0x0080, /**< Connection does not support sending of images */ PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY = 0x0100, /**< Connection supports sending and receiving custom smileys */ - + } PurpleConnectionFlags; typedef enum diff -r f18f37a62971 -r d855ff9cf839 libpurple/conversation.c --- a/libpurple/conversation.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/conversation.c Thu Nov 13 19:49:58 2008 +0000 @@ -960,6 +960,16 @@ g_free(displayed); } +void +purple_conversation_attention(PurpleConversation *conv, const char *who, + guint type, PurpleMessageFlags flags, time_t mtime) +{ + PurpleAccount *account = purple_conversation_get_account(conv); + purple_signal_emit(purple_conversations_get_handle(), + flags == PURPLE_MESSAGE_SEND ? "sent-attention" : "got-attention", + account, who, conv, type); +} + gboolean purple_conversation_has_focus(PurpleConversation *conv) { @@ -2180,7 +2190,27 @@ purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONVERSATION), purple_value_new(PURPLE_TYPE_UINT)); - + + purple_signal_register(handle, "sent-attention", + purple_marshal_VOID__POINTER_POINTER_POINTER_UINT, + NULL, 4, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_CONVERSATION), + purple_value_new(PURPLE_TYPE_UINT)); + + purple_signal_register(handle, "got-attention", + purple_marshal_VOID__POINTER_POINTER_POINTER_UINT, + NULL, 4, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_CONVERSATION), + purple_value_new(PURPLE_TYPE_UINT)); + purple_signal_register(handle, "sending-im-msg", purple_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3, diff -r f18f37a62971 -r d855ff9cf839 libpurple/conversation.h --- a/libpurple/conversation.h Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/conversation.h Thu Nov 13 19:49:58 2008 +0000 @@ -645,7 +645,21 @@ const char *message, PurpleMessageFlags flags, time_t mtime); - +/** + * Sends an attention to a conversation window. + * + * This is to be called by prpls to tell UIs to set off the action for + * an attention message + * + * @param conv The conversation + * @param who The user who sent the attention + * @param type The attention type (will be 0 for protocols that only have 1 type) + * @param flags The message flags (send, receive) + * @param mtime The time the attentsion was sent + */ +void purple_conversation_attention(PurpleConversation *conv, const char *who, + guint attention_type, PurpleMessageFlags flags, time_t mtime); + /** Set the features as supported for the given conversation. @param conv The conversation diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Thu Nov 13 19:49:58 2008 +0000 @@ -1645,9 +1645,12 @@ PurpleStatusType *type; GList *types = NULL; PurpleValue *priority_value; + PurpleValue *buzz_enabled; priority_value = purple_value_new(PURPLE_TYPE_INT); purple_value_set_int(priority_value, 1); + buzz_enabled = purple_value_new(PURPLE_TYPE_BOOLEAN); + purple_value_set_boolean(buzz_enabled, TRUE); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_ONLINE), NULL, TRUE, TRUE, FALSE, @@ -1656,7 +1659,7 @@ "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING), "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), - "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), + "buzz", _("Allow Buzz"), buzz_enabled, NULL); types = g_list_append(types, type); @@ -1670,7 +1673,7 @@ "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING), "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), - "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), + "buzz", _("Allow Buzz"), buzz_enabled, NULL); types = g_list_append(types, type); @@ -1684,7 +1687,7 @@ "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING), "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), - "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), + "buzz", _("Allow Buzz"), buzz_enabled, NULL); types = g_list_append(types, type); @@ -1698,7 +1701,7 @@ "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING), "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), - "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), + "buzz", _("Allow Buzz"), buzz_enabled, NULL); types = g_list_append(types, type); @@ -1712,7 +1715,6 @@ "mood", _("Mood"), purple_value_new(PURPLE_TYPE_STRING), "moodtext", _("Mood Text"), purple_value_new(PURPLE_TYPE_STRING), "nick", _("Nickname"), purple_value_new(PURPLE_TYPE_STRING), - "buzz", _("Allow Buzz"), purple_value_new(PURPLE_TYPE_BOOLEAN), NULL); types = g_list_append(types, type); @@ -2295,8 +2297,13 @@ JabberBuddy *jb; JabberBuddyResource *jbr; - GList *iter; - + PurpleConnection *gc = js->gc; + PurpleAccount *account = purple_connection_get_account(gc); + PurpleConversation *conv = + purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, username, + account); + gchar *str; + if(!username) return FALSE; @@ -2305,53 +2312,62 @@ *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), username); return FALSE; } - + jbr = jabber_buddy_find_resource(jb, NULL); - if(!jbr) { - *error = g_strdup_printf(_("Unable to buzz, because user %s might be offline."), username); - return FALSE; - } - - if(!jbr->caps) { - *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), username); + if (!jbr) { + *error = g_strdup_printf(_("Unable to buzz, because user %s might be offline."), + username); return FALSE; } - - for(iter = jbr->caps->features; iter; iter = g_list_next(iter)) { - if(!strcmp(iter->data, "http://www.xmpp.org/extensions/xep-0224.html#ns")) { - xmlnode *buzz, *msg = xmlnode_new("message"); - gchar *to; + + if (jabber_resource_has_capability(jbr, XEP_0224_NAMESPACE)) { + xmlnode *buzz, *msg = xmlnode_new("message"); + gchar *to; - to = g_strdup_printf("%s/%s", username, jbr->name); - xmlnode_set_attrib(msg, "to", to); - g_free(to); + to = g_strdup_printf("%s/%s", username, jbr->name); + xmlnode_set_attrib(msg, "to", to); + g_free(to); - /* avoid offline storage */ - xmlnode_set_attrib(msg, "type", "headline"); + /* avoid offline storage */ + xmlnode_set_attrib(msg, "type", "headline"); - buzz = xmlnode_new_child(msg, "attention"); - xmlnode_set_namespace(buzz, "http://www.xmpp.org/extensions/xep-0224.html#ns"); + buzz = xmlnode_new_child(msg, "attention"); + xmlnode_set_namespace(buzz, XEP_0224_NAMESPACE); - jabber_send(js, msg); - xmlnode_free(msg); + jabber_send(js, msg); + xmlnode_free(msg); - return TRUE; - } + str = g_strdup_printf(_("Buzzing %s..."), username); + purple_conversation_write(conv, NULL, str, + PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL)); + g_free(str); + + return TRUE; + } else { + *error = g_strdup_printf(_("Unable to buzz, because the user %s does not support it."), username); + return FALSE; } - - *error = g_strdup_printf(_("Unable to buzz, because the user %s does not support it."), username); - return FALSE; } static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data) { JabberStream *js = conv->account->gc->proto_data; - - if(!args || !args[0]) - return PURPLE_CMD_RET_FAILED; - - return _jabber_send_buzz(js, args[0], error) ? PURPLE_CMD_RET_OK : PURPLE_CMD_RET_FAILED; + const gchar *who; + + if (!args || !args[0]) { + /* use the buddy from conversation, if it's a one-to-one conversation */ + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + who = purple_conversation_get_name(conv); + } else { + return PURPLE_CMD_RET_FAILED; + } + } else { + who = args[0]; + } + + purple_conversation_attention(conv, who, 0, PURPLE_MESSAGE_SEND, time(NULL)); + return _jabber_send_buzz(js, who, error) ? PURPLE_CMD_RET_OK : PURPLE_CMD_RET_FAILED; } GList *jabber_attention_types(PurpleAccount *account) @@ -2372,7 +2388,13 @@ gchar *error = NULL; if (!_jabber_send_buzz(js, username, &error)) { + PurpleAccount *account = purple_connection_get_account(gc); + PurpleConversation *conv = + purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, + username, account); purple_debug_error("jabber", "jabber_send_attention: jabber_cmd_buzz failed with error: %s\n", error ? error : "(NULL)"); + purple_conversation_write(conv, username, error, + PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL)); g_free(error); return FALSE; } @@ -2464,8 +2486,9 @@ "prpl-jabber", jabber_cmd_ping, _("ping <jid>: Ping a user/component/server."), NULL); - purple_cmd_register("buzz", "s", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY, + purple_cmd_register("buzz", "w", PURPLE_CMD_P_PRPL, + PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY | + PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", jabber_cmd_buzz, _("buzz: Buzz a user to get their attention"), NULL); } diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Thu Nov 13 19:49:58 2008 +0000 @@ -283,7 +283,7 @@ jabber_add_feature("avatarmeta", AVATARNAMESPACEMETA, jabber_pep_namespace_only_when_pep_enabled_cb); jabber_add_feature("avatardata", AVATARNAMESPACEDATA, jabber_pep_namespace_only_when_pep_enabled_cb); - jabber_add_feature("buzz", "http://www.xmpp.org/extensions/xep-0224.html#ns", + jabber_add_feature("buzz", XEP_0224_NAMESPACE, jabber_buzz_isenabled); jabber_add_feature("bob", XEP_0231_NAMESPACE, jabber_custom_smileys_isenabled); diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/jabber/message.c --- a/libpurple/protocols/jabber/message.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/jabber/message.c Thu Nov 13 19:49:58 2008 +0000 @@ -312,6 +312,7 @@ str = g_strdup_printf(_("%s has buzzed you!"), username); purple_conversation_write(c, NULL, str, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL)); + purple_conversation_attention(c, username, 0, PURPLE_MESSAGE_RECV, time(NULL)); g_free(username); g_free(str); } @@ -704,7 +705,7 @@ jm->type = JABBER_MESSAGE_EVENT; for(items = xmlnode_get_child(child,"items"); items; items = items->next) jm->eventitems = g_list_append(jm->eventitems, items); - } else if(!strcmp(child->name, "attention") && !strcmp(xmlns,"http://www.xmpp.org/extensions/xep-0224.html#ns")) { + } else if(!strcmp(child->name, "attention") && !strcmp(xmlns, XEP_0224_NAMESPACE)) { jm->hasBuzz = TRUE; } else if(!strcmp(child->name, "error")) { const char *code = xmlnode_get_attrib(child, "code"); diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/jabber/message.h --- a/libpurple/protocols/jabber/message.h Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/jabber/message.h Thu Nov 13 19:49:58 2008 +0000 @@ -26,6 +26,8 @@ #include "jabber.h" #include "xmlnode.h" +#define XEP_0224_NAMESPACE "urn:xmpp:attention:0" + typedef struct _JabberMessage { JabberStream *js; enum { diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/msn/msn.c Thu Nov 13 19:49:58 2008 +0000 @@ -165,7 +165,9 @@ username = purple_conversation_get_name(conv); purple_prpl_send_attention(gc, username, MSN_NUDGE); - + purple_conversation_attention(conv, username, 0, PURPLE_MESSAGE_SEND, + time(NULL)); + return PURPLE_CMD_RET_OK; } diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/msn/switchboard.c --- a/libpurple/protocols/msn/switchboard.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/msn/switchboard.c Thu Nov 13 19:49:58 2008 +0000 @@ -1031,6 +1031,9 @@ else purple_prpl_got_attention(account->gc, user, MSN_NUDGE); + + purple_conversation_attention(swboard->conv, user, 0, + PURPLE_MESSAGE_RECV, time(NULL)); } else if (!strcmp(id, "2")) { /* Wink */ diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/msnp9/msn.c --- a/libpurple/protocols/msnp9/msn.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/msnp9/msn.c Thu Nov 13 19:49:58 2008 +0000 @@ -775,7 +775,8 @@ gc->proto_data = session; gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO | PURPLE_CONNECTION_NO_BGCOLOR | - PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY; + PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY | + PURPLE_CONNECTION_ALLOW_ATTENTION; msn_session_set_login_step(session, MSN_LOGIN_STEP_START); diff -r f18f37a62971 -r d855ff9cf839 libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Thu Nov 13 19:49:58 2008 +0000 @@ -878,6 +878,8 @@ username = g_markup_escape_text(im->from, -1); purple_prpl_got_attention(gc, username, YAHOO_BUZZ); + purple_conversation_attention(c, username, 0, PURPLE_MESSAGE_RECV, + time(NULL)); g_free(username); g_free(m); g_free(im); @@ -4135,6 +4137,7 @@ return PURPLE_CMD_RET_FAILED; purple_prpl_send_attention(account->gc, c->name, YAHOO_BUZZ); + purple_conversation_attention(c, c->name, 0, PURPLE_MESSAGE_SEND, time(NULL)); return PURPLE_CMD_RET_OK; } diff -r f18f37a62971 -r d855ff9cf839 libpurple/sound.h --- a/libpurple/sound.h Thu Nov 13 09:00:45 2008 +0000 +++ b/libpurple/sound.h Thu Nov 13 19:49:58 2008 +0000 @@ -51,6 +51,8 @@ PURPLE_SOUND_CHAT_SAY, /**< Someone else says somthing in a chat. */ PURPLE_SOUND_POUNCE_DEFAULT, /**< Default sound for a buddy pounce. */ PURPLE_SOUND_CHAT_NICK, /**< Someone says your name in a chat. */ + PURPLE_SOUND_SEND_ATTENTION, /**< Send an attention */ + PURPLE_SOUND_GOT_ATTENTION, /**< Got an attention */ PURPLE_NUM_SOUNDS /**< Total number of sounds. */ } PurpleSoundEventID; diff -r f18f37a62971 -r d855ff9cf839 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/gtkconv.c Thu Nov 13 19:49:58 2008 +0000 @@ -1212,6 +1212,20 @@ } static void +menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget) +{ + PidginWindow *win = data; + PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); + + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { + purple_prpl_send_attention(purple_conversation_get_gc(conv), + purple_conversation_get_name(conv), 0); + purple_conversation_attention(conv, purple_conversation_get_name(conv), + 0, PURPLE_MESSAGE_SEND, time(NULL)); + } +} + +static void menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget) { PidginWindow *win = data; @@ -2274,6 +2288,11 @@ gtkconv = PIDGIN_CONVERSATION(conv); old_conv = gtkconv->active_conv; + purple_debug_info("gtkconv", "setting active conversation on toolbar %p\n", + conv); + gtk_imhtmltoolbar_switch_active_conversation(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), + conv); + if (old_conv == conv) return; @@ -3120,6 +3139,7 @@ { "/Conversation/sep1", NULL, NULL, 0, "", NULL }, { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "", PIDGIN_STOCK_TOOLBAR_SEND_FILE }, + { N_("/Conversation/Get _Attention"), NULL, menu_get_attention_cb, 0, "", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION }, { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb, 0, "", NULL }, { N_("/Conversation/_Get Info"), "O", menu_get_info_cb, 0, @@ -3435,6 +3455,9 @@ gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/Send File...")); + win->menu.get_attention = + gtk_item_factory_get_widget(win->menu.item_factory, + N_("/Conversation/Get Attention")); win->menu.add_pounce = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/Add Buddy Pounce...")); @@ -6325,6 +6348,7 @@ /* Deal with menu items */ gtk_widget_show(win->menu.view_log); gtk_widget_show(win->menu.send_file); + gtk_widget_show(win->menu.get_attention); gtk_widget_show(win->menu.add_pounce); gtk_widget_show(win->menu.get_info); gtk_widget_hide(win->menu.invite); @@ -6353,6 +6377,7 @@ /* Deal with menu items */ gtk_widget_show(win->menu.view_log); gtk_widget_hide(win->menu.send_file); + gtk_widget_hide(win->menu.get_attention); gtk_widget_hide(win->menu.add_pounce); gtk_widget_hide(win->menu.get_info); gtk_widget_show(win->menu.invite); @@ -6430,6 +6455,7 @@ gtk_widget_set_sensitive(win->menu.send_file, (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); + gtk_widget_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); gtk_widget_set_sensitive(win->menu.alias, (account != NULL) && (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); @@ -6450,6 +6476,7 @@ /* Then deal with menu items */ gtk_widget_set_sensitive(win->menu.view_log, TRUE); gtk_widget_set_sensitive(win->menu.send_file, FALSE); + gtk_widget_set_sensitive(win->menu.get_attention, FALSE); gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); gtk_widget_set_sensitive(win->menu.get_info, FALSE); gtk_widget_set_sensitive(win->menu.invite, FALSE); @@ -6754,6 +6781,7 @@ } } + static PurpleConversationUiOps conversation_ui_ops = { pidgin_conv_new, diff -r f18f37a62971 -r d855ff9cf839 pidgin/gtkconvwin.h --- a/pidgin/gtkconvwin.h Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/gtkconvwin.h Thu Nov 13 19:49:58 2008 +0000 @@ -51,6 +51,7 @@ GtkWidget *view_log; GtkWidget *send_file; + GtkWidget *get_attention; GtkWidget *add_pounce; GtkWidget *get_info; GtkWidget *invite; diff -r f18f37a62971 -r d855ff9cf839 pidgin/gtkimhtmltoolbar.c --- a/pidgin/gtkimhtmltoolbar.c Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Thu Nov 13 19:49:58 2008 +0000 @@ -33,6 +33,7 @@ #include "request.h" #include "pidginstock.h" #include "util.h" +#include "debug.h" #include "gtkdialogs.h" #include "gtkimhtmltoolbar.h" @@ -913,6 +914,18 @@ gtk_widget_grab_focus(toolbar->imhtml); } +static void send_attention_cb(GtkWidget *attention, GtkIMHtmlToolbar *toolbar) +{ + PurpleConversation *conv = toolbar->active_conv; + const gchar *who = purple_conversation_get_name(conv); + PurpleConnection *gc = purple_conversation_get_gc(conv); + + toggle_button_set_active_block(GTK_TOGGLE_BUTTON(toolbar->attention), FALSE, + toolbar); + purple_conversation_attention(conv, who, 0, PURPLE_MESSAGE_SEND, time(NULL)); + purple_prpl_send_attention(gc, who, 0); +} + static void update_buttons_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, GtkIMHtmlToolbar *toolbar) { gtk_widget_set_sensitive(GTK_WIDGET(toolbar->bold), buttons & GTK_IMHTML_BOLD); @@ -1232,6 +1245,8 @@ {PIDGIN_STOCK_TOOLBAR_INSERT_LINK, insert_link_cb, &toolbar->link, _("Insert Link")}, {PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, insert_image_cb, &toolbar->image, _("Insert IM Image")}, {PIDGIN_STOCK_TOOLBAR_SMILEY, insert_smiley_cb, &toolbar->smiley, _("Insert Smiley")}, + {PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, send_attention_cb, &toolbar->attention, + _("Send Attention")}, {NULL, NULL, NULL, NULL} }; int iter; @@ -1297,6 +1312,7 @@ GtkWidget *insert_button; GtkWidget *font_button; GtkWidget *smiley_button; + GtkWidget *attention_button; GtkWidget *font_menu; GtkWidget *insert_menu; GtkWidget *menuitem; @@ -1438,6 +1454,30 @@ g_signal_connect_swapped(G_OBJECT(smiley_button), "clicked", G_CALLBACK(gtk_button_clicked), toolbar->smiley); gtk_widget_show_all(smiley_button); + /* Sep */ + sep = gtk_vseparator_new(); + gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 0); + gtk_widget_show_all(sep); + + /* Attention */ + attention_button = gtk_button_new(); + gtk_button_set_relief(GTK_BUTTON(attention_button), GTK_RELIEF_NONE); + bbox = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(attention_button), bbox); + image = gtk_image_new_from_stock(PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); + label = gtk_label_new_with_mnemonic(_("_Attention!")); + gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(box), attention_button, FALSE, FALSE, 0); + g_signal_connect_swapped(G_OBJECT(attention_button), "clicked", + G_CALLBACK(gtk_button_clicked), toolbar->attention); + gtk_widget_show_all(attention_button); + + g_signal_connect(G_OBJECT(toolbar->attention), "notify::sensitive", + G_CALLBACK(button_sensitiveness_changed), attention_button); + + gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0); g_object_set_data(G_OBJECT(hbox), "lean-view", box); gtk_widget_show(box); @@ -1519,3 +1559,21 @@ g_free(toolbar->sml); toolbar->sml = g_strdup(proto_id); } + +void gtk_imhtmltoolbar_switch_active_conversation(GtkIMHtmlToolbar *toolbar, + PurpleConversation *conv) +{ + PurpleConnection *gc = purple_conversation_get_gc(conv); + PurplePlugin *prpl = purple_connection_get_prpl(gc); + + purple_debug_info("gtkimhtmltoolbar", "switch active conversation to %p\n", + conv); + toolbar->active_conv = conv; + + /* gray out attention button on protocols that don't support it + for the time being it is always disabled for chats */ + gtk_widget_set_sensitive(toolbar->attention, + conv && prpl && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM && + PURPLE_PLUGIN_PROTOCOL_INFO(prpl)->send_attention != NULL); +} + diff -r f18f37a62971 -r d855ff9cf839 pidgin/gtkimhtmltoolbar.h --- a/pidgin/gtkimhtmltoolbar.h Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/gtkimhtmltoolbar.h Thu Nov 13 19:49:58 2008 +0000 @@ -65,7 +65,8 @@ GtkWidget *image; GtkWidget *link; GtkWidget *smiley; - + GtkWidget *attention; + GtkWidget *font_dialog; GtkWidget *fgcolor_dialog; GtkWidget *bgcolor_dialog; @@ -76,6 +77,8 @@ char *sml; GtkWidget *strikethrough; GtkWidget *insert_hr; + + PurpleConversation *active_conv; }; struct _GtkIMHtmlToolbarClass { @@ -89,6 +92,8 @@ void gtk_imhtmltoolbar_attach (GtkIMHtmlToolbar *toolbar, GtkWidget *imhtml); void gtk_imhtmltoolbar_associate_smileys (GtkIMHtmlToolbar *toolbar, const char *proto_id); +void gtk_imhtmltoolbar_switch_active_conversation(GtkIMHtmlToolbar *toolbar, + PurpleConversation *conv); #ifdef __cplusplus } diff -r f18f37a62971 -r d855ff9cf839 pidgin/gtksound.c --- a/pidgin/gtksound.c Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/gtksound.c Thu Nov 13 19:49:58 2008 +0000 @@ -70,7 +70,9 @@ {N_("Others talk in chat"), "chat_msg_recv", "receive.wav"}, /* this isn't a terminator, it's the buddy pounce default sound event ;-) */ {NULL, "pounce_default", "alert.wav"}, - {N_("Someone says your username in chat"), "nick_said", "alert.wav"} + {N_("Someone says your username in chat"), "nick_said", "alert.wav"}, + {N_("Attention received"), "got_attention", "alert.wav"}, + {N_("Attention sent"), "sent_attention", "alert.wav"} }; static gboolean @@ -215,6 +217,20 @@ play_conv_event(conv, event); } +static void +sent_attention_cb(PurpleAccount *account, const char *who, + PurpleConversation *conv, guint type, PurpleSoundEventID event) +{ + play_conv_event(conv, event); +} + +static void +got_attention_cb(PurpleAccount *account, const char *who, + PurpleConversation *conv, guint type, PurpleSoundEventID event) +{ + play_conv_event(conv, event); +} + /* * We mute sounds for the 10 seconds after you log in so that * you don't get flooded with sounds when the blist shows all @@ -294,6 +310,10 @@ purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/nick_said", ""); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/enabled/pounce_default", TRUE); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/pounce_default", ""); + purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/enabled/sent_attention", TRUE); + purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/sent_attention", ""); + purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/enabled/got_attention", TRUE); + purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/got_attention", ""); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/conv_focus", TRUE); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/mute", FALSE); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/command", ""); @@ -340,6 +360,12 @@ purple_signal_connect(conv_handle, "received-chat-msg", gtk_sound_handle, PURPLE_CALLBACK(chat_msg_received_cb), GINT_TO_POINTER(PURPLE_SOUND_CHAT_SAY)); + purple_signal_connect(conv_handle, "sent-attention", gtk_sound_handle, + PURPLE_CALLBACK(sent_attention_cb), + GINT_TO_POINTER(PURPLE_SOUND_SEND_ATTENTION)); + purple_signal_connect(conv_handle, "got-attention", gtk_sound_handle, + PURPLE_CALLBACK(got_attention_cb), + GINT_TO_POINTER(PURPLE_SOUND_GOT_ATTENTION)); } static void diff -r f18f37a62971 -r d855ff9cf839 pidgin/pidginstock.c --- a/pidgin/pidginstock.c Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/pidginstock.c Thu Nov 13 19:49:58 2008 +0000 @@ -194,7 +194,8 @@ { PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, "toolbar", "select-avatar.png", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_SEND_FILE, "toolbar", "send-file.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_TRANSFER, "toolbar", "transfer.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - + { PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, "toolbar", "get-attention.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TRAY_INVISIBLE, "tray", "tray-invisible.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, diff -r f18f37a62971 -r d855ff9cf839 pidgin/pidginstock.h --- a/pidgin/pidginstock.h Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/pidginstock.h Thu Nov 13 19:49:58 2008 +0000 @@ -153,6 +153,7 @@ #define PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR "pidgin-select-avatar" #define PIDGIN_STOCK_TOOLBAR_SEND_FILE "pidgin-send-file" #define PIDGIN_STOCK_TOOLBAR_TRANSFER "pidgin-transfer" +#define PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION "pidgin-send-attention" /* Tray icons */ #define PIDGIN_STOCK_TRAY_AVAILABLE "pidgin-tray-available" diff -r f18f37a62971 -r d855ff9cf839 pidgin/pixmaps/Makefile.am --- a/pidgin/pixmaps/Makefile.am Thu Nov 13 09:00:45 2008 +0000 +++ b/pidgin/pixmaps/Makefile.am Thu Nov 13 19:49:58 2008 +0000 @@ -434,7 +434,8 @@ toolbar/16/plugins.png \ toolbar/16/send-file.png \ toolbar/16/transfer.png \ - toolbar/16/unblock.png + toolbar/16/unblock.png \ + toolbar/16/get-attention.png TOOLBAR_22_SCALABLE = \ toolbar/22/scalable/select-avatar.svg