[gnome-panel] [panel] Port away from GnomeIconEntry



commit 93d07aae99349c37730e509a2ab4906885ad3bae
Author: Vincent Untz <vuntz gnome org>
Date:   Tue Jan 12 18:53:53 2010 +0100

    [panel] Port away from GnomeIconEntry
    
    We add a new PanelIconChooser widget, which is a simple button opening a
    GtkFileChooser.
    
    Some code is also factored in libpanel-util:
     - API to easily add an image preview to a file chooser (moved away from
       gnome-panel-properties.c)
     - some XDG-related icon theme API (moved away from panel-util.c:
       panel_util_icon_remove_extension is renamed to
       panel_xdg_icon_remove_extension)
    
    The new PanelIconChooser is now used in panel-ditem-editor.c and
    panel-properties-dialog.c. This enables us to remove some workaround to
    handle icon themes in a hacky way -- this is now hidden in
    PanelIconChooser.

 gnome-panel/libpanel-util/Makefile.am          |    6 +
 gnome-panel/libpanel-util/panel-gtk.c          |   83 ++++
 gnome-panel/libpanel-util/panel-gtk.h          |    4 +-
 gnome-panel/libpanel-util/panel-icon-chooser.c |  555 ++++++++++++++++++++++++
 gnome-panel/libpanel-util/panel-icon-chooser.h |   75 ++++
 gnome-panel/libpanel-util/panel-xdg.c          |  152 +++++++
 gnome-panel/libpanel-util/panel-xdg.h          |   39 ++
 gnome-panel/menu.c                             |    3 +-
 gnome-panel/panel-ditem-editor.c               |   98 +----
 gnome-panel/panel-properties-dialog.c          |  134 +-----
 gnome-panel/panel-util.c                       |   21 +-
 gnome-panel/panel-util.h                       |    1 -
 12 files changed, 965 insertions(+), 206 deletions(-)
---
diff --git a/gnome-panel/libpanel-util/Makefile.am b/gnome-panel/libpanel-util/Makefile.am
index 38beeb5..3e2a7fe 100644
--- a/gnome-panel/libpanel-util/Makefile.am
+++ b/gnome-panel/libpanel-util/Makefile.am
@@ -9,6 +9,7 @@ INCLUDES =							\
 	-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"	\
 	-DBUILDERDIR=\""$(uidir)"\"				\
 	-DICONDIR=\""$(datadir)/gnome-panel/pixmaps"\"		\
+	-DDATADIR=\""$(datadir)"\"				\
 	-DGMENU_I_KNOW_THIS_IS_UNSTABLE				\
 	$(DISABLE_DEPRECATED_CFLAGS)				\
 	$(STANDARD_PROPERTIES_CFLAGS)				\
@@ -28,7 +29,10 @@ libpanel_util_la_SOURCES=	\
 	panel-error.h			\
 	panel-glib.c			\
 	panel-glib.h			\
+	panel-gtk.c			\
 	panel-gtk.h			\
+	panel-icon-chooser.c		\
+	panel-icon-chooser.h		\
 	panel-keyfile.c			\
 	panel-keyfile.h			\
 	panel-launch.c			\
@@ -39,6 +43,8 @@ libpanel_util_la_SOURCES=	\
 	panel-session-manager.h		\
 	panel-show.c			\
 	panel-show.h			\
+	panel-xdg.c			\
+	panel-xdg.h			\
 	$(NULL)
 
 -include $(top_srcdir)/git.mk
diff --git a/gnome-panel/libpanel-util/panel-gtk.c b/gnome-panel/libpanel-util/panel-gtk.c
new file mode 100644
index 0000000..097367f
--- /dev/null
+++ b/gnome-panel/libpanel-util/panel-gtk.c
@@ -0,0 +1,83 @@
+/*
+ * panel-gtk.c: various small extensions to gtk+
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz gnome org>
+ */
+
+#include <gtk/gtk.h>
+
+#include "panel-gtk.h"
+
+/*
+ * Originally based on code from panel-properties-dialog.c. This part of the
+ * code was:
+ * Copyright (C) 2005 Vincent Untz <vuntz gnome org>
+ */
+
+static void
+panel_gtk_file_chooser_preview_update (GtkFileChooser *chooser,
+				       gpointer data)
+{
+	GtkWidget *preview;
+	char      *filename;
+	GdkPixbuf *pixbuf;
+	gboolean   have_preview;
+
+	preview = GTK_WIDGET (data);
+	filename = gtk_file_chooser_get_preview_filename (chooser);
+
+	if (filename == NULL)
+		return;
+
+	pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
+	have_preview = (pixbuf != NULL);
+	g_free (filename);
+
+	gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+	if (pixbuf)
+		g_object_unref (pixbuf);
+
+	gtk_file_chooser_set_preview_widget_active (chooser,
+						    have_preview);
+}
+
+void
+panel_gtk_file_chooser_add_image_preview (GtkFileChooser *chooser)
+{
+	GtkFileFilter *filter;
+	GtkWidget     *chooser_preview;
+
+	g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
+
+	filter = gtk_file_filter_new ();
+	gtk_file_filter_add_pixbuf_formats (filter);
+	gtk_file_chooser_set_filter (chooser, filter);
+
+	chooser_preview = gtk_image_new ();
+	gtk_file_chooser_set_preview_widget (chooser, chooser_preview);
+	g_signal_connect (chooser, "update-preview",
+			  G_CALLBACK (panel_gtk_file_chooser_preview_update),
+			  chooser_preview);
+}
+
+/*
+ * End of code coming from panel-properties-dialog.c
+ */
diff --git a/gnome-panel/libpanel-util/panel-gtk.h b/gnome-panel/libpanel-util/panel-gtk.h
index e293420..f0e5715 100644
--- a/gnome-panel/libpanel-util/panel-gtk.h
+++ b/gnome-panel/libpanel-util/panel-gtk.h
@@ -1,7 +1,7 @@
 /*
  * panel-gtk.h: various small extensions to gtk+
  *
- * Copyright (C) 2009 Novell, Inc.
+ * Copyright (C) 2009-2010 Novell, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -31,6 +31,8 @@ G_BEGIN_DECLS
 
 #define PANEL_GTK_BUILDER_GET(builder, name) GTK_WIDGET (gtk_builder_get_object (builder, name))
 
+void panel_gtk_file_chooser_add_image_preview (GtkFileChooser *chooser);
+
 G_END_DECLS
 
 #endif /* PANEL_GTK_H */
diff --git a/gnome-panel/libpanel-util/panel-icon-chooser.c b/gnome-panel/libpanel-util/panel-icon-chooser.c
new file mode 100644
index 0000000..90828e6
--- /dev/null
+++ b/gnome-panel/libpanel-util/panel-icon-chooser.c
@@ -0,0 +1,555 @@
+/*
+ * panel-icon-chooser.c: An icon chooser widget
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz gnome org>
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "panel-gtk.h"
+#include "panel-xdg.h"
+
+#include "panel-icon-chooser.h"
+
+#define PANEL_ICON_CHOOSER_ICON_SIZE GTK_ICON_SIZE_DIALOG
+
+struct _PanelIconChooserPrivate
+{
+	char *fallback_icon_name;
+	char *icon;
+
+	char *icon_theme_dir;
+
+	GtkWidget *image;
+
+	GtkWidget *filechooser;
+};
+
+enum {
+	CHANGED,
+	LAST_SIGNAL
+};
+
+enum {
+	PROP_0,
+	PROP_FALLBACK_ICON,
+	PROP_ICON
+};
+
+static guint panel_icon_chooser_signals[LAST_SIGNAL] = { 0 };
+
+#define PANEL_ICON_CHOOSER_GET_PRIVATE(o)  (PANEL_ICON_CHOOSER (o)->priv)
+
+G_DEFINE_TYPE (PanelIconChooser, panel_icon_chooser, GTK_TYPE_BUTTON)
+
+static void _panel_icon_chooser_clicked (GtkButton *button);
+static void _panel_icon_chooser_style_set (GtkWidget *widget,
+					   GtkStyle  *prev_style);
+static void _panel_icon_chooser_screen_changed (GtkWidget *widget,
+						GdkScreen *prev_screen);
+
+/* gobject stuff */
+
+static GObject *
+panel_icon_chooser_constructor (GType                  type,
+				guint                  n_construct_properties,
+				GObjectConstructParam *construct_properties)
+{
+	GObject          *obj;
+	PanelIconChooser *chooser;
+
+	obj = G_OBJECT_CLASS (panel_icon_chooser_parent_class)->constructor (type,
+									     n_construct_properties,
+									     construct_properties);
+
+	chooser = PANEL_ICON_CHOOSER (obj);
+	gtk_container_add (GTK_CONTAINER (chooser), chooser->priv->image);
+	gtk_widget_show (chooser->priv->image);
+
+	return obj;
+}
+
+static void
+panel_icon_chooser_get_property (GObject    *object,
+				 guint	     prop_id,
+				 GValue	    *value,
+				 GParamSpec *pspec)
+{
+	PanelIconChooser *chooser;
+
+	g_return_if_fail (PANEL_IS_ICON_CHOOSER (object));
+
+	chooser = PANEL_ICON_CHOOSER (object);
+
+	switch (prop_id) {
+	case PROP_FALLBACK_ICON:
+		g_value_set_string (value, panel_icon_chooser_get_fallback_icon_name (chooser));
+		break;
+	case PROP_ICON:
+		g_value_set_string (value, panel_icon_chooser_get_icon (chooser));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+panel_icon_chooser_set_property (GObject      *object,
+				 guint	       prop_id,
+				 const GValue *value,
+				 GParamSpec   *pspec)
+{
+	PanelIconChooser *chooser;
+
+	g_return_if_fail (PANEL_IS_ICON_CHOOSER (object));
+
+	chooser = PANEL_ICON_CHOOSER (object);
+
+	switch (prop_id) {
+	case PROP_FALLBACK_ICON:
+		panel_icon_chooser_set_fallback_icon_name (chooser,
+							   g_value_get_string (value));
+		break;
+	case PROP_ICON:
+		panel_icon_chooser_set_icon (chooser,
+					     g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+panel_icon_chooser_destroy (GtkObject *object)
+{
+	PanelIconChooser *chooser;
+
+	chooser = PANEL_ICON_CHOOSER (object);
+
+	if (chooser->priv->filechooser) {
+		gtk_widget_destroy (chooser->priv->filechooser);
+		chooser->priv->filechooser = NULL;
+	}
+
+	/* remember, destroy can be run multiple times! */
+
+	if (chooser->priv->fallback_icon_name != NULL)
+		g_free (chooser->priv->fallback_icon_name);
+	chooser->priv->fallback_icon_name = NULL;
+
+	if (chooser->priv->icon != NULL)
+		g_free (chooser->priv->icon);
+	chooser->priv->icon = NULL;
+
+	if (chooser->priv->icon_theme_dir != NULL)
+		g_free (chooser->priv->icon_theme_dir);
+	chooser->priv->icon_theme_dir = NULL;
+
+	GTK_OBJECT_CLASS (panel_icon_chooser_parent_class)->destroy (object);
+}
+
+static void
+panel_icon_chooser_class_init (PanelIconChooserClass *class)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+	GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (class);
+	GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (class);
+	GtkButtonClass *gtkbutton_class = GTK_BUTTON_CLASS (class);
+
+	gobject_class->constructor = panel_icon_chooser_constructor;
+	gobject_class->get_property = panel_icon_chooser_get_property;
+	gobject_class->set_property = panel_icon_chooser_set_property;
+
+	gtkobject_class->destroy = panel_icon_chooser_destroy;
+
+	gtkwidget_class->style_set = _panel_icon_chooser_style_set;
+	gtkwidget_class->screen_changed = _panel_icon_chooser_screen_changed;
+
+	gtkbutton_class->clicked = _panel_icon_chooser_clicked;
+
+	g_type_class_add_private (class,
+				  sizeof (PanelIconChooserPrivate));
+
+	panel_icon_chooser_signals[CHANGED] =
+		g_signal_new ("changed",
+			      G_TYPE_FROM_CLASS (gobject_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PanelIconChooserClass,
+					       changed),
+			      NULL,
+			      NULL,
+			      g_cclosure_marshal_VOID__STRING,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_STRING);
+
+	g_object_class_install_property (
+		gobject_class,
+		PROP_FALLBACK_ICON,
+		g_param_spec_string ("fallback-icon-name",
+				     "Fallback Icon Name",
+				     "Icon name of the icon displayed (but not returned) if the current icon does not exit",
+				     NULL,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		gobject_class,
+		PROP_ICON,
+		g_param_spec_string ("icon",
+				     "Icon",
+				     "Icon name or path",
+				     NULL,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+panel_icon_chooser_init (PanelIconChooser *chooser)
+{
+	PanelIconChooserPrivate *priv;
+
+	priv = G_TYPE_INSTANCE_GET_PRIVATE (chooser,
+					    PANEL_TYPE_ICON_CHOOSER,
+					    PanelIconChooserPrivate);
+
+	chooser->priv = priv;
+
+	priv->fallback_icon_name = g_strdup ("gtk-missing-image");
+	priv->icon = NULL;
+	priv->icon_theme_dir = NULL;
+
+	priv->image = gtk_image_new_from_icon_name (priv->fallback_icon_name,
+						    PANEL_ICON_CHOOSER_ICON_SIZE);
+
+	priv->filechooser = NULL;
+}
+
+/* internal code */
+
+static void
+_panel_icon_chooser_update (PanelIconChooser *chooser)
+{
+	if (!chooser->priv->icon) {
+		gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+					      chooser->priv->fallback_icon_name,
+					      PANEL_ICON_CHOOSER_ICON_SIZE);
+
+	} else if (g_path_is_absolute (chooser->priv->icon)) {
+		gboolean fallback;
+
+		fallback = TRUE;
+
+		if (g_file_test (chooser->priv->icon, G_FILE_TEST_EXISTS)) {
+			/* we pass via a pixbuf to force the size we want */
+			GdkPixbuf *pixbuf;
+			int        width, height;
+
+			gtk_icon_size_lookup (PANEL_ICON_CHOOSER_ICON_SIZE,
+					      &width, &height);
+			pixbuf = gdk_pixbuf_new_from_file_at_size (chooser->priv->icon,
+								   width, height,
+								   NULL);
+
+			if (pixbuf) {
+				gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image),
+							   pixbuf);
+				g_object_unref (pixbuf);
+				fallback = FALSE;
+			}
+		}
+
+		if (fallback) {
+			gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+						      chooser->priv->fallback_icon_name,
+						      PANEL_ICON_CHOOSER_ICON_SIZE);
+		}
+
+	} else {
+		/* Note: using GThemedIcon doesn't work well, see bug #606752.
+		 * When we'll remove the alternative code, we won't need the
+		 * style_set/screen_changed handlers anymore.
+		 */
+#if 0
+		GIcon *icon;
+		char  *names[2];
+
+		names[0] = panel_xdg_icon_remove_extension (chooser->priv->icon);
+		names[1] = chooser->priv->fallback_icon_name;
+		icon = g_themed_icon_new_from_names (names, 2);
+
+		gtk_image_set_from_gicon (GTK_IMAGE (chooser->priv->image),
+					  icon,
+					  PANEL_ICON_CHOOSER_ICON_SIZE);
+
+		g_free (names[0]);
+#endif
+		GtkIconTheme *icon_theme;
+		const char   *icon;
+		char         *no_ext;
+
+		no_ext = panel_xdg_icon_remove_extension (chooser->priv->icon);
+
+		icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser)));
+		if (gtk_icon_theme_has_icon (icon_theme, no_ext))
+			icon = no_ext;
+		else
+			icon = chooser->priv->fallback_icon_name;
+
+		gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+					      icon,
+					      PANEL_ICON_CHOOSER_ICON_SIZE);
+
+		g_free (no_ext);
+	}
+}
+
+static char *
+_panel_icon_chooser_find_icon_from_path (PanelIconChooser *chooser,
+					 const char       *path)
+{
+	GdkScreen *screen;
+	char      *icon;
+
+	screen = gtk_widget_get_screen (GTK_WIDGET (chooser));
+
+	icon = panel_xdg_icon_name_from_icon_path (path, screen);
+	if (!icon)
+		icon = g_strdup (path);
+
+	return icon;
+}
+
+static void
+_panel_icon_chooser_file_chooser_response (GtkFileChooser   *filechooser,
+					   gint              response_id,
+					   PanelIconChooser *chooser)
+{
+	if (response_id == GTK_RESPONSE_ACCEPT) {
+		char *path;
+		char *icon;
+
+		path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
+		icon = _panel_icon_chooser_find_icon_from_path (chooser, path);
+		g_free (path);
+
+		panel_icon_chooser_set_icon (chooser, icon);
+		g_free (icon);
+	}
+
+	gtk_widget_destroy (GTK_WIDGET (filechooser));
+}
+
+static void
+_panel_icon_chooser_clicked (GtkButton *button)
+{
+	PanelIconChooser *chooser = PANEL_ICON_CHOOSER (button);
+	GtkWidget        *filechooser;
+	GtkWidget        *toplevel;
+	GtkWindow        *parent;
+	char             *path;
+	gboolean          filechooser_path_set;
+
+	if (chooser->priv->filechooser) {
+		gtk_window_present (GTK_WINDOW (chooser->priv->filechooser));
+		return;
+	}
+
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+	if (GTK_WIDGET_TOPLEVEL (toplevel))
+		parent = GTK_WINDOW (toplevel);
+	else
+		parent = NULL;
+
+	filechooser = gtk_file_chooser_dialog_new (_("Choose an icon"),
+						   parent,
+						   GTK_FILE_CHOOSER_ACTION_OPEN,
+						   GTK_STOCK_CANCEL,
+						   GTK_RESPONSE_CANCEL,
+						   GTK_STOCK_OPEN,
+						   GTK_RESPONSE_ACCEPT,
+						   NULL);
+	panel_gtk_file_chooser_add_image_preview (GTK_FILE_CHOOSER (filechooser));
+
+	path = g_build_filename (DATADIR, "icons", NULL);
+	gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (filechooser),
+					      path, NULL);
+	g_free (path);
+
+	path = g_build_filename (DATADIR, "pixmaps", NULL);
+	gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (filechooser),
+					      path, NULL);
+	g_free (path);
+
+	filechooser_path_set = FALSE;
+
+	if (chooser->priv->icon) {
+		char *path = NULL;
+		if (g_path_is_absolute (chooser->priv->icon)) {
+			path = g_strdup (chooser->priv->icon);
+		} else {
+			GtkIconTheme *icon_theme;
+			GtkIconInfo  *info;
+			char         *no_ext;
+			int           size;
+
+			icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser)));
+			no_ext = panel_xdg_icon_remove_extension (chooser->priv->icon);
+			gtk_icon_size_lookup (PANEL_ICON_CHOOSER_ICON_SIZE,
+					      &size, NULL);
+
+			info = gtk_icon_theme_lookup_icon (icon_theme, no_ext,
+							   size, 0);
+			g_free (no_ext);
+
+			if (info) {
+				path = g_strdup (gtk_icon_info_get_filename (info));
+				gtk_icon_info_free (info);
+			}
+		}
+
+		if (path) {
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser),
+						       path);
+			g_free (path);
+			filechooser_path_set = TRUE;
+		}
+	}
+
+	if (!filechooser_path_set) {
+		char *path;
+		// FIXME? Use current icon theme? But there might not be a lot
+		// of icons there...
+		path = g_build_filename (DATADIR, "icons", NULL);
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser),
+						     path);
+	}
+
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (filechooser), TRUE);
+
+	g_signal_connect (filechooser, "response",
+			  G_CALLBACK (_panel_icon_chooser_file_chooser_response),
+			  chooser);
+
+	chooser->priv->filechooser = filechooser;
+
+	g_signal_connect (G_OBJECT (filechooser), "destroy",
+			  G_CALLBACK (gtk_widget_destroyed),
+			  &chooser->priv->filechooser);
+
+	gtk_widget_show (filechooser);
+}
+
+static void
+_panel_icon_chooser_style_set (GtkWidget *widget,
+			       GtkStyle  *prev_style)
+{
+	PanelIconChooser *chooser;
+
+	chooser = PANEL_ICON_CHOOSER (widget);
+
+	GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->style_set (widget, prev_style);
+
+	_panel_icon_chooser_update (chooser);
+}
+
+static void
+_panel_icon_chooser_screen_changed (GtkWidget *widget,
+				    GdkScreen *prev_screen)
+{
+	PanelIconChooser *chooser;
+
+	chooser = PANEL_ICON_CHOOSER (widget);
+
+	if (GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->screen_changed)
+		GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->screen_changed (widget, prev_screen);
+
+	_panel_icon_chooser_update (chooser);
+}
+
+/* public methods */
+
+GtkWidget  *
+panel_icon_chooser_new (const char  *icon)
+{
+	GtkWidget *chooser;
+
+	chooser = g_object_new (PANEL_TYPE_ICON_CHOOSER,
+			       "icon", icon,
+			       NULL);
+
+	return chooser;
+}
+
+const char *
+panel_icon_chooser_get_fallback_icon_name (PanelIconChooser *chooser)
+{
+	g_return_val_if_fail (PANEL_IS_ICON_CHOOSER (chooser), NULL);
+
+	return chooser->priv->fallback_icon_name;
+}
+
+void
+panel_icon_chooser_set_fallback_icon_name (PanelIconChooser *chooser,
+					   const char       *fallback_icon_name)
+{
+	g_return_if_fail (PANEL_IS_ICON_CHOOSER (chooser));
+
+	if (g_strcmp0 (chooser->priv->fallback_icon_name, fallback_icon_name) == 0)
+		return;
+
+	if (chooser->priv->fallback_icon_name)
+		g_free (chooser->priv->fallback_icon_name);
+	chooser->priv->fallback_icon_name = g_strdup (fallback_icon_name);
+
+	_panel_icon_chooser_update (chooser);
+
+	g_object_notify (G_OBJECT (chooser), "fallback-icon-name");
+}
+
+const char *
+panel_icon_chooser_get_icon (PanelIconChooser *chooser)
+{
+	g_return_val_if_fail (PANEL_IS_ICON_CHOOSER (chooser), NULL);
+
+	return chooser->priv->icon;
+}
+
+void
+panel_icon_chooser_set_icon (PanelIconChooser *chooser,
+			     const char       *icon)
+{
+	g_return_if_fail (PANEL_IS_ICON_CHOOSER (chooser));
+
+	if (g_strcmp0 (chooser->priv->icon, icon) == 0)
+		return;
+
+	if (chooser->priv->icon)
+		g_free (chooser->priv->icon);
+	chooser->priv->icon = g_strdup (icon);
+
+	_panel_icon_chooser_update (chooser);
+
+	g_object_notify (G_OBJECT (chooser), "icon");
+
+	g_signal_emit (G_OBJECT (chooser),
+		       panel_icon_chooser_signals[CHANGED], 0, icon);
+}
diff --git a/gnome-panel/libpanel-util/panel-icon-chooser.h b/gnome-panel/libpanel-util/panel-icon-chooser.h
new file mode 100644
index 0000000..bb20ac6
--- /dev/null
+++ b/gnome-panel/libpanel-util/panel-icon-chooser.h
@@ -0,0 +1,75 @@
+/*
+ * panel-icon-chooser.h: An icon chooser widget
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef PANEL_ICON_CHOOSER_H
+#define PANEL_ICON_CHOOSER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_ICON_CHOOSER			(panel_icon_chooser_get_type ())
+#define PANEL_ICON_CHOOSER(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_ICON_CHOOSER, PanelIconChooser))
+#define PANEL_ICON_CHOOSER_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_ICON_CHOOSER, PanelIconChooserClass))
+#define PANEL_IS_ICON_CHOOSER(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_ICON_CHOOSER))
+#define PANEL_IS_ICON_CHOOSER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_ICON_CHOOSER))
+#define PANEL_ICON_CHOOSER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_ICON_CHOOSER, PanelIconChooserClass))
+
+typedef struct _PanelIconChooser      PanelIconChooser;
+typedef struct _PanelIconChooserClass PanelIconChooserClass;
+
+typedef struct _PanelIconChooserPrivate PanelIconChooserPrivate;
+
+struct _PanelIconChooserClass
+{
+	GtkButtonClass parent_class;
+
+	void (* changed)         (PanelIconChooser *chooser,
+				  const char       *icon);
+};
+
+struct _PanelIconChooser
+{
+	GtkButton parent_instance;
+
+	PanelIconChooserPrivate *priv;
+};
+
+GType       panel_icon_chooser_get_type (void);
+
+GtkWidget  *panel_icon_chooser_new                    (const char  *icon);
+
+const char *panel_icon_chooser_get_fallback_icon_name (PanelIconChooser *chooser);
+
+void        panel_icon_chooser_set_fallback_icon_name (PanelIconChooser *chooser,
+						       const char       *fallback_icon_name);
+
+const char *panel_icon_chooser_get_icon               (PanelIconChooser *chooser);
+
+void        panel_icon_chooser_set_icon               (PanelIconChooser *chooser,
+						       const char       *icon);
+
+G_END_DECLS
+
+#endif /* PANEL_ICON_CHOOSER_H */
diff --git a/gnome-panel/libpanel-util/panel-xdg.c b/gnome-panel/libpanel-util/panel-xdg.c
new file mode 100644
index 0000000..5415a22
--- /dev/null
+++ b/gnome-panel/libpanel-util/panel-xdg.c
@@ -0,0 +1,152 @@
+/*
+ * panel-xdg.c: miscellaneous XDG-related functions.
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz gnome org>
+ */
+
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "panel-xdg.h"
+
+#define DEFAULT_THEME_NAME "hicolor"
+
+/*
+ * Originally based on code from panel-util.c. This part of the code was:
+ * Copyright (C) 2006 Vincent Untz <vuntz gnome org>
+ */
+
+char *
+panel_xdg_icon_remove_extension (const char *icon)
+{
+	char *icon_no_extension;
+	char *p;
+
+	icon_no_extension = g_strdup (icon);
+	p = strrchr (icon_no_extension, '.');
+	if (p &&
+	    (strcmp (p, ".png") == 0 ||
+	     strcmp (p, ".xpm") == 0 ||
+	     strcmp (p, ".svg") == 0)) {
+	    *p = 0;
+	}
+
+	return icon_no_extension;
+}
+
+/*
+ * End of code coming from panel-util.c
+ */
+
+char *
+panel_xdg_icon_name_from_icon_path (const char *path,
+				    GdkScreen  *screen)
+{
+	GtkIconTheme  *theme;
+	GtkSettings   *settings;
+	char          *theme_name;
+	char          *icon;
+	char         **paths;
+	int            n_paths;
+	int            i;
+	GFile         *file;
+
+	/* we look if the icon comes from the current icon theme */
+	if (!screen)
+		screen = gdk_screen_get_default ();
+
+	settings = gtk_settings_get_for_screen (screen);
+	g_object_get (settings,
+		      "gtk-icon-theme-name", &theme_name,
+		      NULL);
+
+	theme = gtk_icon_theme_get_for_screen (screen);
+	gtk_icon_theme_get_search_path (theme, &paths, &n_paths);
+
+	file = g_file_new_for_path (path);
+	icon = NULL;
+
+	for (i = 0; i < n_paths; i++) {
+		GFile *parent;
+		char  *basename;
+
+		parent = g_file_new_for_path (paths[i]);
+
+		if (!g_file_has_prefix (file, parent)) {
+			g_object_unref (parent);
+			continue;
+		}
+
+		basename = g_file_get_basename (parent);
+
+		if (g_strcmp0 (basename, "pixmaps") == 0) {
+			char *relative_path;
+
+			relative_path = g_file_get_relative_path (parent, file);
+
+			/* if the icon is in a subdir of pixmaps, then it's not
+			 * a real icon name */
+			if (!strchr (relative_path, G_DIR_SEPARATOR))
+				icon = panel_xdg_icon_remove_extension (relative_path);
+
+			g_free (relative_path);
+		} else {
+			/* real icon theme; but is it the current one? */
+			GFile    *theme_dir;
+			gboolean  current;
+
+			theme_dir = g_file_get_child (parent, theme_name);
+
+			current = FALSE;
+			if (g_file_has_prefix (file, theme_dir)) {
+				/* it's the current one */
+				current = TRUE;
+			} else {
+				/* it's the default one */
+				g_object_unref (theme_dir);
+				theme_dir = g_file_get_child (parent, DEFAULT_THEME_NAME);
+				current = g_file_has_prefix (file, theme_dir);
+			}
+
+			g_object_unref (theme_dir);
+
+			if (current) {
+				char *buffer;
+
+				buffer = g_file_get_basename (file);
+				icon = panel_xdg_icon_remove_extension (buffer);
+				g_free (buffer);
+			}
+		}
+
+		g_free (basename);
+		g_object_unref (parent);
+
+		break;
+	}
+
+	g_object_unref (file);
+	g_free (theme_name);
+
+	return icon;
+}
diff --git a/gnome-panel/libpanel-util/panel-xdg.h b/gnome-panel/libpanel-util/panel-xdg.h
new file mode 100644
index 0000000..e6322e3
--- /dev/null
+++ b/gnome-panel/libpanel-util/panel-xdg.h
@@ -0,0 +1,39 @@
+/*
+ * panel-xdg.h: miscellaneous XDG-related functions.
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * 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.
+ *
+ * Authors:
+ *	Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef PANEL_XDG_H
+#define PANEL_XDG_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+char *panel_xdg_icon_remove_extension (const char *icon);
+
+char *panel_xdg_icon_name_from_icon_path (const char *path,
+					  GdkScreen  *screen);
+
+G_END_DECLS
+
+#endif /* PANEL_XDG_H */
diff --git a/gnome-panel/menu.c b/gnome-panel/menu.c
index e2ce55a..52fdd57 100644
--- a/gnome-panel/menu.c
+++ b/gnome-panel/menu.c
@@ -32,6 +32,7 @@
 #include <gconf/gconf-client.h>
 
 #include <libpanel-util/panel-keyfile.h>
+#include <libpanel-util/panel-xdg.h>
 
 #include "launcher.h"
 #include "panel-util.h"
@@ -1525,7 +1526,7 @@ create_menuitem (GtkWidget          *menu,
 
 			icon = gmenu_tree_entry_get_icon (entry);
 			if (!g_path_is_absolute (icon)) {
-				icon_no_ext = panel_util_icon_remove_extension (icon);
+				icon_no_ext = panel_xdg_icon_remove_extension (icon);
 				gtk_drag_source_set_icon_name (menuitem,
 							       icon_no_ext);
 				g_free (icon_no_ext);
diff --git a/gnome-panel/panel-ditem-editor.c b/gnome-panel/panel-ditem-editor.c
index e82155c..641a121 100644
--- a/gnome-panel/panel-ditem-editor.c
+++ b/gnome-panel/panel-ditem-editor.c
@@ -30,10 +30,10 @@
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 
-#include <libgnomeui/gnome-icon-entry.h>
-
+#include <libpanel-util/panel-icon-chooser.h>
 #include <libpanel-util/panel-keyfile.h>
 #include <libpanel-util/panel-show.h>
+#include <libpanel-util/panel-xdg.h>
 
 #include "panel-ditem-editor.h"
 #include "panel-icon-names.h"
@@ -74,16 +74,13 @@ struct _PanelDItemEditorPrivate
 	GtkWidget *command_browse_filechooser;
 	GtkWidget *comment_label;
 	GtkWidget *comment_entry;
-	GtkWidget *icon_entry;
+	GtkWidget *icon_chooser;
 
 	GtkWidget *help_button;
 	GtkWidget *revert_button;
 	GtkWidget *close_button;
 	GtkWidget *cancel_button;
 	GtkWidget *ok_button;
-
-	/* the directory of the theme for the icon, see bug #119208 */
-	char *icon_theme_dir;
 };
 
 /* Time in seconds after which we save the file on the disk */
@@ -181,8 +178,8 @@ static void type_combo_changed (PanelDItemEditor *dialog);
 static void response_cb (GtkDialog *dialog,
 			 gint       response_id);
 
-static void setup_icon_entry (PanelDItemEditor *dialog,
-			      const char       *icon_name);
+static void setup_icon_chooser (PanelDItemEditor *dialog,
+			        const char       *icon_name);
 
 static gboolean panel_ditem_editor_save         (PanelDItemEditor *dialog,
 						 gboolean          report_errors);
@@ -276,7 +273,7 @@ panel_ditem_editor_constructor (GType                  type,
 	panel_ditem_editor_setup_ui (dialog);
 
 	if (dialog->priv->new_file)
-		setup_icon_entry (dialog, NULL);
+		setup_icon_chooser (dialog, NULL);
 
 	return obj;
 }
@@ -369,10 +366,6 @@ panel_ditem_editor_destroy (GtkObject *object)
 		g_free (dialog->priv->uri);
 	dialog->priv->uri = NULL;
 
-	if (dialog->priv->icon_theme_dir != NULL)
-		g_free (dialog->priv->icon_theme_dir);
-	dialog->priv->icon_theme_dir = NULL;
-
 	GTK_OBJECT_CLASS (panel_ditem_editor_parent_class)->destroy (object);
 }
 
@@ -636,12 +629,13 @@ panel_ditem_editor_make_ui (PanelDItemEditor *dialog)
 				       priv->name_entry);
 
 	/* Icon */
-	priv->icon_entry = gnome_icon_entry_new ("desktop-icon",
-						 _("Browse icons"));
-	gtk_table_attach (GTK_TABLE (priv->table), priv->icon_entry,
+	priv->icon_chooser = panel_icon_chooser_new (NULL);
+	panel_icon_chooser_set_fallback_icon_name (PANEL_ICON_CHOOSER (priv->icon_chooser),
+						   PANEL_ICON_LAUNCHER);
+	gtk_table_attach (GTK_TABLE (priv->table), priv->icon_chooser,
 			  0, 1, 0, 2,
 			  0, 0, 0, 0);
-	gtk_widget_show (priv->icon_entry);
+	gtk_widget_show (priv->icon_chooser);
 
 	/* Command */
 	priv->command_label = label_new_with_mnemonic ("");
@@ -802,7 +796,7 @@ panel_ditem_editor_setup_ui (PanelDItemEditor *dialog)
 	/* set a focus chain since GTK+ doesn't want to put the icon entry
 	 * as the first widget in the chain */
 	focus_chain = NULL;
-	focus_chain = g_list_prepend (focus_chain, priv->icon_entry);
+	focus_chain = g_list_prepend (focus_chain, priv->icon_chooser);
 	focus_chain = g_list_prepend (focus_chain, priv->type_combo);
 	focus_chain = g_list_prepend (focus_chain, priv->name_entry);
 	focus_chain = g_list_prepend (focus_chain, priv->command_hbox);
@@ -913,7 +907,7 @@ panel_ditem_editor_command_changed (PanelDItemEditor *dialog)
 								    "Icon");
 
 			if (!current || strcmp (icon, current))
-				setup_icon_entry (dialog, icon);
+				setup_icon_chooser (dialog, icon);
 
 			g_free (current);
 			g_free (icon);
@@ -952,30 +946,9 @@ panel_ditem_editor_comment_changed (PanelDItemEditor *dialog)
 }
 
 static void
-panel_ditem_editor_icon_changed (PanelDItemEditor *dialog)
+panel_ditem_editor_icon_changed (PanelDItemEditor *dialog,
+				 const char       *icon)
 {
-	char *icon;
-	char *file;
-
-	file = gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (dialog->priv->icon_entry));
-
-	icon = NULL;
-	if (file != NULL && file[0] != '\0') {
-		/* if the icon_theme_dir is the same as the directory name of
-		 * this icon, then just use the basename as we've just picked
-		 * another icon from the theme.  See bug #119208 */
-		char *dn = g_path_get_dirname (file);
-		if (dialog->priv->icon_theme_dir != NULL &&
-		    strcmp (dn, dialog->priv->icon_theme_dir) == 0) {
-			char *buffer;
-			buffer = g_path_get_basename (file);
-			icon = panel_util_icon_remove_extension (buffer);
-			g_free (buffer);
-		} else
-			icon = g_strdup (file);
-		g_free (dn);
-	}
-
 	if (icon)
 		panel_key_file_set_locale_string (dialog->priv->key_file,
 						  "Icon", icon);
@@ -984,8 +957,7 @@ panel_ditem_editor_icon_changed (PanelDItemEditor *dialog)
 						      "Icon");
 
 	g_signal_emit (G_OBJECT (dialog), ditem_edit_signals[ICON_CHANGED], 0,
-		       file);
-	g_free (file);
+		       icon);
 }
 
 static void
@@ -1069,8 +1041,6 @@ command_browse_button_clicked (PanelDItemEditor *dialog)
 					       GTK_STOCK_OPEN,
 					       GTK_RESPONSE_ACCEPT,
 					       NULL);
-	gtk_window_set_transient_for (GTK_WINDOW (chooser),
-				      GTK_WINDOW (dialog));
 	gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
 
 	g_signal_connect (chooser, "response",
@@ -1101,7 +1071,7 @@ panel_ditem_editor_connect_signals (PanelDItemEditor *dialog)
 	CONNECT_CHANGED (priv->name_entry, panel_ditem_editor_name_changed);
 	CONNECT_CHANGED (priv->command_entry, panel_ditem_editor_command_changed);
 	CONNECT_CHANGED (priv->comment_entry, panel_ditem_editor_comment_changed);
-	CONNECT_CHANGED (priv->icon_entry, panel_ditem_editor_icon_changed);
+	CONNECT_CHANGED (priv->icon_chooser, panel_ditem_editor_icon_changed);
 
 	g_signal_connect_swapped (priv->name_entry, "activate",
 				  G_CALLBACK (panel_ditem_editor_activated),
@@ -1143,7 +1113,7 @@ panel_ditem_editor_block_signals (PanelDItemEditor *dialog)
 	BLOCK_CHANGED (priv->name_entry, panel_ditem_editor_name_changed);
 	BLOCK_CHANGED (priv->command_entry, panel_ditem_editor_command_changed);
 	BLOCK_CHANGED (priv->comment_entry, panel_ditem_editor_comment_changed);
-	BLOCK_CHANGED (priv->icon_entry, panel_ditem_editor_icon_changed);
+	BLOCK_CHANGED (priv->icon_chooser, panel_ditem_editor_icon_changed);
 }
 
 static void
@@ -1164,7 +1134,7 @@ panel_ditem_editor_unblock_signals (PanelDItemEditor *dialog)
 	UNBLOCK_CHANGED (priv->name_entry, panel_ditem_editor_name_changed);
 	UNBLOCK_CHANGED (priv->command_entry, panel_ditem_editor_command_changed);
 	UNBLOCK_CHANGED (priv->comment_entry, panel_ditem_editor_comment_changed);
-	UNBLOCK_CHANGED (priv->icon_entry, panel_ditem_editor_icon_changed);
+	UNBLOCK_CHANGED (priv->icon_chooser, panel_ditem_editor_icon_changed);
 }
 
 static void
@@ -1190,7 +1160,6 @@ panel_ditem_editor_init (PanelDItemEditor *dialog)
 	priv->save_uri = NULL;
 	priv->save_uri_data = NULL;
 	priv->combo_setuped = FALSE;
-	priv->icon_theme_dir = NULL;
 	priv->command_browse_filechooser = NULL;
 
 	panel_ditem_editor_make_ui (dialog);
@@ -1253,11 +1222,10 @@ type_combo_changed (PanelDItemEditor *dialog)
 }
 
 static void
-setup_icon_entry (PanelDItemEditor *dialog,
-		  const char       *icon_name)
+setup_icon_chooser (PanelDItemEditor *dialog,
+		    const char       *icon_name)
 {
 	char *buffer;
-	char *tmpstr;
 
 	if (!icon_name || icon_name[0] == '\0') {
 		if (dialog->priv->type_directory) {
@@ -1269,27 +1237,9 @@ setup_icon_entry (PanelDItemEditor *dialog,
 		buffer = g_strdup (icon_name);
 	}
 
-	tmpstr = panel_find_icon (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (dialog))),
-				  buffer, 48);
-
-	g_free (dialog->priv->icon_theme_dir);
-	if (tmpstr != NULL && buffer != NULL && !g_path_is_absolute (buffer)) {
-		/* this is a themed icon, see bug #119208 */
-		dialog->priv->icon_theme_dir = g_path_get_dirname (tmpstr);
-		/* FIXME: what about theme changes when the dialog is up */
-	} else {
-		/* use the default pixmap directory as the standard
-		 * icon_theme_dir, since the standard directory is themed */
-		g_object_get (G_OBJECT (dialog->priv->icon_entry), "pixmap_subdir",
-			      &(dialog->priv->icon_theme_dir), NULL);
-	}
-
-	/* do this after we set icon_theme_dir since this will launch a
-	 * callback */
-	gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (dialog->priv->icon_entry),
-				       tmpstr);
+	panel_icon_chooser_set_icon (PANEL_ICON_CHOOSER (dialog->priv->icon_chooser),
+				     buffer);
 
-	g_free (tmpstr);
 	g_free (buffer);
 }
 
@@ -1369,7 +1319,7 @@ panel_ditem_editor_sync_display (PanelDItemEditor *dialog)
 
 	/* Icon */
 	buffer = panel_key_file_get_locale_string (key_file, "Icon");
-	setup_icon_entry (dialog, buffer);
+	setup_icon_chooser (dialog, buffer);
 	g_free (buffer);
 
 	if (dialog->priv->save_timeout != 0) {
diff --git a/gnome-panel/panel-properties-dialog.c b/gnome-panel/panel-properties-dialog.c
index 62ea7c0..4cab60c 100644
--- a/gnome-panel/panel-properties-dialog.c
+++ b/gnome-panel/panel-properties-dialog.c
@@ -28,11 +28,11 @@
 
 #include <string.h>
 #include <glib/gi18n.h>
-#include <libgnomeui/gnome-icon-entry.h>
 
 #include <libpanel-util/panel-error.h>
 #include <libpanel-util/panel-glib.h>
 #include <libpanel-util/panel-gtk.h>
+#include <libpanel-util/panel-icon-chooser.h>
 #include <libpanel-util/panel-show.h>
 
 #include "nothing.h"
@@ -40,6 +40,7 @@
 #include "panel-gconf.h"
 #include "panel-util.h"
 #include "panel-globals.h"
+#include "panel-icon-names.h"
 
 typedef struct {
 	PanelToplevel *toplevel;
@@ -55,7 +56,7 @@ typedef struct {
 	GtkWidget     *size_label;
 	GtkWidget     *size_label_pixels;
 	GtkWidget     *icon_align;
-	GtkWidget     *icon_entry;
+	GtkWidget     *icon_chooser;
 	GtkWidget     *icon_label;
   	GtkWidget     *expand_toggle;
 	GtkWidget     *autohide_toggle;
@@ -79,9 +80,6 @@ typedef struct {
 	guint          toplevel_notify;
 	guint          background_notify;
 
-	/* The theme directory of the icon, see bug #119209 */
-	char          *icon_theme_dir;
-
 	/* FIXME: This is a workaround for GTK+ bug #327243 */
 	int            selection_emitted;
 } PanelPropertiesDialog;
@@ -107,9 +105,6 @@ panel_properties_dialog_free (PanelPropertiesDialog *dialog)
 		gtk_widget_destroy (dialog->properties_dialog);
 	dialog->properties_dialog = NULL;
 
-	g_free (dialog->icon_theme_dir);
-	dialog->icon_theme_dir = NULL;
-
 	g_free (dialog);
 }
 
@@ -246,83 +241,42 @@ panel_properties_dialog_setup_size_spin (PanelPropertiesDialog *dialog,
 }
 
 static void
-panel_properties_dialog_icon_changed (PanelPropertiesDialog *dialog,
-				      GnomeIconEntry        *entry)
+panel_properties_dialog_icon_changed (PanelIconChooser      *chooser,
+				      const char            *icon,
+				      PanelPropertiesDialog *dialog)
 {
-	const char *icon = NULL;
-        char       *freeme = NULL;
-
-        icon = gnome_icon_entry_get_filename (entry);
-
-        /* Strip dir from the icon path if in the icon
-         * theme directory.  See bug #119209
-         */
-        if (icon && g_path_is_absolute (icon)) {
-                char *dir;
-
-                dir = g_path_get_dirname (icon);
-
-                if (dir && dialog->icon_theme_dir && strcmp (dir, dialog->icon_theme_dir) == 0)
-                        icon = freeme = g_path_get_basename (icon);
-
-                g_free (dir);
-        }
-
         panel_profile_set_attached_custom_icon (dialog->toplevel, icon);
-
-        g_free (freeme);
 }
 
 static void
-panel_properties_dialog_setup_icon_entry (PanelPropertiesDialog *dialog,
-					  GtkBuilder            *gui)
+panel_properties_dialog_setup_icon_chooser (PanelPropertiesDialog *dialog,
+					    GtkBuilder            *gui)
 {
 	char *custom_icon;
 
 	dialog->icon_align = PANEL_GTK_BUILDER_GET (gui, "icon_align");
 	g_return_if_fail (dialog->icon_align != NULL);
 
-	dialog->icon_entry = gnome_icon_entry_new ("panel-drawer-icon",
-						   _("Browse icons"));
-	gtk_widget_show (dialog->icon_entry);
+	dialog->icon_chooser = panel_icon_chooser_new (NULL);
+	panel_icon_chooser_set_fallback_icon_name (PANEL_ICON_CHOOSER (dialog->icon_chooser),
+						   PANEL_ICON_DRAWER);
+	gtk_widget_show (dialog->icon_chooser);
 	gtk_container_add (GTK_CONTAINER (dialog->icon_align),
-			   dialog->icon_entry);
+			   dialog->icon_chooser);
 
 	dialog->icon_label = PANEL_GTK_BUILDER_GET (gui, "icon_label");
 	g_return_if_fail (dialog->icon_label != NULL);
 
-	dialog->icon_theme_dir = NULL;
 	custom_icon = panel_profile_get_attached_custom_icon (dialog->toplevel);
-	if (custom_icon != NULL &&
-	    ! g_path_is_absolute (custom_icon)) {
-		/* if the icon is not absolute path name it comes from the
-		   theme, and as such we wish to store the theme directory
-		   where it comes from.  See bug #119209 */
-		char *icon;
-		
-		icon = panel_find_icon (gtk_icon_theme_get_default (),
-					custom_icon, 48);
-		if (icon != NULL)
-			dialog->icon_theme_dir = g_path_get_dirname (icon);
-
-		g_free (custom_icon);
-		custom_icon = icon;
-	}
-	gnome_icon_entry_set_filename (GNOME_ICON_ENTRY (dialog->icon_entry), custom_icon);
+	panel_icon_chooser_set_icon (PANEL_ICON_CHOOSER (dialog->icon_chooser),
+				     custom_icon);
 	g_free (custom_icon);
 
-	if (dialog->icon_theme_dir == NULL) {
-		/* use the default pixmap directory as the standard icon_theme_dir,
-		 * since the standard directory is themed */
-		g_object_get (G_OBJECT (dialog->icon_entry), "pixmap_subdir",
-			      &(dialog->icon_theme_dir), NULL);
-	}
-
-	g_signal_connect_swapped (dialog->icon_entry, "changed",
-				  G_CALLBACK (panel_properties_dialog_icon_changed), dialog);
+	g_signal_connect (dialog->icon_chooser, "changed",
+			  G_CALLBACK (panel_properties_dialog_icon_changed), dialog);
 
 	if (!panel_profile_is_writable_attached_custom_icon (dialog->toplevel)) {
-		gtk_widget_set_sensitive (dialog->icon_entry, FALSE);
+		gtk_widget_set_sensitive (dialog->icon_chooser, FALSE);
 		gtk_widget_set_sensitive (dialog->icon_label, FALSE);
 		gtk_widget_show (dialog->writability_warn_general);
 	}
@@ -416,53 +370,13 @@ panel_properties_dialog_image_changed (PanelPropertiesDialog *dialog)
 }
 
 static void
-panel_properties_dialog_chooser_preview_update (GtkFileChooser *file_chooser,
-						gpointer data)
-{
-	GtkWidget *preview;
-	char      *filename;
-	GdkPixbuf *pixbuf;
-	gboolean   have_preview;
-
-	preview = GTK_WIDGET (data);
-	filename = gtk_file_chooser_get_preview_filename (file_chooser);
-
-	if (filename == NULL)
-		return;
-
-	pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
-	have_preview = (pixbuf != NULL);
-	g_free (filename);
-
-	gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
-	if (pixbuf)
-		g_object_unref (pixbuf);
-
-	gtk_file_chooser_set_preview_widget_active (file_chooser,
-						    have_preview);
-}
-
-static void
 panel_properties_dialog_setup_image_chooser (PanelPropertiesDialog *dialog,
 					     GtkBuilder            *gui)
 {
-	GtkFileFilter *filter;
-	GtkWidget     *chooser_preview;
-	char          *image;
+	char *image;
 
 	dialog->image_chooser = PANEL_GTK_BUILDER_GET (gui, "image_chooser");
-
-	filter = gtk_file_filter_new ();
-	gtk_file_filter_add_pixbuf_formats (filter);
-	gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog->image_chooser),
-				     filter);
-
-	chooser_preview = gtk_image_new ();
-	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog->image_chooser),
-					     chooser_preview);
-	g_signal_connect (dialog->image_chooser, "update-preview",
-			  G_CALLBACK (panel_properties_dialog_chooser_preview_update),
-			  chooser_preview);
+	panel_gtk_file_chooser_add_image_preview (GTK_FILE_CHOOSER (dialog->image_chooser));
 
 	image = panel_profile_get_background_image (dialog->toplevel);
 
@@ -915,7 +829,7 @@ panel_properties_dialog_remove_orientation_combo (PanelPropertiesDialog *dialog)
 }
 
 static void
-panel_properties_dialog_remove_icon_entry (PanelPropertiesDialog *dialog)
+panel_properties_dialog_remove_icon_chooser (PanelPropertiesDialog *dialog)
 {
 	GtkContainer *container = GTK_CONTAINER (dialog->general_table);
 
@@ -924,7 +838,7 @@ panel_properties_dialog_remove_icon_entry (PanelPropertiesDialog *dialog)
 
 	dialog->icon_label = NULL;
 	dialog->icon_align = NULL;
-	dialog->icon_entry = NULL;
+	dialog->icon_chooser = NULL;
 
 	gtk_table_resize (GTK_TABLE (dialog->general_table), 3, 2);
 }
@@ -946,7 +860,7 @@ panel_properties_dialog_update_for_attached (PanelPropertiesDialog *dialog,
 					     gboolean               attached)
 {
 	if (!attached)
-		panel_properties_dialog_remove_icon_entry (dialog);
+		panel_properties_dialog_remove_icon_chooser (dialog);
 	else {
 		gtk_window_set_title (GTK_WINDOW (dialog->properties_dialog),
 				      _("Drawer Properties"));
@@ -987,7 +901,7 @@ panel_properties_dialog_new (PanelToplevel *toplevel,
 
 	panel_properties_dialog_setup_orientation_combo  (dialog, gui);
 	panel_properties_dialog_setup_size_spin          (dialog, gui);
-	panel_properties_dialog_setup_icon_entry         (dialog, gui);
+	panel_properties_dialog_setup_icon_chooser       (dialog, gui);
 	panel_properties_dialog_setup_expand_toggle      (dialog, gui);
 	panel_properties_dialog_setup_autohide_toggle    (dialog, gui);
 	panel_properties_dialog_setup_hidebuttons_toggle (dialog, gui);
diff --git a/gnome-panel/panel-util.c b/gnome-panel/panel-util.c
index 3b8c608..4dfec4c 100644
--- a/gnome-panel/panel-util.c
+++ b/gnome-panel/panel-util.c
@@ -32,6 +32,7 @@
 #include <libpanel-util/panel-error.h>
 #include <libpanel-util/panel-glib.h>
 #include <libpanel-util/panel-keyfile.h>
+#include <libpanel-util/panel-xdg.h>
 
 #include "applet.h"
 #include "nothing.h"
@@ -241,24 +242,6 @@ panel_uri_exists (const char *uri)
 }
 
 char *
-panel_util_icon_remove_extension (const char *icon)
-{
-	char *icon_no_extension;
-	char *p;
-
-	icon_no_extension = g_strdup (icon);
-	p = strrchr (icon_no_extension, '.');
-	if (p &&
-	    (strcmp (p, ".png") == 0 ||
-	     strcmp (p, ".xpm") == 0 ||
-	     strcmp (p, ".svg") == 0)) {
-	    *p = 0;
-	}
-
-	return icon_no_extension;
-}
-
-char *
 panel_find_icon (GtkIconTheme  *icon_theme,
 		 const char    *icon_name,
 		 gint           size)
@@ -287,7 +270,7 @@ panel_find_icon (GtkIconTheme  *icon_theme,
 
 	/* This is needed because some .desktop files have an icon name *and*
 	 * an extension as icon */
-	icon_no_extension = panel_util_icon_remove_extension (icon_name);
+	icon_no_extension = panel_xdg_icon_remove_extension (icon_name);
 
 	info = gtk_icon_theme_lookup_icon (icon_theme, icon_no_extension,
 					   size, 0);
diff --git a/gnome-panel/panel-util.h b/gnome-panel/panel-util.h
index 49b03f3..8551d95 100644
--- a/gnome-panel/panel-util.h
+++ b/gnome-panel/panel-util.h
@@ -25,7 +25,6 @@ void            panel_lock_screen_action           (GdkScreen    *screen,
                                                     const char   *action);
 gboolean        panel_lock_screen_action_available (const char   *action);
 
-char *          panel_util_icon_remove_extension (const char *icon);
 char *          panel_find_icon         (GtkIconTheme  *icon_theme,
 					 const char    *icon_name,
 					 int            size);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]