changeset 14561:3ff55ec8203a

[gaim-migrate @ 17284] GtkCellRendererExpander draws an expander in a renderer to avoid a large, needless margin. The approach is a bit hacky, but it's a good job. - RTL fix in GtkStatusBox - Drag-and-drop image into the global buddy icon selector to set a buddy icon committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Fri, 15 Sep 2006 22:05:34 +0000
parents 16bba6d02c2a
children 78d0f3c4c9ff
files gtk/Makefile.am gtk/gaimstock.c gtk/gaimstock.h gtk/gtkblist.c gtk/gtkblist.h gtk/gtkcellrendererexpander.c gtk/gtkcellrendererexpander.h gtk/gtkmain.c gtk/gtkstatusbox.c gtk/pixmaps/Makefile.am gtk/pixmaps/expander-collapsed.png gtk/pixmaps/expander-expanded.png
diffstat 12 files changed, 420 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/Makefile.am	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/Makefile.am	Fri Sep 15 22:05:34 2006 +0000
@@ -64,6 +64,7 @@
 	gtkaccount.c \
 	gtkblist.c \
 	gtkcelllayout.c \
+	gtkcellrendererexpander.c \
 	gtkcellrendererprogress.c \
 	gtkcellview.c \
 	gtkcellviewmenuitem.c \
@@ -102,6 +103,7 @@
 	gtkaccount.h \
 	gtkblist.h \
 	gtkcelllayout.h \
+	gtkcellrendererexpander.h \
 	gtkcellrendererprogress.h \
 	gtkcellview.h \
 	gtkcellviewmenuitem.h \
--- a/gtk/gaimstock.c	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gaimstock.c	Fri Sep 15 22:05:34 2006 +0000
@@ -130,8 +130,6 @@
 	{ GAIM_STOCK_STATUS_CONNECT2, "gaim",    "status-connect2.png"      },
 	{ GAIM_STOCK_STATUS_CONNECT3, "gaim",    "status-connect3.png"      },
 	{ GAIM_STOCK_UPLOAD,          NULL,      GTK_STOCK_GO_UP            },
-	{ GAIM_STOCK_EXPANDER_EXPANDED,"gaim",   "expander-expanded.png"    },
-	{ GAIM_STOCK_EXPANDER_COLLAPSED,"gaim",  "expander-collapsed.png"   },
 };
 
 static const GtkStockItem stock_items[] =
--- a/gtk/gaimstock.h	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gaimstock.h	Fri Sep 15 22:05:34 2006 +0000
@@ -98,8 +98,6 @@
 #define GAIM_STOCK_TYPING          "gaim-typing"
 #define GAIM_STOCK_UPLOAD          "gaim-upload"
 #define GAIM_STOCK_VOICE_CHAT      "gaim-voice-chat"
-#define GAIM_STOCK_EXPANDER_EXPANDED "gaim-stock-expander-expanded"
-#define GAIM_STOCK_EXPANDER_COLLAPSED "gaim-stock-expander-collapsed"
 /*@}*/
 
 /**
--- a/gtk/gtkblist.c	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gtkblist.c	Fri Sep 15 22:05:34 2006 +0000
@@ -41,6 +41,7 @@
 
 #include "gtkaccount.h"
 #include "gtkblist.h"
+#include "gtkcellrendererexpander.h"
 #include "gtkconv.h"
 #include "gtkdebug.h"
 #include "gtkdialogs.h"
@@ -810,10 +811,10 @@
 	} else if (GAIM_BLIST_NODE_IS_CHAT(node)) {
 		gtk_blist_join_chat((GaimChat *)node);
 	} else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
-		if (gtk_tree_view_row_expanded(tv, path))
+/*		if (gtk_tree_view_row_expanded(tv, path))
 			gtk_tree_view_collapse_row(tv, path);
 		else
-			gtk_tree_view_expand_row(tv,path,FALSE);
+			gtk_tree_view_expand_row(tv,path,FALSE);*/
 	}
 }
 
@@ -3928,10 +3929,18 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
 	gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS,
-						 GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_STRING, 
-						 G_TYPE_STRING, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN,
-						 G_TYPE_POINTER, GDK_TYPE_COLOR, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF,
-						 G_TYPE_BOOLEAN);
+						 GDK_TYPE_PIXBUF, /* Status icon */
+						 G_TYPE_BOOLEAN,  /* Status icon visible */
+						 G_TYPE_STRING,   /* Name */ 
+						 G_TYPE_STRING,   /* Idle */
+						 G_TYPE_BOOLEAN,  /* Idle visible */
+						 GDK_TYPE_PIXBUF, /* Buddy icon */
+						 G_TYPE_BOOLEAN,  /* Buddy icon visible */
+						 G_TYPE_POINTER,  /* Node */
+						 GDK_TYPE_COLOR,  /* bgcolor */
+						 G_TYPE_BOOLEAN,  /* Group expander */
+						 G_TYPE_BOOLEAN,  /* Contact expander */
+						 G_TYPE_BOOLEAN); /* Contact expander visible */
 
 	gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel));
 
@@ -3971,17 +3980,17 @@
 	gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gtkblist->treeview), column);
 
 	gtkblist->text_column = column = gtk_tree_view_column_new ();
-	rend = gtk_cell_renderer_pixbuf_new();
+	rend = gaim_gtk_cell_renderer_expander_new();
 	gtk_tree_view_column_pack_start(column, rend, FALSE);
 	gtk_tree_view_column_set_attributes(column, rend,
-					    "pixbuf", GROUP_EXPANDER_COLUMN,
+					    "expander-visible", GROUP_EXPANDER_COLUMN,
 					    "cell-background-gdk", BGCOLOR_COLUMN,
 					    NULL);
 
-	rend = gtk_cell_renderer_pixbuf_new();
+	rend = gaim_gtk_cell_renderer_expander_new();
 	gtk_tree_view_column_pack_start(column, rend, FALSE);
 	gtk_tree_view_column_set_attributes(column, rend,
-					    "pixbuf", CONTACT_EXPANDER_COLUMN,
+					    "expander-visible", CONTACT_EXPANDER_COLUMN,
 					    "visible", CONTACT_EXPANDER_VISIBLE_COLUMN,
 					    "cell-background-gdk", BGCOLOR_COLUMN,
 					    NULL);
@@ -4026,9 +4035,6 @@
 					    NULL);
 	
 
-	gtkblist->expander_expanded = gtk_widget_render_icon(gtkblist->treeview, GAIM_STOCK_EXPANDER_EXPANDED, -1, NULL);
-	gtkblist->expander_collapsed = gtk_widget_render_icon(gtkblist->treeview, GAIM_STOCK_EXPANDER_COLLAPSED, -1, NULL);
-
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL);
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL);
 	g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL);
@@ -4412,7 +4418,7 @@
 				   NAME_COLUMN, mark,
 				   NODE_COLUMN, gnode,
 				   BGCOLOR_COLUMN, &bgcolor,
-				   GROUP_EXPANDER_COLUMN, expanded ? gtkblist->expander_expanded : gtkblist->expander_collapsed,
+				   GROUP_EXPANDER_COLUMN, TRUE,
 				   CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE,
 				   BUDDY_ICON_VISIBLE_COLUMN, FALSE,
 				   IDLE_VISIBLE_COLUMN, FALSE,
@@ -4540,7 +4546,7 @@
 					   IDLE_VISIBLE_COLUMN, FALSE,
 					   BGCOLOR_COLUMN, NULL,
 					   BUDDY_ICON_COLUMN, NULL,
-					   CONTACT_EXPANDER_COLUMN, gtkblist->expander_expanded,
+					   CONTACT_EXPANDER_COLUMN, TRUE,
 					   CONTACT_EXPANDER_VISIBLE_COLUMN, TRUE,
 					-1);
 			g_free(mark);
--- a/gtk/gtkblist.h	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gtkblist.h	Fri Sep 15 22:05:34 2006 +0000
@@ -94,10 +94,6 @@
 	GaimBlistNode *selected_node;    /**< The currently selected node */
 	GtkWidget *error_buttons;        /**< Box containing the connection error buttons */
 	GtkWidget *statusbox;            /**< The status selector dropdown */
-	GdkPixbuf *east, *south;                 /**< Drop shadow stuff */
-	GdkWindow *east_shadow, *south_shadow;   /**< Drop shadow stuff */
-	GdkPixbuf *expander_collapsed;   /**< A collapsed expander */
-	GdkPixbuf *expander_expanded;    /**< An expanded expander */  
 };
 
 #define GAIM_GTK_BLIST(list) ((GaimGtkBuddyList *)(list)->ui_data)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gtk/gtkcellrendererexpander.c	Fri Sep 15 22:05:34 2006 +0000
@@ -0,0 +1,283 @@
+/*
+ * @file gtkcellrendererexpander.c GTK+ Cell Renderer Expander
+ * @ingroup gtkui
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by 
+ * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc.
+ */
+
+#include <gtk/gtktreeview.h>
+#include "gtkcellrendererexpander.h"
+
+static void gaim_gtk_cell_renderer_expander_get_property  (GObject                    *object,
+						      guint                       param_id,
+						      GValue                     *value,
+						      GParamSpec                 *pspec);
+static void gaim_gtk_cell_renderer_expander_set_property  (GObject                    *object,
+						      guint                       param_id,
+						      const GValue               *value,
+						      GParamSpec                 *pspec);
+static void gaim_gtk_cell_renderer_expander_init       (GaimGtkCellRendererExpander      *cellexpander);
+static void gaim_gtk_cell_renderer_expander_class_init (GaimGtkCellRendererExpanderClass *class);
+static void gaim_gtk_cell_renderer_expander_get_size   (GtkCellRenderer            *cell,
+						   GtkWidget                  *widget,
+						   GdkRectangle               *cell_area,
+						   gint                       *x_offset,
+						   gint                       *y_offset,
+						   gint                       *width,
+						   gint                       *height);
+static void gaim_gtk_cell_renderer_expander_render     (GtkCellRenderer            *cell,
+						   GdkWindow                  *window,
+						   GtkWidget                  *widget,
+						   GdkRectangle               *background_area,
+						   GdkRectangle               *cell_area,
+						   GdkRectangle               *expose_area,
+						   guint                       flags);
+static gboolean gaim_gtk_cell_renderer_expander_activate  (GtkCellRenderer            *cell,
+						      GdkEvent                   *event,
+						      GtkWidget                  *widget,
+						      const gchar                *path,
+						      GdkRectangle               *background_area,
+						      GdkRectangle               *cell_area,
+						      guint                       flags);
+static void  gaim_gtk_cell_renderer_expander_finalize (GObject *gobject);
+
+enum {
+	LAST_SIGNAL
+};
+
+enum {
+	PROP_0,
+	PROP_IS_EXPANDER
+};
+     
+static gpointer parent_class;
+/* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */
+
+GType  gaim_gtk_cell_renderer_expander_get_type (void)
+{
+	static GType cell_expander_type = 0;
+	
+	if (!cell_expander_type)
+		{
+			static const GTypeInfo cell_expander_info =
+				{
+					sizeof (GaimGtkCellRendererExpanderClass),
+					NULL,           /* base_init */
+					NULL,           /* base_finalize */
+					(GClassInitFunc) gaim_gtk_cell_renderer_expander_class_init,
+					NULL,           /* class_finalize */
+					NULL,           /* class_data */
+					sizeof (GaimGtkCellRendererExpander),
+					0,              /* n_preallocs */
+					(GInstanceInitFunc) gaim_gtk_cell_renderer_expander_init,
+					NULL		/* value_table */
+				};
+			
+			cell_expander_type =
+				g_type_register_static (GTK_TYPE_CELL_RENDERER,
+										"GaimGtkCellRendererExpander",
+										&cell_expander_info, 0);
+		}
+	
+	return cell_expander_type;
+}
+
+static void gaim_gtk_cell_renderer_expander_init (GaimGtkCellRendererExpander *cellexpander)
+{
+	GTK_CELL_RENDERER(cellexpander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+	GTK_CELL_RENDERER(cellexpander)->xpad = 2;
+	GTK_CELL_RENDERER(cellexpander)->ypad = 2;
+}
+
+static void gaim_gtk_cell_renderer_expander_class_init (GaimGtkCellRendererExpanderClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(class);
+	GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
+	
+	parent_class = g_type_class_peek_parent (class);
+	object_class->finalize = gaim_gtk_cell_renderer_expander_finalize;
+
+	object_class->get_property = gaim_gtk_cell_renderer_expander_get_property;
+	object_class->set_property = gaim_gtk_cell_renderer_expander_set_property;
+	
+	cell_class->get_size = gaim_gtk_cell_renderer_expander_get_size;
+	cell_class->render   = gaim_gtk_cell_renderer_expander_render;
+	cell_class->activate = gaim_gtk_cell_renderer_expander_activate;
+	
+	g_object_class_install_property (object_class,
+					 PROP_IS_EXPANDER,
+					 g_param_spec_boolean ("expander-visible",
+							      "Is Expander",
+							      "True if the renderer should draw an expander",
+							      FALSE,
+							      G_PARAM_READWRITE));
+}
+
+static void gaim_gtk_cell_renderer_expander_finalize (GObject *object)
+{
+/*
+	GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER(object);
+*/
+
+	(* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+static void gaim_gtk_cell_renderer_expander_get_property (GObject    *object,
+						     guint      param_id,
+						     GValue     *value,
+						     GParamSpec *psec)
+{
+	GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER(object);
+
+	switch (param_id)
+		{
+		case PROP_IS_EXPANDER:
+			g_value_set_boolean(value, cellexpander->is_expander);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec);
+			break;
+			
+		}
+}
+
+static void gaim_gtk_cell_renderer_expander_set_property (GObject      *object,
+						     guint        param_id,
+						     const GValue *value,
+						     GParamSpec   *pspec)
+{
+	GaimGtkCellRendererExpander *cellexpander = GAIM_GTK_CELL_RENDERER_EXPANDER (object);
+
+	switch (param_id)
+		{
+		case PROP_IS_EXPANDER:
+			cellexpander->is_expander = g_value_get_boolean(value);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+			break;
+		}
+}
+
+GtkCellRenderer *gaim_gtk_cell_renderer_expander_new(void)
+{
+	return g_object_new(GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER, NULL);
+}
+
+static void gaim_gtk_cell_renderer_expander_get_size (GtkCellRenderer *cell,
+						 GtkWidget       *widget,
+						 GdkRectangle    *cell_area,
+						 gint            *x_offset,
+						 gint            *y_offset,
+						 gint            *width,
+						 gint            *height)
+{
+	gint calc_width;
+	gint calc_height;
+	gint expander_size; 
+	
+	gtk_widget_style_get(widget, "expander-size", &expander_size, NULL);
+	
+	calc_width = (gint) cell->xpad * 2 + expander_size;
+	calc_height = (gint) cell->ypad * 2 + expander_size;
+	
+	if (width)
+		*width = calc_width;
+	
+	if (height)
+		*height = calc_height;
+	
+	if (cell_area)
+		{
+			if (x_offset)
+				{
+					*x_offset = cell->xalign * (cell_area->width - calc_width);
+					*x_offset = MAX (*x_offset, 0);
+				}
+			if (y_offset)
+				{
+					*y_offset = cell->yalign * (cell_area->height - calc_height);
+					*y_offset = MAX (*y_offset, 0);
+				}
+		}
+}
+
+
+static void gaim_gtk_cell_renderer_expander_render (GtkCellRenderer *cell,
+					       GdkWindow       *window,
+					       GtkWidget       *widget,
+					       GdkRectangle    *background_area,
+					       GdkRectangle    *cell_area,
+					       GdkRectangle    *expose_area,
+					       guint            flags)
+{
+	GaimGtkCellRendererExpander *cellexpander = (GaimGtkCellRendererExpander *) cell;
+	
+	gint width, height;
+	GtkStateType state;
+
+	if (!cellexpander->is_expander)
+		return;
+
+	width = cell_area->width;
+	height = cell_area->height;
+	
+	if (!cell->sensitive)
+		state = GTK_STATE_INSENSITIVE;
+	else if (flags & GTK_CELL_RENDERER_PRELIT)
+		state = GTK_STATE_PRELIGHT;
+	else if (GTK_WIDGET_HAS_FOCUS (widget) && flags & GTK_CELL_RENDERER_SELECTED)
+		state = GTK_STATE_ACTIVE;
+	else
+		state = GTK_STATE_NORMAL;
+
+	width -= cell->xpad*2;
+	height -= cell->ypad*2;
+
+	gtk_paint_expander (widget->style,
+			    window, state,
+			    NULL, widget, "treeview",
+			    cell_area->x + cell->xpad + (width / 2),
+			    cell_area->y + cell->ypad + (height / 2),
+			    cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
+}
+
+static gint gaim_gtk_cell_renderer_expander_activate(GtkCellRenderer *r,
+						     GdkEvent *event,
+						     GtkWidget *widget,
+						     const gchar *p,
+						     GdkRectangle *bg,
+						     GdkRectangle *cell,
+						     GtkCellRendererState flags)
+{
+	GtkTreePath *path = gtk_tree_path_new_from_string(p);
+printf("!! Activated!\n");
+	if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
+		gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
+	else
+		gtk_tree_view_expand_row(GTK_TREE_VIEW(widget),path,FALSE);
+	gtk_tree_path_free(path);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gtk/gtkcellrendererexpander.h	Fri Sep 15 22:05:34 2006 +0000
@@ -0,0 +1,59 @@
+/* gtkxcellrendererexpander.h
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#ifndef _GAIM_GTKCELLRENDEREREXPANDER_H_
+#define _GAIM_GTKCELLRENDEREREXPANDER_H_
+
+#include <gtk/gtkcellrenderer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER         (gaim_gtk_cell_renderer_expander_get_type())
+#define GAIM_GTK_CELL_RENDERER_EXPANDER(obj)         (G_TYPE_CHECK_INSTANCE_CAST((obj), GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER, GaimGtkCellRendererExpander))
+#define GAIM_GTK_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER, GaimGtkCellRendererExpanderClass))
+#define GAIM_IS_GTK_CELL_RENDERER_EXPANDER(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER))
+#define GAIM_IS_GTK_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER))
+#define GAIM_GTK_CELL_RENDERER_EXPANDER_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER, GaimGtkCellRendererExpanderClass))
+
+typedef struct _GaimGtkCellRendererExpander GaimGtkCellRendererExpander;
+typedef struct _GaimGtkCellRendererExpanderClass GaimGtkCellRendererExpanderClass;
+
+struct _GaimGtkCellRendererExpander {
+	GtkCellRenderer parent;
+
+	gboolean is_expander;
+};
+
+struct _GaimGtkCellRendererExpanderClass {
+	GtkCellRendererClass parent_class;
+};
+
+GType            gaim_gtk_cell_renderer_expander_get_type     (void);
+GtkCellRenderer  *gaim_gtk_cell_renderer_expander_new          (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GAIM_GTKCELLRENDEREREXPANDER_H_ */
--- a/gtk/gtkmain.c	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gtkmain.c	Fri Sep 15 22:05:34 2006 +0000
@@ -796,7 +796,6 @@
 #ifdef HAVE_STARTUP_NOTIFICATION
 	startup_notification_complete();
 #endif
-
 	gtk_main();
 
 #ifdef HAVE_SIGNAL_H
--- a/gtk/gtkstatusbox.c	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/gtkstatusbox.c	Fri Sep 15 22:05:34 2006 +0000
@@ -238,6 +238,36 @@
 	return FALSE;
 }
 
+static void
+icon_box_dnd_cb(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
+		GtkSelectionData *sd, guint info, guint t, GtkGaimStatusBox *box)
+{
+	gchar *name = (gchar *)sd->data;
+
+	if ((sd->length >= 0) && (sd->format == 8)) {
+		/* Well, it looks like the drag event was cool.
+		 * Let's do something with it */
+		if (!g_ascii_strncasecmp(name, "file://", 7)) {
+			GError *converr = NULL;
+			gchar *tmp, *rtmp;
+		
+			if(!(tmp = g_filename_from_uri(name, NULL, &converr))) {
+				gaim_debug(GAIM_DEBUG_ERROR, "buddyicon", "%s\n",
+					   (converr ? converr->message :
+					    "g_filename_from_uri error"));
+				return;
+			}
+			if ((rtmp = strchr(tmp, '\r')) || (rtmp = strchr(tmp, '\n')))
+				*rtmp = '\0';
+			icon_choose_cb(tmp, box);
+			g_free(tmp);
+		}
+		gtk_drag_finish(dc, TRUE, FALSE, t);
+	}
+	gtk_drag_finish(dc, FALSE, FALSE, t);
+}
+
+
 static gboolean
 icon_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, GtkGaimStatusBox *box)
 {
@@ -254,6 +284,13 @@
 	return FALSE;
 }
 
+
+static const GtkTargetEntry dnd_targets[] = {
+       {"text/plain", 0, 0},
+	{"text/uri-list", 0, 1},
+	{"STRING", 0, 2}
+};
+
 static void
 setup_icon_box(GtkGaimStatusBox *status_box)
 {
@@ -273,9 +310,19 @@
 	}
 	status_box->icon = gtk_image_new_from_pixbuf(status_box->buddy_icon);
 	status_box->icon_box = gtk_event_box_new();
+	
 	status_box->hand_cursor = gdk_cursor_new (GDK_HAND2);
 	status_box->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR);
 
+	/* Set up DND */
+	gtk_drag_dest_set(status_box->icon_box,
+			  GTK_DEST_DEFAULT_MOTION |
+			  GTK_DEST_DEFAULT_DROP,
+			  dnd_targets,
+			  sizeof(dnd_targets) / sizeof(GtkTargetEntry),
+			  GDK_ACTION_COPY);
+	
+	g_signal_connect(G_OBJECT(status_box->icon_box), "drag_data_received", G_CALLBACK(icon_box_dnd_cb), status_box);
 	g_signal_connect(G_OBJECT(status_box->icon_box), "enter-notify-event", G_CALLBACK(icon_box_enter_cb), status_box);
 	g_signal_connect(G_OBJECT(status_box->icon_box), "leave-notify-event", G_CALLBACK(icon_box_leave_cb), status_box);
 	g_signal_connect(G_OBJECT(status_box->icon_box), "button-press-event", G_CALLBACK(icon_box_press_cb), status_box);
@@ -1272,11 +1319,17 @@
 
 	if (status_box->icon_box)
 	{
+		GtkTextDirection dir = gtk_widget_get_direction(widget);
 		parent_alc.width -= (parent_alc.height + border_width);
 		icon_alc = *allocation;
 		icon_alc.height = MAX(1,req.height) - (border_width);
 		icon_alc.width = icon_alc.height;
-		icon_alc.x = allocation->width - (icon_alc.width + border_width);
+		if (dir == GTK_TEXT_DIR_RTL) {
+			icon_alc.x = parent_alc.x;
+			parent_alc.x += icon_alc.width + border_width;
+		} else {
+			icon_alc.x = allocation->width - (icon_alc.width + border_width);
+		}
 		icon_alc.y += border_width;
 	       
 		if (status_box->icon_size != icon_alc.height)
--- a/gtk/pixmaps/Makefile.am	Fri Sep 15 17:10:37 2006 +0000
+++ b/gtk/pixmaps/Makefile.am	Fri Sep 15 22:05:34 2006 +0000
@@ -8,8 +8,6 @@
 		change-fgcolor-small.png	\
 		connect.png			\
 		edit.png			\
-		expander-expanded.png           \
-		expander-collapsed.png          \
 		gaim.png			\
 		gaim.svg			\
 		gaim_auth.png			\
@@ -84,7 +82,7 @@
 gaimiconpix_DATA = away.png connect.png msgpend.png offline.png online.png msgunread.png stock_connect_16.png stock_disconnect_16.png
 
 gaimdistpixdir = $(datadir)/pixmaps/gaim
-gaimdistpix_DATA = logo.png tb_drag_arrow_down.xpm tb_drag_arrow_left.xpm tb_drag_arrow_right.xpm tb_drag_arrow_up.xpm typed.png typing.png status-online.png status-offline.png status-away.png status-invisible.png status-typing0.png status-typing1.png status-typing2.png status-typing3.png status-connect0.png status-connect1.png status-connect2.png status-connect3.png phone.png expander-expanded.png expander-collapsed.png
+gaimdistpix_DATA = logo.png tb_drag_arrow_down.xpm tb_drag_arrow_left.xpm tb_drag_arrow_right.xpm tb_drag_arrow_up.xpm typed.png typing.png status-online.png status-offline.png status-away.png status-invisible.png status-typing0.png status-typing1.png status-typing2.png status-typing3.png status-connect0.png status-connect1.png status-connect2.png status-connect3.png phone.png
 
 distpixmapdir = $(datadir)/pixmaps
 distpixmap_DATA = gaim.png gaim.svg
Binary file gtk/pixmaps/expander-collapsed.png has changed
Binary file gtk/pixmaps/expander-expanded.png has changed