Mercurial > pidgin
changeset 19618:a38ee5d9eedf
merge of 'bf68a58b8bbc1d43f4ebe7b94bd47282cb66f26e'
and 'daa5fcdfa800915c5bed0df9809e1b367f6b56da'
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Mon, 03 Sep 2007 21:04:02 +0000 |
parents | 66882abaf8f1 (current diff) f3c83871a442 (diff) |
children | 5e03760e4c6b |
files | libpurple/util.c pidgin/gtkmain.c |
diffstat | 18 files changed, 414 insertions(+), 255 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Mon Sep 03 21:02:52 2007 +0000 +++ b/COPYRIGHT Mon Sep 03 21:04:02 2007 +0000 @@ -338,6 +338,7 @@ Michael Shkutkov Ettore Simone John Silvestri +Ankit Singla Craig Slusher Alex Smith Brad Smith @@ -375,6 +376,7 @@ Warren Togami Stu Tomlinson Bill Tompkins +Gal Topper Chris Toshok Ken Tossell Tom Tromey
--- a/ChangeLog.API Mon Sep 03 21:02:52 2007 +0000 +++ b/ChangeLog.API Mon Sep 03 21:04:02 2007 +0000 @@ -9,9 +9,13 @@ * serv_send_attention(), serv_got_attention(), as well as send_attention and attention_types in PurplePluginProtocolInfo. This new API is used for zapping in MySpaceIM, buzzing in Yahoo, and nudging in MSN. + Changed: * purple_prefs_load is now called within purple_prefs_init. The UI no longer needs to call it. + * writing-im-msg now receives the conversation name as the who + argument if the caller of purple_conversation_write didn't + provide a value for who. Pidgin: Added: @@ -21,6 +25,10 @@ conversation * conversation-hiding and conversation-displayed signals. + Changed: + * pidgin_conversations_fill_menu now also adds a separator and a 'Show + All' item if there are more than one conversations in the list. + Finch: Added: * finch_sound_is_enabled
--- a/libpurple/account.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/account.c Mon Sep 03 21:04:02 2007 +0000 @@ -1720,15 +1720,6 @@ purple_account_get_protocol_id(const PurpleAccount *account) { g_return_val_if_fail(account != NULL, NULL); - /* - * HACK by Seanegan - */ - if (!strcmp(account->protocol_id, "prpl-oscar")) { - if (isdigit(account->username[0])) - return "prpl-icq"; - else - return "prpl-aim"; - } return account->protocol_id; }
--- a/libpurple/conversation.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/conversation.c Mon Sep 03 21:04:02 2007 +0000 @@ -869,6 +869,10 @@ displayed = g_strdup(message); + if (who == NULL || *who == '\0') + who = purple_conversation_get_name(conv); + alias = who; + plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( purple_conversations_get_handle(), @@ -883,11 +887,6 @@ return; } - if (who == NULL || *who == '\0') - who = purple_conversation_get_name(conv); - - alias = who; - if (account != NULL) { prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account)));
--- a/libpurple/protocols/msn/slp.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/msn/slp.c Mon Sep 03 21:04:02 2007 +0000 @@ -343,7 +343,7 @@ if (xfer) { bin = (char *)purple_base64_decode(context, &bin_len); - file_size = GUINT32_FROM_LE(*((gsize *)bin + 2)); + file_size = GUINT32_FROM_LE(*(gsize *)(bin + 2)); uni_name = (gunichar2 *)(bin + 20); while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
--- a/libpurple/protocols/myspace/CHANGES Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/myspace/CHANGES Mon Sep 03 21:04:02 2007 +0000 @@ -6,7 +6,7 @@ * Support myim:sendIM and addContact URLs with cID and uID parameters. * Fix #2722, only check for mail if "New mail notifications" is enabled. * Modularize msimprpl. - +* Pidgin 2.1.1 only. 2007-08-23 Jeff Connelly <pidgin@xyzzy.cjb.net> - 0.16 * Add option to add all friends from myspace.com to your buddy list (#2660)
--- a/libpurple/protocols/myspace/markup.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/myspace/markup.c Mon Sep 03 21:04:02 2007 +0000 @@ -669,6 +669,8 @@ /** High-level function to convert Purple (HTML) to MySpaceIM markup. * + * TODO: consider using purple_markup_html_to_xhtml() to make valid XML. + * * @return HTML markup string, must be g_free()'d. */ gchar * html_to_msim_markup(MsimSession *session, const gchar *raw)
--- a/libpurple/protocols/myspace/myspace.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.c Mon Sep 03 21:04:02 2007 +0000 @@ -1066,9 +1066,12 @@ statstring = purple_status_get_attr_string(status, "message"); if (!statstring) { - statstring = g_strdup(""); + statstring = ""; } + /* Status strings are plain text. */ + statstring = purple_markup_strip_html(statstring); + msim_set_status_code(session, status_code, g_strdup(statstring)); } @@ -1441,7 +1444,7 @@ /* If a local alias wasn't set, set it to user's username. */ if (!session->account->alias || !strlen(session->account->alias)) - session->account->alias = session->username; + purple_account_set_alias(session->account, session->username); /* The session is now set up, ready to be connected. This emits the * signedOn signal, so clients can now do anything with msimprpl, and @@ -1713,7 +1716,7 @@ PurpleBuddyList *blist; MsimUser *user; GList *list; - gchar *status_headline; + gchar *status_headline, *status_headline_escaped; gint status_code, purple_status_code; gchar *username; @@ -1768,8 +1771,16 @@ purple_debug_info("msim", "msim_status: found buddy %s\n", username); } + /* The status headline is plaintext, but libpurple treats it as HTML, + * so escape any HTML characters to their entity equivalents. */ + status_headline_escaped = g_markup_escape_text(status_headline, strlen(status_headline)); + g_free(status_headline); + + if (user->headline) + g_free(user->headline); + /* don't copy; let the MsimUser own the headline, memory-wise */ - user->headline = status_headline; + user->headline = status_headline_escaped; /* Set user status */ switch (status_code) { @@ -2618,7 +2629,7 @@ switch (GPOINTER_TO_UINT(user_data)) { case MSIM_CONTACT_LIST_IMPORT_ALL_FRIENDS: - msg = g_strdup_printf(_("%d buddies were added or updated"), buddy_count); + msg = g_strdup_printf(_("%d buddies were added or updated from the server (including buddies already on the server-side list)"), buddy_count); purple_notify_info(session->account, _("Add contacts from server"), msg, NULL); g_free(msg); break;
--- a/libpurple/protocols/myspace/myspace.h Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.h Mon Sep 03 21:04:02 2007 +0000 @@ -96,7 +96,7 @@ #define MSIM_LANGUAGE_NAME_ENGLISH "ENGLISH" /* msimprpl version string of this plugin */ -#define MSIM_PRPL_VERSION_STRING "0.16" +#define MSIM_PRPL_VERSION_STRING "0.18" /* Default server */ #define MSIM_SERVER "im.myspace.akadns.net" @@ -186,10 +186,10 @@ /** A type of "attention" message (zap, nudge, buzz, etc. depending on the * protocol) that can be sent and received. */ struct _MsimAttentionType { - PurpleStoredImage *icon; - const gchar *description; /**< Shown before sending. */ + const gchar *name; /**< Shown before sending. */ const gchar *incoming_description; /**< Shown when sent. */ const gchar *outgoing_description; /**< Shown when received. */ + const gchar *icon_name; }; #endif
--- a/libpurple/protocols/myspace/release.sh Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/protocols/myspace/release.sh Mon Sep 03 21:04:02 2007 +0000 @@ -4,7 +4,7 @@ # Package a new msimprpl for release. Must be run with bash. -VERSION=0.16 +VERSION=0.18 make # Include 'myspace' directory in archive, so it can easily be unextracted # into ~/pidgin/libpurple/protocols at the correct location.
--- a/libpurple/stun.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/stun.c Mon Sep 03 21:04:02 2007 +0000 @@ -252,7 +252,7 @@ sinptr = (struct sockaddr_in *) &ifr->ifr_addr; if(sinptr->sin_addr.s_addr == in.s_addr) { /* no NAT */ - purple_debug_info("stun", "no nat"); + purple_debug_info("stun", "no nat\n"); nattype.type = PURPLE_STUN_NAT_TYPE_PUBLIC_IP; } }
--- a/libpurple/util.c Mon Sep 03 21:02:52 2007 +0000 +++ b/libpurple/util.c Mon Sep 03 21:04:02 2007 +0000 @@ -4460,10 +4460,11 @@ const char *_purple_oscar_convert(const char *act, const char *protocol) { if (protocol && act && strcmp(protocol, "prpl-oscar") == 0) { - if (isdigit(*act)) - protocol = "prpl-icq"; - else - protocol = "prpl-aim"; + int i; + for (i = 0; act[i] != '\0'; i++) + if (!isdigit(act[i])) + return "prpl-aim"; + return "prpl-icq"; } return protocol; }
--- a/pidgin/gtkaccount.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkaccount.c Mon Sep 03 21:04:02 2007 +0000 @@ -652,8 +652,10 @@ if (!(dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK)) gtk_widget_hide(dialog->new_mail_check); - if (dialog->prpl_info->icon_spec.format == NULL) + if (dialog->prpl_info->icon_spec.format == NULL) { + gtk_widget_hide(dialog->icon_check); gtk_widget_hide(dialog->icon_hbox); + } } if (dialog->account != NULL) {
--- a/pidgin/gtkblist.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkblist.c Mon Sep 03 21:04:02 2007 +0000 @@ -2870,11 +2870,11 @@ { N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL }, { "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL }, { N_("/Buddies/Show"), NULL, NULL, 0, "<Branch>", NULL}, - { N_("/Buddies/Show/Show _Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL }, - { N_("/Buddies/Show/Show _Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL }, - { N_("/Buddies/Show/Show Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL }, - { N_("/Buddies/Show/Show Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL }, - { N_("/Buddies/Show/Show _Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL }, + { N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL }, + { N_("/Buddies/Show/_Empty Groups"), NULL, pidgin_blist_show_empty_groups_cb, 1, "<CheckItem>", NULL }, + { N_("/Buddies/Show/Buddy _Details"), NULL, pidgin_blist_buddy_details_cb, 1, "<CheckItem>", NULL }, + { N_("/Buddies/Show/Idle _Times"), NULL, pidgin_blist_show_idle_time_cb, 1, "<CheckItem>", NULL }, + { N_("/Buddies/Show/_Protocol Icons"), NULL, pidgin_blist_show_protocol_icons_cb, 1, "<CheckItem>", NULL }, { N_("/Buddies/_Sort Buddies"), NULL, NULL, 0, "<Branch>", NULL }, { "/Buddies/sep2", NULL, NULL, 0, "<Separator>", NULL }, { N_("/Buddies/_Add Buddy..."), "<CTL>B", pidgin_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, @@ -4590,22 +4590,22 @@ /* set the Show Offline Buddies option. must be done * after the treeview or faceprint gets mad. -Robot101 */ - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Offline Buddies"))), + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies")); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Empty Groups"))), + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Empty Groups"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups")); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/sound/mute")); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Buddy Details"))), + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons")); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Idle Times"))), + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Idle Times"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time")); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Show Protocol Icons"))), + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Protocol Icons"))), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")); if(!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"))
--- a/pidgin/gtkconv.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkconv.c Mon Sep 03 21:04:02 2007 +0000 @@ -139,6 +139,7 @@ static void generate_send_to_items(PidginWindow *win); /* Prototypes. <-- because Paco-Paco hates this comment. */ +static gboolean infopane_entry_activate(PidginConversation *gtkconv); static void got_typing_keypress(PidginConversation *gtkconv, gboolean first); static void gray_stuff_out(PidginConversation *gtkconv); static GList *generate_invite_user_names(PurpleConnection *gc); @@ -157,7 +158,8 @@ static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); -static gboolean alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv); +static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); +static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, int width, int height); @@ -1791,17 +1793,108 @@ } static gboolean +conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event) +{ + PidginWindow *win; + PurpleConversation *conv; + int curconv; + + conv = gtkconv->active_conv; + win = gtkconv->win; + curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook)); + + /* If CTRL was held down... */ + if (event->state & GDK_CONTROL_MASK) { + switch (event->keyval) { + case GDK_Page_Down: + case ']': + if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); + else + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); + return TRUE; + break; + + case GDK_Page_Up: + case '[': + if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); + else + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); + return TRUE; + break; + + case GDK_Tab: + case GDK_ISO_Left_Tab: + if (event->state & GDK_SHIFT_MASK) { + move_to_next_unread_tab(gtkconv, FALSE); + } else { + move_to_next_unread_tab(gtkconv, TRUE); + } + + return TRUE; + break; + + case GDK_comma: + gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), + gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), + curconv - 1); + break; + + case GDK_period: + gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), + gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), +#if GTK_CHECK_VERSION(2,2,0) + (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); +#else + (curconv + 1) % g_list_length(GTK_NOTEBOOK(win->notebook)->children)); +#endif + break; + + } /* End of switch */ + } + + /* If ALT (or whatever) was held down... */ + else if (event->state & GDK_MOD1_MASK) + { + if (event->keyval > '0' && event->keyval <= '9') + { + guint switchto = event->keyval - '1'; + if (switchto < pidgin_conv_window_get_gtkconv_count(win)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), switchto); + + return TRUE; + } + } + + /* If neither CTRL nor ALT were held down... */ + else + { + switch (event->keyval) { + case GDK_F2: + if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { + infopane_entry_activate(gtkconv); + return TRUE; + } + break; + } + } + return FALSE; +} + +static gboolean entry_key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer data) { PidginWindow *win; PurpleConversation *conv; PidginConversation *gtkconv; - int curconv; gtkconv = (PidginConversation *)data; conv = gtkconv->active_conv; win = gtkconv->win; - curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook)); + + if (conv_keypress_common(gtkconv, event)) + return TRUE; /* If CTRL was held down... */ if (event->state & GDK_CONTROL_MASK) { @@ -1899,88 +1992,32 @@ return TRUE; break; - - case GDK_Page_Down: - case ']': - if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); - else - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); - return TRUE; - break; - - case GDK_Page_Up: - case '[': - if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); - else - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); - return TRUE; - break; - - case GDK_Tab: - case GDK_ISO_Left_Tab: - if (event->state & GDK_SHIFT_MASK) { - move_to_next_unread_tab(gtkconv, FALSE); - } else { - move_to_next_unread_tab(gtkconv, TRUE); - } - - return TRUE; - break; - - case GDK_comma: - gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), - gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), - curconv - 1); - break; - - case GDK_period: - gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), - gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), -#if GTK_CHECK_VERSION(2,2,0) - (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); -#else - (curconv + 1) % g_list_length(GTK_NOTEBOOK(win->notebook)->children)); -#endif - break; - } /* End of switch */ } /* If ALT (or whatever) was held down... */ - else if (event->state & GDK_MOD1_MASK) - { - if (event->keyval > '0' && event->keyval <= '9') - { - guint switchto = event->keyval - '1'; - if (switchto < pidgin_conv_window_get_gtkconv_count(win)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), switchto); - - return TRUE; - } + else if (event->state & GDK_MOD1_MASK) { + } /* If neither CTRL nor ALT were held down... */ - else - { - switch (event->keyval) - { - case GDK_Tab: - if (gtkconv->entry != entry) - break; - return tab_complete(conv); + else { + switch (event->keyval) { + case GDK_Tab: + if (gtkconv->entry != entry) break; - - case GDK_Page_Up: - gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); - return TRUE; - break; - - case GDK_Page_Down: - gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); - return TRUE; - break; + return tab_complete(conv); + break; + + case GDK_Page_Up: + gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); + return TRUE; + break; + + case GDK_Page_Down: + gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); + return TRUE; + break; } } @@ -2021,6 +2058,7 @@ /* If we have a valid key for the conversation display, then exit */ if ((event->state & GDK_CONTROL_MASK) || + (event->keyval == GDK_F6) || (event->keyval == GDK_F10) || (event->keyval == GDK_Shift_L) || (event->keyval == GDK_Shift_R) || @@ -2031,11 +2069,17 @@ (event->keyval == GDK_Down) || (event->keyval == GDK_Left) || (event->keyval == GDK_Right) || + (event->keyval == GDK_Page_Up) || + (event->keyval == GDK_Page_Down) || (event->keyval == GDK_Home) || (event->keyval == GDK_End) || (event->keyval == GDK_Tab) || (event->keyval == GDK_ISO_Left_Tab)) - return FALSE; + { + if (event->type == GDK_KEY_PRESS) + return conv_keypress_common(gtkconv, event); + return FALSE; + } if (event->type == GDK_KEY_RELEASE) gtk_widget_grab_focus(gtkconv->entry); @@ -2677,31 +2721,6 @@ return TRUE; } -static void -menu_buddyicon_cb(gpointer data, guint action, GtkWidget *widget) -{ - PidginWindow *win = data; - PurpleConversation *conv; - PidginConversation *gtkconv; - gboolean active; - - conv = pidgin_conv_window_get_active_conversation(win); - - if (!conv) - return; - - g_return_if_fail(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM); - - gtkconv = PIDGIN_CONVERSATION(conv); - - active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); - gtkconv->u.im->show_icon = active; - if (active) - pidgin_conv_update_buddy_icon(conv); - else - remove_icon(NULL, gtkconv); -} - /************************************************************************** * End of the bunch of buddy icon functions **************************************************************************/ @@ -2768,6 +2787,18 @@ pidgin_conv_present_conversation(conv); } +static void +unseen_all_conv_menu_cb(GtkMenuItem *item, GList *list) +{ + g_return_if_fail(list != NULL); + /* Do not free the list from here. It will be freed from the + * 'destroy' callback on the menuitem. */ + while (list) { + pidgin_conv_present_conversation(list->data); + list = list->next; + } +} + guint pidgin_conversations_fill_menu(GtkWidget *menu, GList *convs) { @@ -2799,6 +2830,19 @@ ret++; } + if (convs->next) { + /* There are more than one conversation. Add an option to show all conversations. */ + GtkWidget *item; + GList *list = g_list_copy(convs); + + pidgin_separator(menu); + + item = gtk_menu_item_new_with_label(_("Show All")); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(unseen_all_conv_menu_cb), list); + g_signal_connect_swapped(G_OBJECT(item), "destroy", G_CALLBACK(g_list_free), list); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + return ret; } @@ -2869,7 +2913,6 @@ { N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL }, { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL }, { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL }, - { N_("/Options/Show Buddy _Icon"), NULL, menu_buddyicon_cb, 0, "<CheckItem>", NULL }, { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL }, { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL }, { N_("/Options/Show Ti_mestamps"), "F2", menu_timestamps_cb, 0, "<CheckItem>", NULL }, @@ -2992,8 +3035,12 @@ node = (PurpleBlistNode *)buddy; /* Now add the stuff */ - if (all && buddy) { - pidgin_blist_make_buddy_menu(menu, buddy, TRUE); + if (all) { + if (buddy) + pidgin_blist_make_buddy_menu(menu, buddy, TRUE); + else if (chat) { + /* XXX: */ + } } else if (node) { if (purple_account_is_connected(conv->account)) pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node); @@ -4393,6 +4440,10 @@ g_signal_connect(G_OBJECT(list), "button_press_event", G_CALLBACK(right_click_chat_cb), gtkconv); + g_signal_connect(G_OBJECT(list), "motion-notify-event", + G_CALLBACK(pidgin_userlist_motion_cb), gtkconv); + g_signal_connect(G_OBJECT(list), "leave-notify-event", + G_CALLBACK(pidgin_userlist_motion_cb), gtkconv); g_signal_connect(G_OBJECT(list), "popup-menu", G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); @@ -4437,6 +4488,8 @@ int timeout; PidginConversation *gtkconv; /* This is the Pidgin conversation that triggered the tooltip */ + int userlistx; + int userlisty; } tooltip; static void @@ -4493,6 +4546,72 @@ return FALSE; } +static gboolean +pidgin_userlist_tooltip_timeout(PidginConversation *gtkconv) +{ + PurplePluginProtocolInfo *prpl_info; + PurpleConversation *conv = gtkconv->active_conv; + PidginChatPane *gtkchat; + PurpleConnection *gc; + PurpleBlistNode *node = NULL; + PurpleAccount *account; + GtkTreePath *path; + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeViewColumn *column; + gchar *who; + int x, y; + + gtkchat = gtkconv->u.chat; + account = purple_conversation_get_account(conv); + gc = account->gc; + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), + tooltip.userlistx, tooltip.userlisty, &path, &column, &x, &y); + + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); + + node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); + if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) + pidgin_blist_draw_tooltip(node, gtkconv->infopane); + + g_free(who); + gtk_tree_path_free(path); + + + return FALSE; +} + +static gboolean +pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv) +{ + PurpleConversation *conv; + int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); + + pidgin_blist_tooltip_destroy(); + if (delay == 0) + return FALSE; + + if (tooltip.timeout != 0) + g_source_remove(tooltip.timeout); + + conv = gtkconv->active_conv; + + tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_userlist_tooltip_timeout, gtkconv); + tooltip.gtkconv = gtkconv; + tooltip.userlistx = event->x; + tooltip.userlisty = event->y; + + return FALSE; +} + static GtkWidget * setup_common_pane(PidginConversation *gtkconv) { @@ -6902,7 +7021,8 @@ for (l = purple_get_ims(); l != NULL; l = l->next) { conv = (PurpleConversation *)l->data; gtkconv = PIDGIN_CONVERSATION(conv); - gtkconv->u.im->animate = GPOINTER_TO_INT(value); + if (gtkconv) + gtkconv->u.im->animate = GPOINTER_TO_INT(value); } /* Now either stop or start animation for the active conversation in each window */ @@ -6921,6 +7041,8 @@ for (l = purple_get_conversations(); l != NULL; l = l->next) { PurpleConversation *conv = l->data; + if (!PIDGIN_CONVERSATION(conv)) + continue; if (GPOINTER_TO_INT(value)) gtk_widget_show(PIDGIN_CONVERSATION(conv)->infopane_hbox); else @@ -6939,7 +7061,8 @@ GList *l; for (l = purple_get_conversations(); l != NULL; l = l->next) { PurpleConversation *conv = l->data; - update_tab_icon(conv); + if (PIDGIN_CONVERSATION(conv)) + update_tab_icon(conv); } } @@ -7864,7 +7987,7 @@ infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) { if (e->type == GDK_2BUTTON_PRESS && e->button == 1) { - if (alias_double_click_cb(widget, e, gtkconv)) + if (infopane_entry_activate(gtkconv)) return TRUE; } @@ -8105,10 +8228,11 @@ gtk_window_get_size(GTK_WINDOW(dest_win->window), &win_width, &win_height); - +#ifdef WIN32 /* only override window manager placement on Windows */ gtk_window_move(GTK_WINDOW(dest_win->window), e->x_root - (win_width / 2), e->y_root - (win_height / 2)); +#endif pidgin_conv_window_show(dest_win); } @@ -8321,16 +8445,12 @@ } static gboolean -alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv) +infopane_entry_activate(PidginConversation *gtkconv) { GtkWidget *entry = NULL; PurpleConversation *conv = gtkconv->active_conv; const char *text = NULL; - if (event->button != 1 || event->type != GDK_2BUTTON_PRESS) { - return FALSE; - } - if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { /* There's already an entry for alias. Let's not create another one. */ return FALSE; @@ -8373,7 +8493,15 @@ gtk_widget_hide(gtkconv->infopane); gtk_widget_grab_focus(entry); - return FALSE; + return TRUE; +} + +static gboolean +window_keypress_cb(GtkWidget *widget, GdkEventKey *event, PidginWindow *win) +{ + PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); + + return conv_keypress_common(gtkconv, event); } static void @@ -8571,6 +8699,11 @@ g_signal_connect(G_OBJECT(win->window), "focus_in_event", G_CALLBACK(focus_win_cb), win); + /* Intercept keystrokes from the menu items */ + g_signal_connect(G_OBJECT(win->window), "key_press_event", + G_CALLBACK(window_keypress_cb), win); + + /* Create the notebook. */ win->notebook = gtk_notebook_new();
--- a/pidgin/gtkimhtml.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkimhtml.c Mon Sep 03 21:04:02 2007 +0000 @@ -4890,7 +4890,7 @@ } else if (c == '"') { str = g_string_append(str, """); } else if (c == '\n') { - str = g_string_append(str, "<br>"); + str = g_string_append(str, "<br>\n"); } else { str = g_string_append_unichar(str, c); }
--- a/pidgin/gtkimhtmltoolbar.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Mon Sep 03 21:04:02 2007 +0000 @@ -28,6 +28,7 @@ #include "imgstore.h" #include "notify.h" +#include "prefs.h" #include "request.h" #include "pidginstock.h" #include "util.h" @@ -1021,9 +1022,41 @@ if (menu) gtk_widget_destroy(menu); + purple_prefs_disconnect_by_handle(object); + G_OBJECT_CLASS(parent_class)->finalize (object); } +static void +switch_toolbar_view(GtkWidget *item, GtkIMHtmlToolbar *toolbar) +{ + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", + !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide")); +} + +static gboolean +gtk_imhtmltoolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, GtkIMHtmlToolbar *toolbar) +{ + GtkWidget *menu; + GtkWidget *item; + gboolean wide; + + if (event->button != 3) + return FALSE; + + wide = GTK_WIDGET_VISIBLE(toolbar->bold); + + menu = gtk_menu_new(); + item = gtk_menu_item_new_with_mnemonic(wide ? _("Group Items") : _("Ungroup Items")); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(switch_toolbar_view), toolbar); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_widget_show(item); + + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, pidgin_menu_position_func_helper, + widget, event->button, event->time); + return TRUE; +} + /* Boring GTK+ stuff */ static void gtk_imhtmltoolbar_class_init (GtkIMHtmlToolbarClass *class) { @@ -1033,90 +1066,58 @@ gobject_class = (GObjectClass*) class; parent_class = gtk_type_class(GTK_TYPE_HBOX); gobject_class->finalize = gtk_imhtmltoolbar_finalize; + + purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/toolbar"); + purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", FALSE); } static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar) { + GtkWidget *hbox; GtkWidget *button; - /* Bold */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_BOLD); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_bold), toolbar); - toolbar->bold = button; - - - /* Italic */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_ITALIC); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_italic), toolbar); - toolbar->italic = button; - - /* Underline */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_UNDERLINE); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_underline), toolbar); - toolbar->underline = button; - - - /* Strikethrough */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_STRIKETHROUGH); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_strikethrough), toolbar); - toolbar->strikethrough = button; - - /* Increase font size */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_LARGER); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_big), toolbar); - toolbar->larger_size = button; - - /* Decrease font size */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_small), toolbar); - toolbar->smaller_size = button; + struct { + char *stock; + gpointer callback; + GtkWidget **button; + const char *tooltip; + } buttons[] = { + {GTK_STOCK_BOLD, G_CALLBACK(do_bold), &toolbar->bold, _("Bold")}, + {GTK_STOCK_ITALIC, do_italic, &toolbar->italic, _("Italic")}, + {GTK_STOCK_UNDERLINE, do_underline, &toolbar->underline, _("Underline")}, + {GTK_STOCK_STRIKETHROUGH, do_strikethrough, &toolbar->strikethrough, _("Strikethrough")}, + {"", NULL, NULL, NULL}, + {PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, do_big, &toolbar->larger_size, _("Increase Font Size")}, + {PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, do_small, &toolbar->smaller_size, _("Decrease Font Size")}, + {"", NULL, NULL, NULL}, + {PIDGIN_STOCK_TOOLBAR_FONT_FACE, toggle_font, &toolbar->font, _("Font Face")}, + {PIDGIN_STOCK_TOOLBAR_FGCOLOR, toggle_bg_color, &toolbar->bgcolor, _("Background Color")}, + {PIDGIN_STOCK_TOOLBAR_BGCOLOR, toggle_fg_color, &toolbar->fgcolor, _("Foreground Color")}, + {"", NULL, NULL, NULL}, + {PIDGIN_STOCK_CLEAR, clear_formatting_cb, &toolbar->clear, _("Reset Formatting")}, + {"", NULL, NULL, NULL}, + {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")}, + {NULL, NULL, NULL, NULL} + }; + int iter; - /* Font Face */ - - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FONT_FACE); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_font), toolbar); - toolbar->font = button; - - /* Foreground Color */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FGCOLOR); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_fg_color), toolbar); - toolbar->fgcolor = button; - - /* Background Color */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_BGCOLOR); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_bg_color), toolbar); - toolbar->bgcolor = button; + hbox = gtk_hbox_new(FALSE, 0); - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_LINK); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_link_cb), toolbar); - toolbar->link = button; - - /* Insert IM Image */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_image_cb), toolbar); - toolbar->image = button; + for (iter = 0; buttons[iter].stock; iter++) { + if (buttons[iter].stock[0]) { + button = pidgin_pixbuf_toolbar_button_from_stock(buttons[iter].stock); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(buttons[iter].callback), toolbar); + *(buttons[iter].button) = button; + gtk_tooltips_set_tip(toolbar->tooltips, button, buttons[iter].tooltip, NULL); + } else + button = gtk_vseparator_new(); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + } - /* Insert Smiley */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_smiley_cb), toolbar); - toolbar->smiley = button; - - /* Reset formatting */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(clear_formatting_cb), toolbar); - toolbar->clear = button; + gtk_box_pack_start(GTK_BOX(toolbar), hbox, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(toolbar), "wide-view", hbox); } static void @@ -1140,10 +1141,23 @@ g_object_set(G_OBJECT(widget), "use-markup", TRUE, NULL); } +static void +imhtmltoolbar_view_pref_changed(const char *name, PurplePrefType type, + gconstpointer value, gpointer toolbar) +{ + if (value) { + gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "lean-view")); + gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "wide-view")); + } else { + gtk_widget_hide_all(g_object_get_data(G_OBJECT(toolbar), "wide-view")); + gtk_widget_show_all(g_object_get_data(G_OBJECT(toolbar), "lean-view")); + } +} + static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar) { - GtkWidget *hbox = GTK_WIDGET(toolbar); - GtkWidget *bbox; + GtkWidget *hbox = GTK_WIDGET(toolbar), *event = gtk_event_box_new(); + GtkWidget *bbox, *box = gtk_hbox_new(FALSE, 0); GtkWidget *image; GtkWidget *label; GtkWidget *insert_button; @@ -1177,7 +1191,6 @@ {NULL, NULL, FALSE} }; - toolbar->imhtml = NULL; toolbar->font_dialog = NULL; toolbar->fgcolor_dialog = NULL; @@ -1203,7 +1216,7 @@ gtk_label_set_use_markup(GTK_LABEL(label), TRUE); g_object_set_data(G_OBJECT(hbox), "font_label", label); gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), font_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(box), font_button, FALSE, FALSE, 0); gtk_widget_show_all(font_button); font_menu = gtk_menu_new(); @@ -1232,7 +1245,7 @@ /* Sep */ sep = gtk_vseparator_new(); - gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 0); gtk_widget_show_all(sep); /* Insert */ @@ -1244,7 +1257,7 @@ gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); label = gtk_label_new_with_mnemonic(_("_Insert")); gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), insert_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(box), insert_button, FALSE, FALSE, 0); gtk_widget_show_all(insert_button); insert_menu = gtk_menu_new(); @@ -1277,6 +1290,18 @@ g_signal_connect(G_OBJECT(insert_button), "activate", G_CALLBACK(pidgin_menu_clicked), insert_menu); g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button); toolbar->sml = NULL; + + gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(hbox), "lean-view", box); + + purple_prefs_connect_callback(toolbar, PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", + imhtmltoolbar_view_pref_changed, toolbar); + purple_prefs_trigger_callback(PIDGIN_PREFS_ROOT "/conversations/toolbar/wide"); + + gtk_widget_add_events(event, GDK_BUTTON_PRESS_MASK); + gtk_box_pack_start(GTK_BOX(hbox), event, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(event), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar); + gtk_widget_show(event); } GtkWidget *gtk_imhtmltoolbar_new()
--- a/pidgin/gtkmain.c Mon Sep 03 21:02:52 2007 +0000 +++ b/pidgin/gtkmain.c Mon Sep 03 21:04:02 2007 +0000 @@ -774,21 +774,6 @@ /* TODO: Move pounces loading into purple_pounces_init() */ purple_pounces_load(); - /* HACK BY SEANEGAN: - * We've renamed prpl-oscar to prpl-aim and prpl-icq, accordingly. - * Let's do that change right here... after everything's loaded, but - * before anything has happened - */ - for (accounts = purple_accounts_get_all(); accounts != NULL; accounts = accounts->next) { - PurpleAccount *account = accounts->data; - if (!strcmp(purple_account_get_protocol_id(account), "prpl-oscar")) { - if (isdigit(*purple_account_get_username(account))) - purple_account_set_protocol_id(account, "prpl-icq"); - else - purple_account_set_protocol_id(account, "prpl-aim"); - } - } - ui_main(); #ifdef USE_SM