soc.2010.icq-tlc: 850102c2: Display the protocol icon for the author...

ivan.komarov at soc.pidgin.im ivan.komarov at soc.pidgin.im
Wed May 26 16:40:36 EDT 2010


-----------------------------------------------------------------
Revision: 850102c2d3b83ffb1c63bf0bb5ee384cd2fd7ec8
Ancestor: 12ba055ceeb14a00597ed9c99982d8cb3ab6950f
Author: ivan.komarov at soc.pidgin.im
Date: 2010-05-26T20:35:02
Branch: im.pidgin.soc.2010.icq-tlc
URL: http://d.pidgin.im/viewmtn/revision/info/850102c2d3b83ffb1c63bf0bb5ee384cd2fd7ec8

Modified files:
        pidgin/gtkaccount.c pidgin/gtkutils.c pidgin/gtkutils.h
        pidgin/minidialog.c pidgin/minidialog.h

ChangeLog: 

Display the protocol icon for the authorization request dialog
instead of a question mark. Refs #5038.

The dialog is still pretty unusable, though. There should be either
a link to the user profile or a button to start a conversation (or maybe both),
but these seemingly trivial things were surprisingly tough to implement.
I think I'll return to this ticket at the end of the summer.

-------------- next part --------------
============================================================
--- pidgin/gtkaccount.c	ed07c413bd0c6898814f2599871a3319dbf4755a
+++ pidgin/gtkaccount.c	67355ddf08aa04ea8bc82450a9b0276a03937981
@@ -2418,35 +2418,38 @@ pidgin_accounts_request_add(PurpleAccoun
 	g_free(buffer);
 }
 
-struct auth_and_add {
+struct auth_request
+{
 	PurpleAccountRequestAuthorizationCb auth_cb;
 	PurpleAccountRequestAuthorizationCb deny_cb;
 	void *data;
 	char *username;
 	char *alias;
 	PurpleAccount *account;
+	gboolean add_buddy_after_auth;
 };
 
 static void
-free_auth_and_add(struct auth_and_add *aa)
+free_auth_request(struct auth_request *ar)
 {
-	g_free(aa->username);
-	g_free(aa->alias);
-	g_free(aa);
+	g_free(ar->username);
+	g_free(ar->alias);
+	g_free(ar);
 }
 
 static void
-authorize_and_add_cb(struct auth_and_add *aa)
+authorize_and_add_cb(struct auth_request *ar)
 {
-	aa->auth_cb(aa->data);
-	purple_blist_request_add_buddy(aa->account, aa->username,
-	 	                    NULL, aa->alias);
+	ar->auth_cb(ar->data);
+	if (ar->add_buddy_after_auth) {
+		purple_blist_request_add_buddy(ar->account, ar->username, NULL, ar->alias);
+	}
 }
 
 static void
-deny_no_add_cb(struct auth_and_add *aa)
+deny_no_add_cb(struct auth_request *ar)
 {
-	aa->deny_cb(aa->data);
+	ar->deny_cb(ar->data);
 }
 
 static void *
@@ -2463,49 +2466,48 @@ pidgin_accounts_request_authorization(Pu
 	char *buffer;
 	PurpleConnection *gc;
 	GtkWidget *alert;
+	GdkPixbuf *prpl_icon;
+	struct auth_request *aa;
 
 	gc = purple_account_get_connection(account);
 	if (message != NULL && *message == '\0')
 		message = NULL;
 
-	buffer = g_strdup_printf(_("%s%s%s%s wants to add %s to his or her buddy list%s%s"),
+	buffer = g_strdup_printf(_("%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"),
 				remote_user,
-	 	                (alias != NULL ? " ("  : ""),
-		                (alias != NULL ? alias : ""),
-		                (alias != NULL ? ")"   : ""),
-		                (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  : ""));
+				(alias != NULL ? " ("  : ""),
+				(alias != NULL ? alias : ""),
+				(alias != NULL ? ")"   : ""),
+				(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  : ""));
 
 
-	if (!on_list) {
-		struct auth_and_add *aa = g_new0(struct auth_and_add, 1);
-		aa->auth_cb = auth_cb;
-		aa->deny_cb = deny_cb;
-		aa->data = user_data;
-		aa->username = g_strdup(remote_user);
-		aa->alias = g_strdup(alias);
-		aa->account = account;
-		alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION,
-						  _("Authorize buddy?"), buffer, aa,
-						  _("Authorize"), authorize_and_add_cb,
-						  _("Deny"), deny_no_add_cb,
-						  NULL);
-		g_signal_connect_swapped(G_OBJECT(alert), "destroy", G_CALLBACK(free_auth_and_add), aa);
-	} else {
-		alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION,
-						  _("Authorize buddy?"), buffer, user_data,
-						  _("Authorize"), auth_cb,
-						  _("Deny"), deny_cb,
-						  NULL);
-	}
+	prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
+	
+	aa = g_new0(struct auth_request, 1);
+	aa->auth_cb = auth_cb;
+	aa->deny_cb = deny_cb;
+	aa->data = user_data;
+	aa->username = g_strdup(remote_user);
+	aa->alias = g_strdup(alias);
+	aa->account = account;
+	aa->add_buddy_after_auth = !on_list;
+	
+	alert = pidgin_make_mini_dialog_with_custom_icon(
+		gc, prpl_icon,
+		_("Authorize buddy?"), buffer, aa,
+		_("Authorize"), authorize_and_add_cb,
+		_("Deny"), deny_no_add_cb,
+		NULL);
+	
+	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);
-	g_signal_connect(G_OBJECT(alert), "destroy",
-		G_CALLBACK(purple_account_request_close), NULL);
 
 	g_free(buffer);
 
============================================================
--- pidgin/gtkutils.c	b6dcc467269dfd69571545b6c2e9ae87cc134608
+++ pidgin/gtkutils.c	ec65d12f8cb85eafe2ca08bb2faee2b4a41e7927
@@ -2611,18 +2611,11 @@ old_mini_dialog_destroy_cb(GtkWidget *di
 	}
 }
 
-GtkWidget *
-pidgin_make_mini_dialog(PurpleConnection *gc,
-                        const char *icon_name,
-                        const char *primary,
-                        const char *secondary,
-                        void *user_data,
-                        ...)
+static void
+mini_dialog_init(PidginMiniDialog *mini_dialog, PurpleConnection *gc, void *user_data, va_list args)
 {
-	PidginMiniDialog *mini_dialog;
 	const char *button_text;
 	GList *cb_datas = NULL;
-	va_list args;
 	static gboolean first_call = TRUE;
 
 	if (first_call) {
@@ -2632,12 +2625,10 @@ pidgin_make_mini_dialog(PurpleConnection
 		                      PURPLE_CALLBACK(connection_signed_off_cb), NULL);
 	}
 
-	mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name);
 	g_object_set_data(G_OBJECT(mini_dialog), "gc" ,gc);
 	g_signal_connect(G_OBJECT(mini_dialog), "destroy",
 		G_CALLBACK(alert_killed_cb), NULL);
 
-	va_start(args, user_data);
 	while ((button_text = va_arg(args, char*))) {
 		struct _old_button_clicked_cb_data *data = NULL;
 		PidginMiniDialogCallback wrapper_cb = NULL;
@@ -2654,14 +2645,42 @@ pidgin_make_mini_dialog(PurpleConnection
 			wrapper_cb, data);
 		cb_datas = g_list_append(cb_datas, data);
 	}
-	va_end(args);
 
 	g_signal_connect(G_OBJECT(mini_dialog), "destroy",
 		G_CALLBACK(old_mini_dialog_destroy_cb), cb_datas);
+}
 
+#define INIT_AND_RETURN_MINI_DIALOG(mini_dialog) \
+	va_list args; \
+	va_start(args, user_data); \
+	mini_dialog_init(mini_dialog, gc, user_data, args); \
+	va_end(args); \
 	return GTK_WIDGET(mini_dialog);
+
+GtkWidget *
+pidgin_make_mini_dialog(PurpleConnection *gc,
+                        const char *icon_name,
+                        const char *primary,
+                        const char *secondary,
+                        void *user_data,
+                        ...)
+{
+	PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name);
+	INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
 }
 
+GtkWidget *
+pidgin_make_mini_dialog_with_custom_icon(PurpleConnection *gc,
+					GdkPixbuf *custom_icon,
+					const char *primary,
+					const char *secondary,
+					void *user_data,
+					...)
+{
+	PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new_with_custom_icon(primary, secondary, custom_icon);
+	INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
+}
+
 /*
  * "This is so dead sexy."
  * "Two thumbs up."
============================================================
--- pidgin/gtkutils.h	6edab51a638a13f1838a4ec6b6adf63754993191
+++ pidgin/gtkutils.h	9a30d977c1ea9349b66bad57200737cf17299964
@@ -715,6 +715,17 @@ GtkWidget *pidgin_make_mini_dialog(Purpl
 	void *user_data, ...) G_GNUC_NULL_TERMINATED;
 
 /**
+ * Does exactly what pidgin_make_mini_dialog() does, except you can specify
+ * a custom icon for the dialog.
+ */
+GtkWidget *pidgin_make_mini_dialog_with_custom_icon(PurpleConnection *gc,
+	GdkPixbuf *custom_icon,
+	const char *primary,
+	const char *secondary,
+	void *user_data,
+	...) G_GNUC_NULL_TERMINATED;
+
+/**
  * This is a callback function to be used for Ctrl+F searching in treeviews.
  * Sample Use:
  * 		gtk_tree_view_set_search_equal_func(treeview,
============================================================
--- pidgin/minidialog.c	d542d144e8cc4522e84b07391b394f4110cfbe21
+++ pidgin/minidialog.c	0ff3f39351172aebcd5504f3915242777b6d05cd
@@ -75,6 +75,7 @@ enum
 	PROP_TITLE = 1,
 	PROP_DESCRIPTION,
 	PROP_ICON_NAME,
+	PROP_CUSTOM_ICON,
 
 	LAST_PROPERTY
 } HazeConnectionProperties;
@@ -93,17 +94,32 @@ typedef struct _PidginMiniDialogPrivate
 #define PIDGIN_MINI_DIALOG_GET_PRIVATE(dialog) \
 	((PidginMiniDialogPrivate *) ((dialog)->priv))
 
+static PidginMiniDialog *
+mini_dialog_new(const gchar *title, const gchar *description)
+{
+	return g_object_new(PIDGIN_TYPE_MINI_DIALOG,
+		"title", title,
+		"description", description,
+		NULL);
+}
+
 PidginMiniDialog *
 pidgin_mini_dialog_new(const gchar *title,
                        const gchar *description,
                        const gchar *icon_name)
 {
-	PidginMiniDialog *mini_dialog = g_object_new(PIDGIN_TYPE_MINI_DIALOG,
-		"title", title,
-		"description", description,
-		"icon-name", icon_name,
-		NULL);
+	PidginMiniDialog *mini_dialog = mini_dialog_new(title, description);
+	pidgin_mini_dialog_set_icon_name(mini_dialog, icon_name);
+	return mini_dialog;
+}
 
+PidginMiniDialog *
+pidgin_mini_dialog_new_with_custom_icon(const gchar *title,
+					const gchar *description,
+					GdkPixbuf *custom_icon)
+{
+	PidginMiniDialog *mini_dialog = mini_dialog_new(title, description);
+	pidgin_mini_dialog_set_custom_icon(mini_dialog, custom_icon);
 	return mini_dialog;
 }
 
@@ -125,9 +141,15 @@ pidgin_mini_dialog_set_icon_name(PidginM
 pidgin_mini_dialog_set_icon_name(PidginMiniDialog *mini_dialog,
                                  const char *icon_name)
 {
-	g_object_set(G_OBJECT(mini_dialog), "icon_name", icon_name, NULL);
+	g_object_set(G_OBJECT(mini_dialog), "icon-name", icon_name, NULL);
 }
 
+void
+pidgin_mini_dialog_set_custom_icon(PidginMiniDialog *mini_dialog, GdkPixbuf *custom_icon)
+{
+	g_object_set(G_OBJECT(mini_dialog), "custom-icon", custom_icon, NULL);
+}
+
 struct _mini_dialog_button_clicked_cb_data
 {
 	PidginMiniDialog *mini_dialog;
@@ -233,6 +255,9 @@ pidgin_mini_dialog_get_property(GObject 
 			g_value_set_string(value, icon_name);
 			break;
 		}
+		case PROP_CUSTOM_ICON:
+			g_value_set_object(value, gtk_image_get_pixbuf(priv->icon));
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 	}
@@ -305,6 +330,8 @@ pidgin_mini_dialog_set_property(GObject 
 			gtk_image_set_from_stock(priv->icon, g_value_get_string(value),
 				gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
 			break;
+		case PROP_CUSTOM_ICON:
+			gtk_image_set_from_pixbuf(priv->icon, g_value_get_object(value));
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 	}
@@ -355,6 +382,13 @@ pidgin_mini_dialog_class_init(PidginMini
 		G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
 		G_PARAM_READWRITE);
 	g_object_class_install_property (object_class, PROP_ICON_NAME, param_spec);
+	
+	param_spec = g_param_spec_object("custom-icon", "custom-icon",
+		"Pixbuf to use as the dialog's icon",
+		GDK_TYPE_PIXBUF,
+		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);
 }
 
 /* 16 is the width of the icon, due to PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL */
============================================================
--- pidgin/minidialog.h	2e2487f114664eff6a89dd7a7bf0b19d0d868527
+++ pidgin/minidialog.h	0a32b4e69f9f0210bdfd6849a2cc8c2c8b17329a
@@ -73,6 +73,8 @@ G_BEGIN_DECLS
  *   <dd>The Gtk stock id of an icon for the dialog, or @c NULL for no icon.
  *       @see pidginstock.h
  *   </dd>
+ *   <dt><tt>"custom-icon"</tt> (<tt>GdkPixbuf *</tt>)</dt>
+ *   <dd>The custom icon to use instead of a stock one (overrides the "icon-name" property).</dd>
  * </dl>
  */
 typedef struct {
@@ -108,13 +110,20 @@ GType pidgin_mini_dialog_get_type (void)
 /** Get the GType of #PidginMiniDialog. */
 GType pidgin_mini_dialog_get_type (void);
 
-/** Creates a new #PidginMiniDialog.  This is a shortcut for creating the dialog
+/** Creates a new #PidginMiniDialog with a stock icon. This is a shortcut for creating the dialog
  *  with @c g_object_new() then setting each property yourself.
  *  @return a new #PidginMiniDialog.
  */
 PidginMiniDialog *pidgin_mini_dialog_new(const gchar *title,
 	const gchar *description, const gchar *icon_name);
 
+/** Creates a new #PidginMiniDialog with a custom icon. This is a shortcut for creating the dialog
+ *  with @c g_object_new() then setting each property yourself.
+ *  @return a new #PidginMiniDialog.
+ */
+PidginMiniDialog *pidgin_mini_dialog_new_with_custom_icon(const gchar *title,
+	const gchar *description, GdkPixbuf *custom_icon);
+
 /** Shortcut for setting a mini-dialog's title via GObject properties.
  *  @param mini_dialog a mini-dialog
  *  @param title       the new title for @a mini_dialog
@@ -137,6 +146,13 @@ void pidgin_mini_dialog_set_icon_name(Pi
 void pidgin_mini_dialog_set_icon_name(PidginMiniDialog *mini_dialog,
 	const char *icon_name);
 
+/** Shortcut for setting a mini-dialog's custom icon via GObject properties.
+ *  @param mini_dialog a mini-dialog
+ *  @param icon_name   the pixbuf to use as a custom icon
+ */
+void pidgin_mini_dialog_set_custom_icon(PidginMiniDialog *mini_dialog,
+	GdkPixbuf *custom_icon);
+
 /** Adds a new button to a mini-dialog, and attaches the supplied callback to
  *  its <tt>clicked</tt> signal.  After a button is clicked, the dialog is
  *  destroyed.


More information about the Commits mailing list