changeset 27164:f7ef790f3a44

merge of '43b8c66366c5dc03c717fa9d938446752df53293' and 'cd775ef3764162a2493ef7060750cd8c8ef544d4'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Mon, 08 Jun 2009 04:40:58 +0000
parents dda65a7151a2 (diff) 22d73c75e546 (current diff)
children 8671d9a37002
files pidgin/plugins/disco/gtkdisco.c
diffstat 3 files changed, 189 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/plugins/disco/gtkdisco.c	Mon Jun 08 03:35:14 2009 +0000
+++ b/pidgin/plugins/disco/gtkdisco.c	Mon Jun 08 04:40:58 2009 +0000
@@ -29,6 +29,7 @@
 #include "gtkutils.h"
 #include "pidgin.h"
 #include "request.h"
+#include "pidgintooltip.h"
 
 #include "gtkdisco.h"
 #include "xmppdisco.h"
@@ -64,7 +65,7 @@
 	g_return_val_if_fail(list != NULL, NULL);
 
 	++list->ref;
-    purple_debug_misc("xmppdisco", "reffing list, ref count now %d\n", list->ref);
+	purple_debug_misc("xmppdisco", "reffing list, ref count now %d\n", list->ref);
 
 	return list;
 }
@@ -110,7 +111,7 @@
 static void pidgin_disco_create_tree(PidginDiscoList *pdl);
 
 static void dialog_select_account_cb(GObject *w, PurpleAccount *account,
-				     PidginDiscoDialog *dialog)
+                                     PidginDiscoDialog *dialog)
 {
 	dialog->account = account;
 	gtk_widget_set_sensitive(dialog->browse_button, account != NULL);
@@ -210,15 +211,17 @@
 {
 	XmppDiscoService *service = g_object_get_data(G_OBJECT(button), "service");
 	PurpleAccount *account;
+	const char *jid;
 
 	g_return_if_fail(service != NULL);
 
 	account = purple_connection_get_account(service->list->pc);
+	jid = service->jid;
 
 	if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT)
-		purple_blist_request_add_chat(account, NULL, NULL, service->jid);
+		purple_blist_request_add_chat(account, NULL, NULL, jid);
 	else
-		purple_blist_request_add_buddy(account, service->name, NULL, NULL);
+		purple_blist_request_add_buddy(account, jid, NULL, NULL);
 }
 
 static void
@@ -268,6 +271,36 @@
 }
 
 static void
+row_activated_cb(GtkTreeView       *tree_view,
+                 GtkTreePath       *path,
+                 GtkTreeViewColumn *column,
+                 gpointer           user_data)
+{
+	PidginDiscoList *pdl = user_data;
+	GtkTreeIter iter;
+	XmppDiscoService *service;
+	GValue val;
+
+	if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(pdl->model), &iter, path))
+		return;
+
+	val.g_type = 0;
+	gtk_tree_model_get_value(GTK_TREE_MODEL(pdl->model), &iter, SERVICE_COLUMN,
+	                         &val);
+	service = g_value_get_pointer(&val);
+
+	if (service->flags & XMPP_DISCO_BROWSE)
+		if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(pdl->tree), path))
+			gtk_tree_view_collapse_row(GTK_TREE_VIEW(pdl->tree), path);
+		else
+			gtk_tree_view_expand_row(GTK_TREE_VIEW(pdl->tree), path, FALSE);
+	else if (service->flags & XMPP_DISCO_ADD)
+		add_room_to_blist_cb(GTK_BUTTON(pdl->dialog->add_button), pdl->dialog);
+	else if (service->flags & XMPP_DISCO_REGISTER)
+		register_button_cb(GTK_BUTTON(pdl->dialog->register_button), pdl->dialog);
+}
+
+static void
 destroy_win_cb(GtkWidget *window, gpointer d)
 {
 	PidginDiscoDialog *dialog = d;
@@ -303,6 +336,94 @@
 	return purple_strequal(purple_account_get_protocol_id(account), XMPP_PLUGIN_ID);
 }
 
+static gboolean
+disco_paint_tooltip(GtkWidget *tipwindow, gpointer data)
+{
+	PangoLayout *layout = g_object_get_data(G_OBJECT(tipwindow), "tooltip-plugin");
+	gtk_paint_layout(tipwindow->style, tipwindow->window, GTK_STATE_NORMAL, FALSE,
+			NULL, tipwindow, "tooltip",
+			6, 6, layout);
+	return TRUE;
+}
+
+static gboolean
+disco_create_tooltip(GtkWidget *tipwindow, GtkTreePath *path,
+		gpointer data, int *w, int *h)
+{
+	PidginDiscoList *pdl = data;
+	GtkTreeIter iter;
+	PangoLayout *layout;
+	int width, height;
+	XmppDiscoService *service;
+	GValue val;
+	const char *type = NULL;
+	char *markup, *jid, *name, *desc = NULL;
+
+	if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(pdl->model), &iter, path))
+		return FALSE;
+
+	val.g_type = 0;
+	gtk_tree_model_get_value(GTK_TREE_MODEL(pdl->model), &iter, SERVICE_COLUMN,
+	                         &val);
+	service = g_value_get_pointer(&val);
+
+	switch (service->type) {
+		case XMPP_DISCO_SERVICE_TYPE_UNSET:
+			type = _("Unknown");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_GATEWAY:
+			type = _("Gateway");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_DIRECTORY:
+			type = _("Directory");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_CHAT:
+			type = _("Chat");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION:
+			type = _("PubSub Collection");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_PUBSUB_LEAF:
+			type = _("PubSub Leaf");
+			break;
+
+		case XMPP_DISCO_SERVICE_TYPE_OTHER:
+			type = _("Other");
+			break;
+	}
+
+	markup = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>\n<b>%s:</b> %s%s%s",
+	                         name = g_markup_escape_text(service->name, -1),
+	                         type,
+	                         jid = g_markup_escape_text(service->jid, -1),
+	                         service->description ? _("\n<b>Description:</b> ") : "",
+	                         service->description ? desc = g_markup_escape_text(service->description, -1) : "");
+
+	layout = gtk_widget_create_pango_layout(tipwindow, NULL);
+	pango_layout_set_markup(layout, markup, -1);
+	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
+	pango_layout_set_width(layout, 500000);
+	pango_layout_get_size(layout, &width, &height);
+	g_object_set_data_full(G_OBJECT(tipwindow), "tooltip-plugin", layout, g_object_unref);
+
+	if (w)
+		*w = PANGO_PIXELS(width) + 12;
+	if (h)
+		*h = PANGO_PIXELS(height) + 12;
+
+	g_free(markup);
+	g_free(jid);
+	g_free(name);
+	g_free(desc);
+
+	return TRUE;
+}
+
 static void pidgin_disco_create_tree(PidginDiscoList *pdl)
 {
 	GtkCellRenderer *text_renderer, *pixbuf_renderer;
@@ -334,7 +455,7 @@
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_column_set_title(column, _("Name"));
 
-	gtk_tree_view_column_pack_start(column,  pixbuf_renderer, FALSE);
+	gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE);
 	gtk_tree_view_column_set_attributes(column, pixbuf_renderer,
 			"pixbuf", PIXBUF_COLUMN, NULL);
 
@@ -359,6 +480,11 @@
 	gtk_tree_view_append_column(GTK_TREE_VIEW(pdl->tree), column);
 
 	g_signal_connect(G_OBJECT(pdl->tree), "row-expanded", G_CALLBACK(row_expanded_cb), pdl);
+	g_signal_connect(G_OBJECT(pdl->tree), "row-activated", G_CALLBACK(row_activated_cb), pdl);
+
+	pidgin_tooltip_setup_for_treeview(pdl->tree, pdl,
+	                                  disco_create_tooltip,
+	                                  disco_paint_tooltip);
 }
 
 void pidgin_disco_signed_off_cb(PurpleConnection *pc)
@@ -450,13 +576,15 @@
 	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
 
 	/* stop button */
-	dialog->stop_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_STOP,
-	                 G_CALLBACK(stop_button_cb), dialog);
+	dialog->stop_button =
+		pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_STOP,
+		                         G_CALLBACK(stop_button_cb), dialog);
 	gtk_widget_set_sensitive(dialog->stop_button, FALSE);
 
 	/* browse button */
-	dialog->browse_button = pidgin_pixbuf_button_from_stock(_("_Browse"), GTK_STOCK_REFRESH,
-	                                                    PIDGIN_BUTTON_HORIZONTAL);
+	dialog->browse_button =
+		pidgin_pixbuf_button_from_stock(_("_Browse"), GTK_STOCK_REFRESH,
+		                                PIDGIN_BUTTON_HORIZONTAL);
 	gtk_box_pack_start(GTK_BOX(bbox), dialog->browse_button, FALSE, FALSE, 0);
 	g_signal_connect(G_OBJECT(dialog->browse_button), "clicked",
 	                 G_CALLBACK(browse_button_cb), dialog);
@@ -464,13 +592,15 @@
 	gtk_widget_show(dialog->browse_button);
 
 	/* register button */
-	dialog->register_button = pidgin_dialog_add_button(GTK_DIALOG(dialog->window), _("Register"),
-	                 G_CALLBACK(register_button_cb), dialog);
+	dialog->register_button =
+		pidgin_dialog_add_button(GTK_DIALOG(dialog->window), _("Register"),
+		                         G_CALLBACK(register_button_cb), dialog);
 	gtk_widget_set_sensitive(dialog->register_button, FALSE);
 
 	/* add button */
-	dialog->add_button = pidgin_pixbuf_button_from_stock(_("_Add"), GTK_STOCK_ADD,
-	                                                    PIDGIN_BUTTON_HORIZONTAL);
+	dialog->add_button =
+		pidgin_pixbuf_button_from_stock(_("_Add"), GTK_STOCK_ADD,
+	                                    PIDGIN_BUTTON_HORIZONTAL);
 	gtk_box_pack_start(GTK_BOX(bbox), dialog->add_button, FALSE, FALSE, 0);
 	g_signal_connect(G_OBJECT(dialog->add_button), "clicked",
 	                 G_CALLBACK(add_to_blist_cb), dialog);
@@ -478,8 +608,9 @@
 	gtk_widget_show(dialog->add_button);
 
 	/* close button */
-	dialog->close_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE,
-					 G_CALLBACK(close_button_cb), dialog);
+	dialog->close_button =
+		pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE,
+		                         G_CALLBACK(close_button_cb), dialog);
 
 	/* show the dialog window and return the dialog */
 	gtk_widget_show(dialog->window);
--- a/pidgin/plugins/disco/xmppdisco.c	Mon Jun 08 03:35:14 2009 +0000
+++ b/pidgin/plugins/disco/xmppdisco.c	Mon Jun 08 04:40:58 2009 +0000
@@ -56,8 +56,8 @@
 static gboolean iq_listening = FALSE;
 
 typedef void (*XmppIqCallback)(PurpleConnection *pc, const char *type,
-                              const char *id, const char *from, xmlnode *iq,
-							  gpointer data);
+                               const char *id, const char *from, xmlnode *iq,
+                               gpointer data);
 
 struct xmpp_iq_cb_data
 {
@@ -149,7 +149,7 @@
 	g_hash_table_insert(iq_callbacks, id, cbdata);
 
 	if (!iq_listening) {
-    	PurplePlugin *prpl = purple_plugins_find_with_id(XMPP_PLUGIN_ID);
+		PurplePlugin *prpl = purple_plugins_find_with_id(XMPP_PLUGIN_ID);
 		iq_listening = TRUE;
 		purple_signal_connect(prpl, "jabber-receiving-iq", my_plugin,
 		                      PURPLE_CALLBACK(xmpp_iq_received), NULL);
@@ -245,30 +245,30 @@
 }
 
 static const struct {
-    const char *from;
-    const char *to;
+	const char *from;
+	const char *to;
 } disco_type_mappings[] = {
-    { "gadu-gadu", "gadu-gadu" }, /* the prpl is prpl-gg, but list_icon returns "gadu-gadu" */
-    { "sametime",  "meanwhile" },
-    { "myspaceim", "myspace" },
-    { "xmpp",      "jabber" }, /* prpl-jabber (mentioned in case the prpl is renamed so this line will match) */
-    { NULL,        NULL }
+	{ "gadu-gadu", "gadu-gadu" }, /* the prpl is prpl-gg, but list_icon returns "gadu-gadu" */
+	{ "sametime",  "meanwhile" },
+	{ "myspaceim", "myspace" },
+	{ "xmpp",      "jabber" }, /* prpl-jabber (mentioned in case the prpl is renamed so this line will match) */
+	{ NULL,        NULL }
 };
 
 static const gchar *
 disco_type_from_string(const gchar *str)
 {
-    int i = 0;
+	int i = 0;
 
-    g_return_val_if_fail(str != NULL, "");
+	g_return_val_if_fail(str != NULL, "");
 
-    for ( ; disco_type_mappings[i].from; ++i) {
-        if (!strcasecmp(str, disco_type_mappings[i].from))
-            return disco_type_mappings[i].to;
-    }
+	for ( ; disco_type_mappings[i].from; ++i) {
+		if (!strcasecmp(str, disco_type_mappings[i].from))
+			return disco_type_mappings[i].to;
+	}
 
-    /* fallback to the string itself */
-    return str;
+	/* fallback to the string itself */
+	return str;
 }
 
 static void
@@ -607,13 +607,13 @@
 static gboolean
 plugin_load(PurplePlugin *plugin)
 {
-    PurplePlugin *xmpp_prpl;
+	PurplePlugin *xmpp_prpl;
 
 	my_plugin = plugin;
 
-    xmpp_prpl = purple_plugins_find_with_id(XMPP_PLUGIN_ID);
-    if (NULL == xmpp_prpl)
-        return FALSE;
+	xmpp_prpl = purple_plugins_find_with_id(XMPP_PLUGIN_ID);
+	if (NULL == xmpp_prpl)
+		return FALSE;
 
 	purple_signal_connect(purple_connections_get_handle(), "signing-off",
 	                      plugin, PURPLE_CALLBACK(signed_off_cb), NULL);
--- a/pidgin/plugins/disco/xmppdisco.h	Mon Jun 08 03:35:14 2009 +0000
+++ b/pidgin/plugins/disco/xmppdisco.h	Mon Jun 08 04:40:58 2009 +0000
@@ -40,22 +40,22 @@
  */
 typedef enum
 {
-    XMPP_DISCO_SERVICE_TYPE_UNSET,
-    /**
-     * A registerable gateway to another protocol. An example would be
-     * XMPP legacy transports.
-     */
-    XMPP_DISCO_SERVICE_TYPE_GATEWAY,
+	XMPP_DISCO_SERVICE_TYPE_UNSET,
+	/**
+	 * A registerable gateway to another protocol. An example would be
+	 * XMPP legacy transports.
+	 */
+	XMPP_DISCO_SERVICE_TYPE_GATEWAY,
 
-    /**
-     * A directory (e.g. allows the user to search for other users).
-     */
-    XMPP_DISCO_SERVICE_TYPE_DIRECTORY,
+	/**
+	 * A directory (e.g. allows the user to search for other users).
+	 */
+	XMPP_DISCO_SERVICE_TYPE_DIRECTORY,
 
-    /**
-     * A chat (multi-user conversation).
-     */
-    XMPP_DISCO_SERVICE_TYPE_CHAT,
+	/**
+	 * A chat (multi-user conversation).
+	 */
+	XMPP_DISCO_SERVICE_TYPE_CHAT,
 
 	/**
 	 * A pubsub collection (contains nodes)
@@ -68,9 +68,9 @@
 	XMPP_DISCO_SERVICE_TYPE_PUBSUB_LEAF,
 
 	/**
-     * Something else. Do we need more categories?
-     */
-    XMPP_DISCO_SERVICE_TYPE_OTHER
+	 * Something else. Do we need more categories?
+	 */
+	XMPP_DISCO_SERVICE_TYPE_OTHER
 } XmppDiscoServiceType;
 
 /**
@@ -78,10 +78,10 @@
  */
 typedef enum
 {
-    XMPP_DISCO_NONE          = 0x0000,
-    XMPP_DISCO_ADD           = 0x0001, /**< Supports an 'add' operation */
-    XMPP_DISCO_BROWSE        = 0x0002, /**< Supports browsing */
-    XMPP_DISCO_REGISTER      = 0x0004  /**< Supports a 'register' operation */
+	XMPP_DISCO_NONE          = 0x0000,
+	XMPP_DISCO_ADD           = 0x0001, /**< Supports an 'add' operation */
+	XMPP_DISCO_BROWSE        = 0x0002, /**< Supports browsing */
+	XMPP_DISCO_REGISTER      = 0x0004  /**< Supports a 'register' operation */
 } XmppDiscoServiceFlags;
 
 struct _XmppDiscoService {