changeset 29790:d0588e403877

Show thumbnail in ft request dialog New function to create an action request with a PRPL-supplied icon. Perhaps all macros in request.h should be augmented to supply versions for _with_icon As of now, there is only one, needed for file transfers...
author Marcus Lundblad <ml@update.uu.se>
date Sat, 04 Jul 2009 21:45:19 +0000
parents 4beb825ff4bc
children 8781cfb550bb
files libpurple/ft.c libpurple/request.c libpurple/request.h pidgin/gtkrequest.c
diffstat 4 files changed, 150 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/ft.c	Sat Jul 04 07:18:19 2009 +0000
+++ b/libpurple/ft.c	Sat Jul 04 21:45:19 2009 +0000
@@ -361,13 +361,20 @@
 			serv_got_im(purple_account_get_connection(xfer->account),
 								 xfer->who, xfer->message, 0, time(NULL));
 
-		purple_request_accept_cancel(xfer, NULL, buf, NULL,
-								  PURPLE_DEFAULT_ACTION_NONE,
-								  xfer->account, xfer->who, NULL,
-								  xfer,
-								  G_CALLBACK(purple_xfer_choose_file),
-								  G_CALLBACK(cancel_recv_cb));
-
+		if (purple_xfer_get_thumbnail_data(xfer)) {
+			purple_request_accept_cancel_with_icon(xfer, NULL, buf, NULL,
+				PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL,
+				purple_xfer_get_thumbnail_data(xfer),
+				purple_xfer_get_thumbnail_size(xfer), xfer, 
+				G_CALLBACK(purple_xfer_choose_file),
+				G_CALLBACK(cancel_recv_cb));
+		} else {
+			purple_request_accept_cancel(xfer, NULL, buf, NULL,
+				PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL,
+				xfer, G_CALLBACK(purple_xfer_choose_file),
+				G_CALLBACK(cancel_recv_cb));
+		}
+			
 		g_free(buf);
 	} else
 		purple_xfer_choose_file(xfer);
--- a/libpurple/request.c	Sat Jul 04 07:18:19 2009 +0000
+++ b/libpurple/request.c	Sat Jul 04 21:45:19 2009 +0000
@@ -1281,6 +1281,29 @@
 }
 
 void *
+purple_request_action_with_icon(void *handle, const char *title, 
+					const char *primary,
+					const char *secondary, int default_action,
+					PurpleAccount *account, const char *who, 
+					PurpleConversation *conv, gconstpointer icon_data,
+					gsize icon_size, void *user_data, size_t action_count, ...)
+{
+	void *ui_handle;
+	va_list args;
+
+	g_return_val_if_fail(action_count > 0, NULL);
+
+	va_start(args, action_count);
+	ui_handle = purple_request_action_varg_with_icon(handle, title, primary, 
+		secondary, default_action, account, who, conv, icon_data, icon_size,
+		user_data, action_count, args);
+	va_end(args);
+
+	return ui_handle;
+}
+
+
+void *
 purple_request_action_varg(void *handle, const char *title,
 						 const char *primary, const char *secondary,
 						 int default_action,
@@ -1312,6 +1335,41 @@
 }
 
 void *
+purple_request_action_varg_with_icon(void *handle, const char *title,
+						 const char *primary, const char *secondary,
+						 int default_action,
+						 PurpleAccount *account, const char *who, 
+						 PurpleConversation *conv, gconstpointer icon_data,
+						 gsize icon_size,
+						 void *user_data, size_t action_count, va_list actions)
+{
+	PurpleRequestUiOps *ops;
+
+	g_return_val_if_fail(action_count > 0, NULL);
+
+	ops = purple_request_get_ui_ops();
+
+	if (ops != NULL && ops->request_action != NULL) {
+		PurpleRequestInfo *info;
+
+		info            = g_new0(PurpleRequestInfo, 1);
+		info->type      = PURPLE_REQUEST_ACTION;
+		info->handle    = handle;
+		info->ui_handle = ops->request_action_with_icon(title, primary, secondary,
+											  default_action, account, who, conv,
+											  icon_data, icon_size,
+											  user_data, action_count, actions);
+
+		handles = g_list_append(handles, info);
+
+		return info->ui_handle;
+	}
+
+	return NULL;
+}
+
+
+void *
 purple_request_fields(void *handle, const char *title, const char *primary,
 					const char *secondary, PurpleRequestFields *fields,
 					const char *ok_text, GCallback ok_cb,
--- a/libpurple/request.h	Sat Jul 04 07:18:19 2009 +0000
+++ b/libpurple/request.h	Sat Jul 04 21:45:19 2009 +0000
@@ -236,10 +236,18 @@
 	                        PurpleAccount *account, const char *who,
 	                        PurpleConversation *conv, void *user_data);
 
+	/** @see purple_request_action_varg_with_icon(). */
+	void *(*request_action_with_icon)(const char *title, const char *primary,
+	                        const char *secondary, int default_action,
+	                        PurpleAccount *account, const char *who,
+	                        PurpleConversation *conv, 
+							gconstpointer icon_data, gsize icon_size,
+							void *user_data,
+	                        size_t action_count, va_list actions);
+
 	void (*_purple_reserved1)(void);
 	void (*_purple_reserved2)(void);
 	void (*_purple_reserved3)(void);
-	void (*_purple_reserved4)(void);
 } PurpleRequestUiOps;
 
 typedef void (*PurpleRequestInputCb)(void *, const char *);
@@ -1367,6 +1375,27 @@
 	void *user_data, size_t action_count, va_list actions);
 
 /**
+ * Version of purple_request_action() supplying an image for the UI to 
+ * optionally display as an icon in the dialog; see its documentation
+ */
+void *purple_request_action_with_icon(void *handle, const char *title, 
+	const char *primary, const char *secondary, int default_action, 
+	PurpleAccount *account, const char *who, PurpleConversation *conv, 
+	gconstpointer icon_data, gsize icon_size, void *user_data, 
+	size_t action_count, ...);
+
+/**
+ * <tt>va_list</tt> version of purple_request_action_with_icon(); 
+ * see its documentation.
+ */
+void *purple_request_action_varg_with_icon(void *handle, const char *title,
+	const char *primary, const char *secondary, int default_action,
+	PurpleAccount *account, const char *who, PurpleConversation *conv,
+	gconstpointer icon_data, gsize icon_size,
+	void *user_data, size_t action_count, va_list actions);
+
+
+/**
  * Displays groups of fields for the user to fill in.
  *
  * @param handle      The plugin or connection handle.  For some things this
@@ -1451,6 +1480,19 @@
 						_("_Accept"), (accept_cb), _("_Cancel"), (cancel_cb))
 
 /**
+ * A wrapper for purple_request_action_with_icon() that uses Accept and Cancel 
+ * buttons.
+ */
+#define purple_request_accept_cancel_with_icon(handle, title, primary, secondary, \
+								   default_action, account, who, conv, \
+								   icon_data, icon_size, \
+								   user_data, accept_cb, cancel_cb) \
+	purple_request_action_with_icon((handle), (title), (primary), (secondary), \
+						(default_action), account, who, conv, icon_data, icon_size, \
+						(user_data), 2, \
+						_("_Accept"), (accept_cb), _("_Cancel"), (cancel_cb))
+
+/**
  * Displays a file selector request dialog.  Returns the selected filename to
  * the callback.  Can be used for either opening a file or saving a file.
  *
--- a/pidgin/gtkrequest.c	Sat Jul 04 07:18:19 2009 +0000
+++ b/pidgin/gtkrequest.c	Sat Jul 04 21:45:19 2009 +0000
@@ -26,6 +26,7 @@
 #include "internal.h"
 #include "pidgin.h"
 
+#include "debug.h"
 #include "prefs.h"
 #include "util.h"
 
@@ -561,9 +562,11 @@
 }
 
 static void *
-pidgin_request_action(const char *title, const char *primary,
+pidgin_request_action_with_icon(const char *title, const char *primary,
 						const char *secondary, int default_action,
-					    PurpleAccount *account, const char *who, PurpleConversation *conv,
+					    PurpleAccount *account, const char *who, 
+						PurpleConversation *conv, gconstpointer icon_data,
+						gsize icon_size,
 						void *user_data, size_t action_count, va_list actions)
 {
 	PidginRequestData *data;
@@ -571,7 +574,7 @@
 	GtkWidget *vbox;
 	GtkWidget *hbox;
 	GtkWidget *label;
-	GtkWidget *img;
+	GtkWidget *img = NULL;
 	void **buttons;
 	char *label_text;
 	char *primary_esc, *secondary_esc;
@@ -630,8 +633,25 @@
 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
 	/* Dialog icon. */
-	img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
+	if (icon_data) {
+		GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+		GdkPixbuf *pixbuf = NULL;
+		if (gdk_pixbuf_loader_write(loader, icon_data, icon_size, NULL)) {
+			pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
+			if (pixbuf) {
+				img = gtk_image_new_from_pixbuf(pixbuf);
+			}
+		} else {
+			purple_debug_info("pidgin", "failed to parse dialog icon\n");
+		}
+		gdk_pixbuf_loader_close(loader, NULL);
+		g_object_unref(loader);
+	}
+	
+	if (!img) {
+		img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
 				       gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+	}
 	gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
 	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
 
@@ -681,6 +701,16 @@
 	return data;
 }
 
+static void *
+pidgin_request_action(const char *title, const char *primary,
+						const char *secondary, int default_action,
+					    PurpleAccount *account, const char *who, PurpleConversation *conv,
+						void *user_data, size_t action_count, va_list actions)
+{
+	pidgin_request_action_with_icon(title, primary, secondary, default_action,
+		account, who, conv, NULL, 0, user_data, action_count, actions);
+}
+
 static void
 req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field)
 {
@@ -1717,7 +1747,7 @@
 	pidgin_request_file,
 	pidgin_close_request,
 	pidgin_request_folder,
-	NULL,
+	pidgin_request_action_with_icon,
 	NULL,
 	NULL,
 	NULL