/*
 * xfce-appmenuitem - a GtkImageMenuItem subclass that handles menu
 * items that are intended to represent applications
 *
 * Copyright (c) 2004-2007 Brian Tarricone <bjt23@cornell.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>

#include <gtk/gtkaccellabel.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkstyle.h>
#include <gtk/gtkversion.h>

#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/icons.h>
#include <libxfcegui4/xfce-appmenuitem.h>
#include <libxfcegui4/xfce-internals.h>
#include <libxfcegui4/xfce-exec.h>

struct _XfceAppMenuItemPriv {
    gchar *name;
    gchar *command;
    gboolean needs_term;
    gboolean snotify;
    gchar *icon_name;
    gchar *icon_path;
    gboolean icon_set;
    
    gchar *command_expanded;
    gchar *dot_desktop_filename;
    
    GtkWidget *accel_label;
};

enum {
    PROP_ZERO = 0,
    PROP_TERM,
    PROP_CMD,
    PROP_ICON,
    PROP_LABEL,
    PROP_SNOTIFY,
    PROP_USE_UNDERLINE,
};

static void xfce_app_menu_item_class_init(XfceAppMenuItemClass *klass);
static void xfce_app_menu_item_init(XfceAppMenuItem *app_menu_item);
static void xfce_app_menu_item_set_property(GObject *object,
                                            guint prop_id,
                                            const GValue *value,
                                            GParamSpec *pspec);
static void xfce_app_menu_item_get_property(GObject *object,
                                            guint prop_id,
                                            GValue *value,
                                            GParamSpec *pspec);
static void xfce_app_menu_item_size_request(GtkWidget *widget,
                                            GtkRequisition *req);
static void xfce_app_menu_item_finalize(GObject *object);

static void _command_activate_cb(GtkMenuItem *menu_item,
                                 gpointer user_data);

static gint _xfce_app_menu_item_icon_size = -1;


G_DEFINE_TYPE(XfceAppMenuItem, xfce_app_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)


static void
_style_set_cb(GtkWidget *w, GtkStyle *prev_style, gpointer user_data)
{
    GtkStyle *style;
    GList *children, *l;
    
    style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
            "GtkMenuItem", "GtkMenuItem", GTK_TYPE_IMAGE_MENU_ITEM);
    children = gtk_container_get_children(GTK_CONTAINER(w));
    for(l = children; l; l = l->next) {
        if(GTK_IS_WIDGET(l->data))
            gtk_widget_set_style(GTK_WIDGET(l->data), style);
    }
    g_list_free(children);
}

static void
_expand_percent_vars(XfceAppMenuItem *app_menu_item)
{
    GString *newstr;
    gchar *p;
    
    g_return_if_fail(app_menu_item->priv->command);
    
    newstr = g_string_sized_new(strlen(app_menu_item->priv->command) + 1);
    
    for(p = app_menu_item->priv->command; *p; ++p) {
        if('%' == *p) {
            ++p;
            switch(*p) {
                /* we don't care about these since we aren't passing filenames */
                case 'f':
                case 'F':
                case 'u':
                case 'U':
                /* these are all deprecated */
                case 'd':
                case 'D':
                case 'n':
                case 'N':
                case 'v':
                case 'm':
                    break;
                
                case 'i':
                    if(G_LIKELY(app_menu_item->priv->icon_name)) {
                        gchar *str = g_shell_quote(app_menu_item->priv->icon_name);
                        g_string_append(newstr, "--icon ");
                        g_string_append(newstr, str);
                        g_free(str);
                    }
                    break;
                
                case 'c':
                    if(G_LIKELY(app_menu_item->priv->name)) {
                        gchar *name_locale, *str;
                        gsize bread = 0;
                        GError *error = NULL;
                        
                        name_locale = g_locale_from_utf8(app_menu_item->priv->name,
                                                         -1, &bread, NULL,
                                                         &error);
                        if(name_locale) {
                            str = g_shell_quote(name_locale);
                            g_string_append(newstr, str);
                            g_free(str);
                            g_free(name_locale);
                        } else {
                            g_warning("Invalid UTF-8 in Name at byte %u: %s",
                                      (guint)bread, error->message);
                        }
                    }
                    break;
                
                case 'k':
                    if(app_menu_item->priv->dot_desktop_filename) {
                        gchar *str = g_shell_quote(app_menu_item->priv->dot_desktop_filename);
                        g_string_append(newstr, str);
                        g_free(str);
                    }
                    break;
                
                case '%':
                    g_string_append_c(newstr, '%');
                    break;
                
                default:
                    g_warning("Invalid field code in Exec line: %%%c", *p);
                    break;
            }
        } else
            g_string_append_c(newstr, *p);
    }
        
    app_menu_item->priv->command_expanded = newstr->str;
    g_string_free(newstr, FALSE);
}

static void
_command_activate_cb(GtkMenuItem *menu_item, gpointer user_data)
{
    XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(menu_item);
    GdkScreen *gscreen;
    
    g_return_if_fail(app_menu_item && app_menu_item->priv->command);
    
    /* we do this here instead of in _new*() for 2 reasons:
     *   1. menu items that never get activated won't slow us down for no
     *      reason.
     *   2. we can't guarantee that the icon name or whatever (which can
     *      influence the result of _expand_percent_vars()) has been set
     *      when the command is first set.
     */
    if(!app_menu_item->priv->command_expanded)
        _expand_percent_vars(app_menu_item);
    
    gscreen = gtk_widget_get_screen(GTK_WIDGET(menu_item));
    if(!xfce_exec_on_screen(gscreen, app_menu_item->priv->command_expanded,
                            app_menu_item->priv->needs_term,
                            app_menu_item->priv->snotify, NULL))
    {
        g_warning("XfceAppMenuItem: unable to spawn %s\n",
                  app_menu_item->priv->command_expanded);
    }
}

static void
xfce_app_menu_item_class_init(XfceAppMenuItemClass *klass)
{
    GObjectClass *gobject_class = (GObjectClass *)klass;
    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;

    /* be sure to initialize the library's i18n support first */
    _xfce_i18n_init();
    
    g_type_class_add_private(klass, sizeof(XfceAppMenuItemPriv));
    
    widget_class->size_request = xfce_app_menu_item_size_request;
    
    gobject_class->finalize = xfce_app_menu_item_finalize;
    gobject_class->set_property = xfce_app_menu_item_set_property;
    gobject_class->get_property = xfce_app_menu_item_get_property;
    
    g_object_class_install_property(gobject_class, PROP_TERM,
            g_param_spec_boolean("needs_term", _("Needs terminal"), 
                    _("Whether or not the command needs a terminal to execute"),
                    FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    g_object_class_install_property(gobject_class, PROP_CMD,
            g_param_spec_string("command", _("Command"),
                    _("The command to run when the item is clicked"),
                    NULL, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    g_object_class_install_property(gobject_class, PROP_ICON,
            g_param_spec_string("icon_name", _("Icon name"),
                    _("The name of the themed icon to display next to the item"),
                    NULL, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    g_object_class_install_property(gobject_class, PROP_LABEL,
            g_param_spec_string("label", _("Label"),
                                _("The label displayed in the item"),
                                NULL, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    g_object_class_install_property(gobject_class, PROP_SNOTIFY,
            g_param_spec_boolean("snotify", _("Startup notification"),
                                 _("Whether or not the app supports startup notification"),
                                 FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    g_object_class_install_property(gobject_class, PROP_USE_UNDERLINE,
            g_param_spec_boolean("use-underline", _("Use underline"),
                                 _("Whether or not to use an underscore in the label as a keyboard mnemonic"),
                                 FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE));
    
    if(-1 == _xfce_app_menu_item_icon_size) {
        gtk_icon_size_lookup(GTK_ICON_SIZE_MENU,
                             &_xfce_app_menu_item_icon_size, NULL);
    }
}

static void
xfce_app_menu_item_init(XfceAppMenuItem *app_menu_item)
{
    GtkWidget *accel_label;
    
    app_menu_item->priv = G_TYPE_INSTANCE_GET_PRIVATE(app_menu_item,
                                                      XFCE_TYPE_APP_MENU_ITEM,
                                                      XfceAppMenuItemPriv);
    
    gtk_widget_add_events(GTK_WIDGET(app_menu_item),
                          GDK_STRUCTURE_MASK | GDK_SUBSTRUCTURE_MASK
                          | GDK_VISIBILITY_NOTIFY_MASK);
    
    g_signal_connect(G_OBJECT(app_menu_item), "activate",
            G_CALLBACK(_command_activate_cb), NULL);
    g_signal_connect(G_OBJECT(app_menu_item), "style-set",
            G_CALLBACK(_style_set_cb), NULL);
    
    app_menu_item->priv->accel_label = accel_label = gtk_accel_label_new("");
    gtk_misc_set_alignment(GTK_MISC(accel_label), 0.0, 0.5);
    
    gtk_container_add(GTK_CONTAINER(app_menu_item), accel_label);
    gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(accel_label),
            GTK_WIDGET(app_menu_item));
    gtk_widget_show(accel_label);
}

static void
xfce_app_menu_item_set_property(GObject *object, guint prop_id,
        const GValue *value, GParamSpec *pspec)
{
    XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(object);
    
    switch(prop_id) {
        case PROP_TERM:
            xfce_app_menu_item_set_needs_term(app_menu_item,
                                              g_value_get_boolean(value));
            break;
        case PROP_CMD:
            xfce_app_menu_item_set_command(app_menu_item,
                                           g_value_get_string(value));
            break;
        case PROP_ICON:
            xfce_app_menu_item_set_icon_name(app_menu_item,
                                             g_value_get_string(value));
            break;
        case PROP_LABEL:
            xfce_app_menu_item_set_name(app_menu_item,
                                        g_value_get_string(value));
            break;
        case PROP_SNOTIFY:
            xfce_app_menu_item_set_startup_notification(app_menu_item,
                                                        g_value_get_boolean(value));
            break;
        case PROP_USE_UNDERLINE:
            gtk_label_set_use_underline(GTK_LABEL(app_menu_item->priv->accel_label),
                                        g_value_get_boolean(value));
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
            break;
    }
}

static void
xfce_app_menu_item_get_property(GObject *object, guint prop_id, GValue *value,
        GParamSpec *pspec)
{
    XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(object);
    
    switch(prop_id) {
        case PROP_TERM:
            g_value_set_boolean(value, app_menu_item->priv->needs_term);
            break;
        case PROP_CMD:
            g_value_set_string(value, app_menu_item->priv->command);
            break;
        case PROP_ICON:
            g_value_set_string(value, app_menu_item->priv->icon_name);
            break;
        case PROP_LABEL:
            g_value_set_string(value, app_menu_item->priv->name);
            break;
        case PROP_SNOTIFY:
            g_value_set_boolean(value, app_menu_item->priv->snotify);
            break;
        case PROP_USE_UNDERLINE:
            g_value_set_boolean(value,
                                gtk_label_get_use_underline(GTK_LABEL(app_menu_item->priv->accel_label)));
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
            break;
    }
}

static void
xfce_app_menu_item_size_request(GtkWidget *widget,
                                GtkRequisition *req)
{

    XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(widget);
    GtkWidget *img;
    GdkPixbuf *pix;
    
    if(app_menu_item->priv->icon_path && !app_menu_item->priv->icon_set) {
        img = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(app_menu_item));
        if(!img) {
            img = gtk_image_new();
            gtk_widget_show(img);
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(app_menu_item), img);
        }
        
        pix = gdk_pixbuf_new_from_file_at_size(app_menu_item->priv->icon_path,
                                               _xfce_app_menu_item_icon_size,
                                               _xfce_app_menu_item_icon_size,
                                               NULL);
        
        if(pix) {
            gtk_image_set_from_pixbuf(GTK_IMAGE(img), pix);
            g_object_unref(G_OBJECT(pix));
            app_menu_item->priv->icon_set = TRUE;
        } else {
            g_free(app_menu_item->priv->icon_path);
            app_menu_item->priv->icon_path = NULL;
        }
    }
    
    /* let the parent do its magic */
    GTK_WIDGET_CLASS(xfce_app_menu_item_parent_class)->size_request(widget,
                                                                    req);
}

static void
xfce_app_menu_item_finalize(GObject *object)
{
    XfceAppMenuItem *app_menu_item = XFCE_APP_MENU_ITEM(object);
    
    g_return_if_fail(app_menu_item != NULL);
    
    g_free(app_menu_item->priv->name);
    g_free(app_menu_item->priv->command);
    g_free(app_menu_item->priv->icon_name);
    g_free(app_menu_item->priv->icon_path);
    g_free(app_menu_item->priv->command_expanded);
    g_free(app_menu_item->priv->dot_desktop_filename);
    
    G_OBJECT_CLASS(xfce_app_menu_item_parent_class)->finalize(object);
}

/**
 * xfce_app_menu_item_new:
 * @returns: A new #XfceAppMenuItem.
 *
 * Creates a new #XfceAppMenuItem with an empty label.
 *
 * Since 4.1
 **/
GtkWidget *
xfce_app_menu_item_new()
{
    return g_object_new(XFCE_TYPE_APP_MENU_ITEM, NULL);
}

/**
 * xfce_app_menu_item_new_with_label:
 * @label: The text of the menu item.
 * @returns: A new #XfceAppMenuItem.
 *
 * Creates a new #XfceAppMenuItem containing a label.
 *
 * Since 4.1
 **/
GtkWidget *
xfce_app_menu_item_new_with_label(const gchar *label)
{
    return g_object_new(XFCE_TYPE_APP_MENU_ITEM,
                        "label", label,
                        NULL);
}

/**
 * xfce_app_menu_item_new_with_mnemonic:
 * @label: The text of the menu item, with an underscore in front of the
 *         mnemonic character.
 * @returns: A new #XfceAppMenuItem.
 *
 * Creates a new #XfceAppMenuItem containing a label. The label
 * will be created using gtk_label_new_with_mnemonic(), so underscores
 * in @label indicate the mnemonic for the menu item.
 *
 * Since 4.1
 **/
GtkWidget *
xfce_app_menu_item_new_with_mnemonic(const gchar *label)
{
    return g_object_new(XFCE_TYPE_APP_MENU_ITEM,
                        "label", label,
                        "use-underline", TRUE,
                        NULL);
}

/**
 * xfce_app_menu_item_new_with_command:
 * @label: The text of the menu item.
 * @command: The command associated with the menu item.
 * @returns: A new #XfceAppMenuItem.
 *
 * Creates a new #XfceAppMenuItem containing a label. The item's @activate
 * signal will be connected such that @command will run when it is clicked.
 *
 * Since 4.1
 **/
GtkWidget *
xfce_app_menu_item_new_with_command(const gchar *label, const gchar *command)
{
    return g_object_new(XFCE_TYPE_APP_MENU_ITEM,
                        "label", label,
                        "command", command,
                        NULL);
}

/**
 * xfce_app_menu_item_new_full:
 * @label: The text of the menu item.
 * @command: The command associated with the menu item.
 * @icon_filename: The filename of the icon.
 * @needs_term: TRUE if the application needs a terminal, FALSE if not.
 * @snotify: TRUE if the application supports startup notification, FALSE if
 *           not.
 * @returns: A new #XfceAppMenuItem.
 *
 * Single-function interface to create an #XfceAppMenuItem.  Has the effect of
 * calling xfce_app_menu_item_new_with_label() followed by all the
 * xfce_app_menu_item_set_*() functions.
 *
 * Since 4.1
 **/
GtkWidget *xfce_app_menu_item_new_full(const gchar *label, const gchar *command,
        const gchar *icon_filename, gboolean needs_term, gboolean snotify)
{
    return g_object_new(XFCE_TYPE_APP_MENU_ITEM,
                        "label", label,
                        "command", command,
                        "icon-name", icon_filename,
                        "needs-term", needs_term,
                        "snotify", snotify,
                        NULL);
}

/**
 * xfce_app_menu_item_new_from_desktop_entry:
 * @entry: An #XfceDesktopEntry describing the menu item to create.
 * @show_icon: Sets whether or not to show an icon in the menu item.
 * @returns: A new #XfceAppMenuItem, or %NULL on error.
 *
 * Creates a new #XfceAppMenuItem using parameters from the application
 * specified in a #XfceDesktopEntry object. This has the effect of calling
 * xfce_app_menu_item_new_with_command(), xfce_app_menu_item_set_needs_term(),
 * xfce_app_menu_item_set_icon_name(), and
 * xfce_app_menu_item_set_startup_notification().
 *
 * Since 4.1
 **/
GtkWidget *
xfce_app_menu_item_new_from_desktop_entry(XfceDesktopEntry *entry,
        gboolean show_icon)
{
    XfceAppMenuItem *app_menu_item;
    gchar *name = NULL, *cmd = NULL, *icon = NULL, *snotify = NULL;
    gchar *onlyshowin = NULL, *categories = NULL, *term = NULL;
    const gchar *dfile;
    
    g_return_val_if_fail(XFCE_IS_DESKTOP_ENTRY(entry), NULL);
    
    if(xfce_desktop_entry_get_string(entry, "OnlyShowIn", FALSE, &onlyshowin)
       || xfce_desktop_entry_get_string(entry, "Categories", FALSE,
                                        &categories))
    {
        if((onlyshowin && strstr(onlyshowin, "XFCE;"))
           || (categories && strstr(categories, "X-XFCE;")))
        {
            if(xfce_desktop_entry_has_translated_entry(entry, "GenericName")) {
                xfce_desktop_entry_get_string(entry, "GenericName", TRUE,
                                              &name);
            } else if(xfce_desktop_entry_has_translated_entry(entry, "Name")) {
                xfce_desktop_entry_get_string(entry, "Name", TRUE, &name);
            } else {
                xfce_desktop_entry_get_string(entry, "GenericName", FALSE,
                                              &name);
            }
        } else if(onlyshowin) {
            g_free(onlyshowin);
            g_free(categories);
            return NULL;
        }
        
        g_free(onlyshowin);
        g_free(categories);
    }
    
    app_menu_item = XFCE_APP_MENU_ITEM(xfce_app_menu_item_new());
    
    if(!name && !xfce_desktop_entry_get_string(entry, "Name", TRUE, &name)) {
        gchar *tmp, *tmp1;
        
        tmp = g_filename_to_utf8(xfce_desktop_entry_get_file(entry), -1,
                                 NULL, NULL, NULL);
        if(!tmp)
            tmp = g_strdup(xfce_desktop_entry_get_file(entry));
            
        if((tmp1 = g_strrstr(tmp, ".desktop")))
            *tmp1 = 0;
        if((tmp1 = g_strrstr(tmp, "/")))
            tmp1++;
        else
            tmp1 = name;
        name = g_strdup(tmp1);
        g_free(tmp);
    }
    
    app_menu_item->priv->name = name;
    
    if(!g_utf8_validate(name, -1, NULL)) {
        g_warning("XfceAppMenuItem: 'name' failed utf8 validation for .desktop file '%s'",
                xfce_desktop_entry_get_file(entry));
        gtk_widget_destroy(GTK_WIDGET(app_menu_item));
        return NULL;
    }
    
    gtk_label_set_text(GTK_LABEL(app_menu_item->priv->accel_label),
                       app_menu_item->priv->name);
    
    if(xfce_desktop_entry_get_string(entry, "Terminal", TRUE, &term)) {
        app_menu_item->priv->needs_term = (*term == '1'
                                           || !g_ascii_strcasecmp(term,
                                                                  "true"));
        g_free(term);
    }
    
    if(xfce_desktop_entry_get_string(entry, "StartupNotify", TRUE, &snotify)) {
        app_menu_item->priv->snotify = (*snotify == '1'
                                        || !g_ascii_strcasecmp(snotify,
                                                               "true"));
        g_free(snotify);
    }
    
    if(!xfce_desktop_entry_get_string(entry, "Exec", TRUE, &cmd)) {
        gtk_widget_destroy(GTK_WIDGET(app_menu_item));
        return NULL;
    }

    /* remove quotes around the command (yes, people do that!) */
    if(cmd[0] == '"') {
        gint i;
        
        for(i = 1; cmd[i - 1] != '\0'; ++i) {
            if (cmd[i] != '"')
                cmd[i-1] = cmd[i];
            else {
                cmd[i-1] = cmd[i] = ' ';
                break;
            }
        }
    }

    app_menu_item->priv->command = xfce_expand_variables(cmd, NULL);
    g_free(cmd);
    
    if(show_icon) {
        xfce_desktop_entry_get_string(entry, "Icon", TRUE, &icon);
        if(icon) {
            xfce_app_menu_item_set_icon_name(app_menu_item, icon);
            g_free(icon);
        }
    }
    
    dfile = xfce_desktop_entry_get_file(entry);
    if(dfile)
        app_menu_item->priv->dot_desktop_filename = g_strdup(dfile);
    
    return GTK_WIDGET(app_menu_item);
}

/**
 * xfce_app_menu_item_set_name:
 * @app_menu_item: An #XfceAppMenuItem.
 * @name: The name of the menu item the menu item.
 *
 * Sets @name as the displayed name of the #XfceAppMenuItem.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_name(XfceAppMenuItem *app_menu_item, const gchar *name)
{
    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
    
    if(app_menu_item->priv->name)
        g_free(app_menu_item->priv->name);
    
    app_menu_item->priv->name = g_strdup(name);
    gtk_label_set_text(GTK_LABEL(app_menu_item->priv->accel_label), name);
}

/**
 * xfce_app_menu_item_set_icon_name:
 * @app_menu_item: an #XfceAppMenuItem.
 * @filename: The filename of the icon.
 *
 * Sets the icon of the #XfceAppMenuItem using the specified filename.  If
 * the filename doesn't have a full pathname, standard icon search paths
 * will be used.  If the filename doesn't have an extension, the best image
 * format found (if any) will be used.  If there is already an icon set, the
 * current one is freed, regardless if the icon is found or not.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_icon_name(XfceAppMenuItem *app_menu_item,
        const gchar *filename)
{
    GtkWidget *img;
    
    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));

    if(app_menu_item->priv->icon_name)
        g_free(app_menu_item->priv->icon_name);

    if(!filename) {
        app_menu_item->priv->icon_name = NULL;
        return;
    }

    app_menu_item->priv->icon_name = g_strdup(filename);
    app_menu_item->priv->icon_path = xfce_themed_icon_lookup(filename,
                                                _xfce_app_menu_item_icon_size);
    
    img = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(app_menu_item));
    if(img)
        gtk_image_set_from_pixbuf(GTK_IMAGE(img), NULL);
}

/**
 * xfce_app_menu_item_set_command:
 * @app_menu_item: An #XfceAppMenuItem.
 * @command: The command to associate with the menu item.
 *
 * Sets @command as the command run when the #XfceAppMenuItem is clicked.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_command(XfceAppMenuItem *app_menu_item,
        const gchar *command)
{
    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
    
    if(app_menu_item->priv->command)
        g_free(app_menu_item->priv->command);

    app_menu_item->priv->command = xfce_expand_variables(command, NULL);
}

/**
 * xfce_app_menu_item_set_needs_term:
 * @app_menu_item: An #XfceAppMenuItem.
 * @needs_term: TRUE if the application needs a terminal, FALSE if not.
 *
 * Sets whether or not the command executed by this #XfceAppMenuItem requires
 * a terminal window to run.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_needs_term(XfceAppMenuItem *app_menu_item,
        gboolean needs_term)
{
    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
    
    app_menu_item->priv->needs_term = needs_term;
}

/**
 * xfce_app_menu_item_set_startup_notification:
 * @app_menu_item: An #XfceAppMenuItem.
 * @snotify: TRUE if the application supports startup notification, FALSE if
 *           not.
 *
 * Sets whether or not the application supports startup notification.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_startup_notification(XfceAppMenuItem *app_menu_item,
        gboolean snotify)
{
    g_return_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item));
    
    app_menu_item->priv->snotify = snotify;
}

/**
 * xfce_app_menu_item_get_name:
 * @app_menu_item: An #XfceAppMenuItem.
 * @returns: A name/label string.
 *
 * Returns the current name/label set for the #XfceAppMenuItem, or NULL.
 *
 * Since 4.1
 **/
G_CONST_RETURN gchar *
xfce_app_menu_item_get_name(XfceAppMenuItem *app_menu_item)
{
    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
    
    return app_menu_item->priv->name;
}

/**
 * xfce_app_menu_item_get_icon_name:
 * @app_menu_item: An #XfceAppMenuItem.
 * @returns: An icon name string.
 *
 * Returns the current icon name set for the #XfceAppMenuItem, or NULL.
 *
 * Since 4.1
 **/
G_CONST_RETURN gchar *
xfce_app_menu_item_get_icon_name(XfceAppMenuItem *app_menu_item)
{
    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
    
    return app_menu_item->priv->icon_name;
}

/**
 * xfce_app_menu_item_get_command:
 * @app_menu_item: An #XfceAppMenuItem.
 * @returns: A command string.
 *
 * Returns the current command set for the #XfceAppMenuItem, or NULL.
 *
 * Since 4.1
 **/
G_CONST_RETURN gchar *
xfce_app_menu_item_get_command(XfceAppMenuItem *app_menu_item)
{
    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), NULL);
    
    return app_menu_item->priv->command;
}

/**
 * xfce_app_menu_item_get_needs_term:
 * @app_menu_item: An #XfceAppMenuItem.
 * @returns: TRUE if the item will spawn a terminal, FALSE if not.
 *
 * Checks whether or not the command executed by this #XfceAppMenuItem requires
 * a terminal window to run.
 *
 * Since 4.1
 **/
gboolean
xfce_app_menu_item_get_needs_term(XfceAppMenuItem *app_menu_item)
{
    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), FALSE);
    
    return app_menu_item->priv->needs_term;
}

/**
 * xfce_app_menu_item_get_startup_notification:
 * @app_menu_item: An #XfceAppMenuItem.
 * @returns: TRUE if the item supports startup notification, FALSE if not.
 *
 * Checks whether or not the command executed by this #XfceAppMenuItem supports
 * startup notification.
 *
 * Since 4.1
 **/
gboolean
xfce_app_menu_item_get_startup_notification(XfceAppMenuItem *app_menu_item)
{
    g_return_val_if_fail(XFCE_IS_APP_MENU_ITEM(app_menu_item), FALSE);
    
    return app_menu_item->priv->snotify;
}

/**
 * xfce_app_menu_item_set_icon_size:
 * @icon_size: An icon size, in pixels.
 *
 * Sets the icon size that should be used when constructing #XfceAppMenuItems
 * with icons.  This is a @static method and does not need an instance of
 * #XfceAppMenuItem to exist before it is called.
 *
 * Deprecated: This function currently does nothing; the 'menu' icon size
 *             is always used.
 *
 * Since 4.1
 **/
void xfce_app_menu_item_set_icon_size(guint icon_size)
{
    /* deprecated */
}

/**
 * xfce_app_menu_item_set_icon_theme_name:
 * @theme_name: A theme name.
 *
 * Sets the icon theme name that should be used when looking for icons for
 * #XfceAppMenuItems.  This is a @static method and does not need an instance
 * of #XfceAppMenuItem to exist before it is called.
 *
 * Since 4.1
 **/
void
xfce_app_menu_item_set_icon_theme_name(const gchar *theme_name)
{
#if GTK_CHECK_VERSION(2, 4, 0)
    gchar *origin = g_strdup_printf("%s:%d", __FILE__, __LINE__);
    gtk_settings_set_string_property(gtk_settings_get_default(),
            "gtk-icon-theme-name", theme_name, origin);
    g_free(origin);
#else
    xfce_set_icon_theme(theme_name);
#endif
}
