Mercurial > pidgin
changeset 31498:9e9abd65b840
propagate from branch 'im.pidgin.pidgin' (head ece03c16966f58e1db43e5c20fe35a6707b468d2)
to branch 'im.pidgin.pidgin.mxit' (head 524638c79d3d0540b9343247091acf620ef2c733)
author | andrew.victor@mxit.com |
---|---|
date | Thu, 31 Mar 2011 19:32:34 +0000 |
parents | acd92b7d8511 (current diff) a9e077fb65e9 (diff) |
children | a769e6da0a8e |
files | |
diffstat | 9 files changed, 201 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog.API Tue Mar 29 14:43:15 2011 +0000 +++ b/ChangeLog.API Thu Mar 31 19:32:34 2011 +0000 @@ -5,6 +5,7 @@ Added: * account-authorization-requested-with-message signal (Stefan Ott) (#8690) + * cleared-message-history signal (conversation signals) * purple_account_add_buddy_with_invite * purple_account_add_buddies_with_invite * purple_notify_user_info_add_pair_plaintext
--- a/doc/conversation-signals.dox Tue Mar 29 14:43:15 2011 +0000 +++ b/doc/conversation-signals.dox Thu Mar 31 19:32:34 2011 +0000 @@ -32,6 +32,7 @@ @signal chat-join-failed @signal chat-left @signal chat-topic-changed + @signal cleared-message-history @signal conversation-extended-menu @signal sent-attention @signal got-attention @@ -479,6 +480,16 @@ @since 2.1.0 @endsignaldef + @signaldef cleared-message-history + @signalproto +void (*cleared_message_history)(PurpleConversation *conv); + @endsignalproto + @signaldesc + Emitted when the conversation history is cleared. + @param conv The conversation. + @since 2.8.0 + @endsignaldef + @signaldef sent-attention @signalproto void (*got_attention)(PurpleAccount *account, const char *who,
--- a/finch/gntconv.c Tue Mar 29 14:43:15 2011 +0000 +++ b/finch/gntconv.c Thu Mar 31 19:32:34 2011 +0000 @@ -396,10 +396,18 @@ } static void +cleared_message_history_cb(PurpleConversation *conv, gpointer data) +{ + FinchConv *ggc = FINCH_GET_DATA(conv); + if (ggc) + gnt_text_view_clear(GNT_TEXT_VIEW(ggc->tv)); +} + +static void clear_scrollback_cb(GntMenuItem *item, gpointer ggconv) { FinchConv *ggc = ggconv; - gnt_text_view_clear(GNT_TEXT_VIEW(ggc->tv)); + purple_conversation_clear_message_history(ggc->active_conv); } static void @@ -1264,8 +1272,6 @@ clear_command_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data) { - FinchConv *ggconv = FINCH_GET_DATA(conv); - gnt_text_view_clear(GNT_TEXT_VIEW(ggconv->tv)); purple_conversation_clear_message_history(conv); return PURPLE_CMD_RET_OK; } @@ -1459,6 +1465,8 @@ PURPLE_CALLBACK(update_buddy_typing), NULL); purple_signal_connect(purple_conversations_get_handle(), "chat-left", finch_conv_get_handle(), PURPLE_CALLBACK(chat_left_cb), NULL); + purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history", finch_conv_get_handle(), + PURPLE_CALLBACK(cleared_message_history_cb), NULL); purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", finch_conv_get_handle(), PURPLE_CALLBACK(buddy_signed_on_off), NULL); purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", finch_conv_get_handle(),
--- a/libpurple/conversation.c Tue Mar 29 14:43:15 2011 +0000 +++ b/libpurple/conversation.c Thu Mar 31 19:32:34 2011 +0000 @@ -575,6 +575,7 @@ if (ops != NULL && ops->destroy_conversation != NULL) ops->destroy_conversation(conv); + conv->ui_data = NULL; purple_conversation_close_logs(conv); @@ -2270,6 +2271,9 @@ GList *list = conv->message_history; message_history_free(list); conv->message_history = NULL; + + purple_signal_emit(purple_conversations_get_handle(), + "cleared-message-history", conv); } GList *purple_conversation_get_message_history(PurpleConversation *conv) @@ -2626,6 +2630,11 @@ purple_value_new(PURPLE_TYPE_STRING), purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_register(handle, "cleared-message-history", + purple_marshal_VOID__POINTER, NULL, 1, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_CONVERSATION)); + purple_signal_register(handle, "conversation-extended-menu", purple_marshal_VOID__POINTER_POINTER, NULL, 2, purple_value_new(PURPLE_TYPE_SUBTYPE,
--- a/pidgin/gtkaccount.c Tue Mar 29 14:43:15 2011 +0000 +++ b/pidgin/gtkaccount.c Thu Mar 31 19:32:34 2011 +0000 @@ -46,6 +46,7 @@ #include "gtkutils.h" #include "gtkstatusbox.h" #include "pidginstock.h" +#include "minidialog.h" enum { @@ -2501,6 +2502,28 @@ ar->deny_cb(ar->data); } +static gboolean +get_user_info_cb(GtkWidget *label, + const gchar *uri, + gpointer data) +{ + struct auth_request *ar = data; + if (!strcmp(uri, "viewinfo")) { + pidgin_retrieve_user_info(purple_account_get_connection(ar->account), ar->username); + return TRUE; + } + return FALSE; +} + +static void +send_im_cb(PidginMiniDialog *mini_dialog, + GtkButton *button, + gpointer data) +{ + struct auth_request *ar = data; + pidgin_dialogs_im_with_user(ar->account, ar->username); +} + static void * pidgin_accounts_request_authorization(PurpleAccount *account, const char *remote_user, @@ -2515,27 +2538,47 @@ char *buffer; PurpleConnection *gc; GtkWidget *alert; + PidginMiniDialog *dialog; GdkPixbuf *prpl_icon; struct auth_request *aa; + const char *our_name; gboolean have_valid_alias = alias && *alias; gc = purple_account_get_connection(account); if (message != NULL && *message == '\0') message = NULL; - buffer = g_strdup_printf(_("%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"), - remote_user, - (have_valid_alias ? " (" : ""), - (have_valid_alias ? alias : ""), - (have_valid_alias ? ")" : ""), - (id != NULL - ? id - : (purple_connection_get_display_name(gc) != NULL - ? purple_connection_get_display_name(gc) - : purple_account_get_username(account))), - (message != NULL ? ": " : "."), - (message != NULL ? message : "")); - + our_name = (id != NULL) ? id : + (purple_connection_get_display_name(gc) != NULL) ? purple_connection_get_display_name(gc) : + purple_account_get_username(account); + + if (pidgin_mini_dialog_links_supported()) { + char *escaped_remote_user = g_markup_escape_text(remote_user, -1); + char *escaped_alias = alias != NULL ? g_markup_escape_text(alias, -1) : g_strdup(""); + char *escaped_our_name = g_markup_escape_text(our_name, -1); + char *escaped_message = message != NULL ? g_markup_escape_text(message, -1) : g_strdup(""); + buffer = g_strdup_printf(_("<a href=\"viewinfo\">%s</a>%s%s%s wants to add you (%s) to his or her buddy list%s%s"), + escaped_remote_user, + (have_valid_alias ? " (" : ""), + escaped_alias, + (have_valid_alias ? ")" : ""), + escaped_our_name, + (have_valid_alias ? ": " : "."), + escaped_message); + g_free(escaped_remote_user); + g_free(escaped_alias); + g_free(escaped_our_name); + g_free(escaped_message); + } else { + buffer = g_strdup_printf(_("%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"), + remote_user, + (have_valid_alias ? " (" : ""), + (have_valid_alias ? alias : ""), + (have_valid_alias ? ")" : ""), + our_name, + (message != NULL ? ": " : "."), + (message != NULL ? message : "")); + } prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); @@ -2550,11 +2593,19 @@ alert = pidgin_make_mini_dialog_with_custom_icon( gc, prpl_icon, - _("Authorize buddy?"), buffer, aa, + _("Authorize buddy?"), NULL, aa, _("Authorize"), authorize_and_add_cb, _("Deny"), deny_no_add_cb, NULL); + dialog = PIDGIN_MINI_DIALOG(alert); + if (pidgin_mini_dialog_links_supported()) { + pidgin_mini_dialog_enable_description_markup(dialog); + pidgin_mini_dialog_set_link_callback(dialog, G_CALLBACK(get_user_info_cb), aa); + } + pidgin_mini_dialog_set_description(dialog, buffer); + pidgin_mini_dialog_add_non_closing_button(dialog, _("Send Instant Message"), send_im_cb, aa); + g_signal_connect_swapped(G_OBJECT(alert), "destroy", G_CALLBACK(free_auth_request), aa); g_signal_connect(G_OBJECT(alert), "destroy", G_CALLBACK(purple_account_request_close), NULL); pidgin_blist_add_alert(alert);
--- a/pidgin/gtkblist.c Tue Mar 29 14:43:15 2011 +0000 +++ b/pidgin/gtkblist.c Thu Mar 31 19:32:34 2011 +0000 @@ -5134,7 +5134,7 @@ account); if(err->type == PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT) - pidgin_mini_dialog_add_button(PIDGIN_MINI_DIALOG(mini_dialog), + pidgin_mini_dialog_add_non_closing_button(PIDGIN_MINI_DIALOG(mini_dialog), _("SSL FAQs"), ssl_faq_clicked_cb, NULL); g_signal_connect_after(mini_dialog, "destroy",
--- a/pidgin/gtkconv.c Tue Mar 29 14:43:15 2011 +0000 +++ b/pidgin/gtkconv.c Thu Mar 31 19:32:34 2011 +0000 @@ -373,23 +373,21 @@ return PURPLE_CMD_RET_OK; } -static void clear_conversation_scrollback(PurpleConversation *conv) +static void clear_conversation_scrollback_cb(PurpleConversation *conv, + void *data) { PidginConversation *gtkconv = NULL; - GList *iter; gtkconv = PIDGIN_CONVERSATION(conv); - - gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); - for (iter = gtkconv->convs; iter; iter = iter->next) - purple_conversation_clear_message_history(iter->data); + if (gtkconv) + gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); } static PurpleCmdRet clear_command_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data) { - clear_conversation_scrollback(conv); + purple_conversation_clear_message_history(conv); return PURPLE_CMD_RET_OK; } @@ -397,7 +395,7 @@ clearall_command_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data) { - purple_conversation_foreach(clear_conversation_scrollback); + purple_conversation_foreach(purple_conversation_clear_message_history); return PURPLE_CMD_RET_OK; } @@ -1113,7 +1111,7 @@ PurpleConversation *conv; conv = pidgin_conv_window_get_active_conversation(win); - clear_conversation_scrollback(conv); + purple_conversation_clear_message_history(conv); } static void @@ -8042,6 +8040,8 @@ purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", handle, G_CALLBACK(received_im_msg_cb), NULL); + purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history", + handle, G_CALLBACK(clear_conversation_scrollback_cb), NULL); purple_conversations_set_ui_ops(&conversation_ui_ops);
--- a/pidgin/minidialog.c Tue Mar 29 14:43:15 2011 +0000 +++ b/pidgin/minidialog.c Thu Mar 31 19:32:34 2011 +0000 @@ -76,6 +76,7 @@ PROP_DESCRIPTION, PROP_ICON_NAME, PROP_CUSTOM_ICON, + PROP_ENABLE_DESCRIPTION_MARKUP, LAST_PROPERTY } HazeConnectionProperties; @@ -87,6 +88,7 @@ GtkLabel *title; GtkLabel *desc; GtkBox *buttons; + gboolean enable_description_markup; guint idle_destroy_cb_id; } PidginMiniDialogPrivate; @@ -138,6 +140,27 @@ } void +pidgin_mini_dialog_enable_description_markup(PidginMiniDialog *mini_dialog) +{ + g_object_set(G_OBJECT(mini_dialog), "enable-description-markup", TRUE, NULL); +} + +gboolean +pidgin_mini_dialog_links_supported() +{ +#if GTK_CHECK_VERSION(2,18,0) + return TRUE; +#else + return FALSE; +#endif +} + +void pidgin_mini_dialog_set_link_callback(PidginMiniDialog *mini_dialog, GCallback cb, gpointer user_data) +{ + g_signal_connect(PIDGIN_MINI_DIALOG_GET_PRIVATE(mini_dialog)->desc, "activate-link", cb, user_data); +} + +void pidgin_mini_dialog_set_icon_name(PidginMiniDialog *mini_dialog, const char *icon_name) { @@ -155,6 +178,7 @@ PidginMiniDialog *mini_dialog; PidginMiniDialogCallback callback; gpointer user_data; + gboolean close_dialog_after_click; }; guint @@ -178,12 +202,14 @@ PidginMiniDialogPrivate *priv = PIDGIN_MINI_DIALOG_GET_PRIVATE(data->mini_dialog); - /* Set up the destruction callback before calling the clicked callback, - * so that if the mini-dialog gets destroyed during the clicked callback - * the idle_destroy_cb is correctly removed by _finalize. - */ - priv->idle_destroy_cb_id = - g_idle_add((GSourceFunc) idle_destroy_cb, data->mini_dialog); + if (data->close_dialog_after_click) { + /* Set up the destruction callback before calling the clicked callback, + * so that if the mini-dialog gets destroyed during the clicked callback + * the idle_destroy_cb is correctly removed by _finalize. + */ + priv->idle_destroy_cb_id = + g_idle_add((GSourceFunc) idle_destroy_cb, data->mini_dialog); + } if (data->callback != NULL) data->callback(data->mini_dialog, button, data->user_data); @@ -198,11 +224,12 @@ g_free(data); } -void -pidgin_mini_dialog_add_button(PidginMiniDialog *self, - const char *text, - PidginMiniDialogCallback clicked_cb, - gpointer user_data) +static void +mini_dialog_add_button(PidginMiniDialog *self, + const char *text, + PidginMiniDialogCallback clicked_cb, + gpointer user_data, + gboolean close_dialog_after_click) { PidginMiniDialogPrivate *priv = PIDGIN_MINI_DIALOG_GET_PRIVATE(self); struct _mini_dialog_button_clicked_cb_data *callback_data @@ -218,6 +245,7 @@ callback_data->mini_dialog = self; callback_data->callback = clicked_cb; callback_data->user_data = user_data; + callback_data->close_dialog_after_click = close_dialog_after_click; g_signal_connect(G_OBJECT(button), "clicked", (GCallback) mini_dialog_button_clicked_cb, callback_data); g_signal_connect(G_OBJECT(button), "destroy", @@ -231,6 +259,24 @@ gtk_widget_show_all(GTK_WIDGET(button)); } +void +pidgin_mini_dialog_add_button(PidginMiniDialog *self, + const char *text, + PidginMiniDialogCallback clicked_cb, + gpointer user_data) +{ + mini_dialog_add_button(self, text, clicked_cb, user_data, TRUE); +} + +void +pidgin_mini_dialog_add_non_closing_button(PidginMiniDialog *self, + const char *text, + PidginMiniDialogCallback clicked_cb, + gpointer user_data) +{ + mini_dialog_add_button(self, text, clicked_cb, user_data, FALSE); +} + static void pidgin_mini_dialog_get_property(GObject *object, guint property_id, @@ -258,6 +304,9 @@ case PROP_CUSTOM_ICON: g_value_set_object(value, gtk_image_get_pixbuf(priv->icon)); break; + case PROP_ENABLE_DESCRIPTION_MARKUP: + g_value_set_boolean(value, priv->enable_description_markup); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -287,7 +336,7 @@ PidginMiniDialogPrivate *priv = PIDGIN_MINI_DIALOG_GET_PRIVATE(self); if(description) { - char *desc_esc = g_markup_escape_text(description, -1); + char *desc_esc = priv->enable_description_markup ? g_strdup(description) : g_markup_escape_text(description, -1); char *desc_markup = g_strdup_printf( "<span size=\"smaller\">%s</span>", desc_esc); @@ -333,6 +382,9 @@ case PROP_CUSTOM_ICON: gtk_image_set_from_pixbuf(priv->icon, g_value_get_object(value)); break; + case PROP_ENABLE_DESCRIPTION_MARKUP: + priv->enable_description_markup = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -390,6 +442,12 @@ G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_CUSTOM_ICON, param_spec); + + param_spec = g_param_spec_boolean("enable-description-markup", "enable-description-markup", + "Use GMarkup in the description text", FALSE, + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_ENABLE_DESCRIPTION_MARKUP, param_spec); } /* 16 is the width of the icon, due to PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL */
--- a/pidgin/minidialog.h Tue Mar 29 14:43:15 2011 +0000 +++ b/pidgin/minidialog.h Thu Mar 31 19:32:34 2011 +0000 @@ -139,6 +139,23 @@ void pidgin_mini_dialog_set_description(PidginMiniDialog *mini_dialog, const char *description); +/** Enable GMarkup elements in the mini-dialog's description. + * @param mini_dialog a mini-dialog + */ +void pidgin_mini_dialog_enable_description_markup(PidginMiniDialog *mini_dialog); + +/** Mini-dialogs support hyperlinks in their description + * (you should first call pidgin_mini_dialog_enable_description_markup() on a given + * dialog to enable them). */ +gboolean pidgin_mini_dialog_links_supported(void); + +/** Sets a callback which gets invoked when a hyperlink in the dialog's description is clicked on. + * @param mini_dialog a mini-dialog + * @param cb the callback to invoke + * @param user_data the user data to pass to the callback + */ +void pidgin_mini_dialog_set_link_callback(PidginMiniDialog *mini_dialog, GCallback cb, gpointer user_data); + /** Shortcut for setting a mini-dialog's icon via GObject properties. * @param mini_dialog a mini-dialog * @param icon_name the Gtk stock ID of an icon, or @c NULL for no icon. @@ -166,6 +183,13 @@ const char *text, PidginMiniDialogCallback clicked_cb, gpointer user_data); +/** Equivalent to pidgin_mini_dialog_add_button(), the only difference + * is that the mini-dialog won't be closed after the button is clicked. + */ +void pidgin_mini_dialog_add_non_closing_button(PidginMiniDialog *mini_dialog, + const char *text, PidginMiniDialogCallback clicked_cb, + gpointer user_data); + /** Gets the number of widgets packed into PidginMiniDialog.contents. * @param mini_dialog a mini-dialog * @return the number of widgets in @a mini_dialog->contents.