static gchar *
xfdesktop_regular_file_icon_get_identifier(XfdesktopIcon *icon)
{
    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon);

    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON(icon), NULL);

    if(xfdesktop_file_icon_peek_file(file_icon) == NULL)
        return NULL;

    return g_file_get_path(xfdesktop_file_icon_peek_file(file_icon));
}
static void
xfdesktop_volume_icon_menu_properties(GtkWidget *widget,
                                      gpointer user_data)
{
    XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(user_data);        
    GFile *file;
    
    file = xfdesktop_file_icon_peek_file(icon);
    xfdesktop_file_utils_show_properties_dialog(file, 
                                                XFDESKTOP_VOLUME_ICON(icon)->priv->gscreen, 
                                                NULL);
}
static GdkDragAction
xfdesktop_regular_file_icon_get_allowed_drag_actions(XfdesktopIcon *icon)
{
    GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(icon));
    GFile *file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(icon));
    GdkDragAction actions = GDK_ACTION_LINK;  /* we can always link */

    if(!info)
        return 0;

    if(g_file_info_get_attribute_boolean(info,
                                         G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
    {
        GFileInfo *parent_info;
        GFile *parent_file;
        
        actions |= GDK_ACTION_COPY;
        
        /* we can only move if the parent is writable */
        parent_file = g_file_get_parent(file);
        parent_info = g_file_query_info(parent_file, 
                                        XFDESKTOP_FILE_INFO_NAMESPACE,
                                        G_FILE_QUERY_INFO_NONE, 
                                        NULL, NULL);
        if(parent_info) {
            if(g_file_info_get_attribute_boolean(parent_info,
                                                 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
            {
                actions |= GDK_ACTION_MOVE;
            }
            g_object_unref(parent_info);
        }
        g_object_unref(parent_file);
    }
    
    return actions;
}
static const gchar *
xfdesktop_volume_icon_peek_tooltip(XfdesktopIcon *icon)
{
    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
    GFileInfo *fs_info = xfdesktop_file_icon_peek_filesystem_info(XFDESKTOP_FILE_ICON(icon));
    GFile *file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(icon));
    
    if(!volume_icon->priv->tooltip) {
        guint64 size, free_space;
        gchar *mount_point = NULL, *size_string = NULL, *free_space_string = NULL;

        if(file && fs_info) {
            mount_point = g_file_get_parse_name(file);

            size = g_file_info_get_attribute_uint64(fs_info,
                                                    G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
            free_space = g_file_info_get_attribute_uint64(fs_info,
                                                          G_FILE_ATTRIBUTE_FILESYSTEM_FREE);

            size_string = g_format_size(size);
            free_space_string = g_format_size(free_space);

            volume_icon->priv->tooltip =
                g_strdup_printf(_("Removable Volume\nMounted in \"%s\"\n%s left (%s total)"),
                                mount_point, free_space_string, size_string);
    
            g_free(free_space_string);
            g_free(size_string);
            g_free(mount_point);
        } else {
            volume_icon->priv->tooltip = g_strdup(_("Removable Volume\nNot mounted yet"));
        }
    }

    return volume_icon->priv->tooltip;
}
gboolean
xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                         XfdesktopIcon *src_icon,
                                         GdkDragAction action)
{
    XfdesktopRegularFileIcon *regular_file_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file;
    gboolean result = FALSE;
    
    TRACE("entering");
    
    g_return_val_if_fail(regular_file_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_regular_file_icon_get_allowed_drop_actions(icon, NULL) != 0,
                         FALSE);
    
    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;
    
    if(g_file_info_get_file_type(regular_file_icon->priv->file_info) != G_FILE_TYPE_DIRECTORY
       && xfdesktop_file_utils_file_is_executable(regular_file_icon->priv->file_info))
    {
        GList files;

        files.data = src_file;
        files.prev = files.next = NULL;

        xfdesktop_file_utils_execute(NULL, regular_file_icon->priv->file, &files,
                                     regular_file_icon->priv->gscreen, NULL);

        result = TRUE;
    } else {
        GFile *parent, *dest_file = NULL;
        gchar *name;
        
        parent = g_file_get_parent(src_file);
        if(!parent)
            return FALSE;
        g_object_unref(parent);
        
        name = g_file_get_basename(src_file);
        if(!name)
            return FALSE;
        
        switch(action) {
            case GDK_ACTION_MOVE:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            case GDK_ACTION_COPY:
                dest_file = g_file_get_child(regular_file_icon->priv->file, name);
                break;
            case GDK_ACTION_LINK:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            default:
                g_warning("Unsupported drag action: %d", action);
        }

        if(dest_file) {
            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                               regular_file_icon->priv->gscreen);

            g_object_unref(dest_file);

            result = TRUE;
        }

        g_free(name);
    }
    
    return result;
}
static gchar *
xfdesktop_load_icon_location_from_folder(XfdesktopFileIcon *icon)
{
    gchar *icon_file = g_file_get_path(xfdesktop_file_icon_peek_file(icon));
    gchar *path;

    g_return_val_if_fail(icon_file, NULL);

    /* So much for standards */
    path = xfdesktop_check_file_is_valid(icon_file, "Folder.jpg");
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "folder.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Folder.JPG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "folder.JPG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "folder.jpeg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "folder.JPEG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Folder.JPEG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Folder.jpeg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Cover.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "cover.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Cover.jpeg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "cover.jpeg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "albumart.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "albumart.jpeg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "fanart.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Fanart.jpg");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "fanart.JPG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "Fanart.JPG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "FANART.JPG");
    }
    if(path == NULL) {
        path = xfdesktop_check_file_is_valid(icon_file, "FANART.jpg");
    }

    g_free(icon_file);

    /* the file *should* already be a thumbnail */
    return path;
}
static gboolean
xfdesktop_volume_icon_do_drop_dest(XfdesktopIcon *icon,
                                 XfdesktopIcon *src_icon,
                                 GdkDragAction action)
{
    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file, *parent, *dest_file = NULL;
    gboolean result = FALSE;
    gchar *name;
    
    DBG("entering");
    
    g_return_val_if_fail(volume_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_volume_icon_get_allowed_drop_actions(icon, NULL),
                         FALSE);
    
    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;

    if(!volume_icon->priv->file_info)
        return FALSE;
   
    parent = g_file_get_parent(src_file);
    if(!parent)
        return FALSE;
    g_object_unref(parent);
        
    name = g_file_get_basename(src_file);
    if(!name)
        return FALSE;
    
    switch(action) {
        case GDK_ACTION_MOVE:
            DBG("doing move");
            dest_file = g_object_ref(volume_icon->priv->file);
            break;
        
        case GDK_ACTION_COPY:
            DBG("doing copy");
            dest_file = g_file_get_child(volume_icon->priv->file, name);
            break;
        
        case GDK_ACTION_LINK:
            DBG("doing link");
            dest_file = g_object_ref(volume_icon->priv->file);
            break;
        
        default:
            g_warning("Unsupported drag action: %d", action);
    }

    if(dest_file) {
        xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                           volume_icon->priv->gscreen);
    
        g_object_unref(dest_file);

        result = TRUE;
    }

    g_free(name);
        
    return result;
}
static gboolean
xfdesktop_special_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                         XfdesktopIcon *src_icon,
                                         GdkDragAction action)
{
    XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file;
    GFile *dest_file = NULL;
    gboolean result = FALSE;

    TRACE("entering");

    g_return_val_if_fail(special_file_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_special_file_icon_get_allowed_drop_actions(icon, NULL),
                         FALSE);

    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;

    if(special_file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
        GList files;

        XF_DEBUG("doing trash");

        /* fake a file list */
        files.data = src_file;
        files.prev = files.next = NULL;

        /* let the trash service handle the trash operation */
        xfdesktop_file_utils_trash_files(&files, special_file_icon->priv->gscreen, NULL);
    } else {
        gchar *name = g_file_get_basename(src_file);
        if(!name)
            return FALSE;

        switch(action) {
            case GDK_ACTION_MOVE:
                XF_DEBUG("doing move");
                dest_file = g_object_ref(special_file_icon->priv->file);
                break;
            case GDK_ACTION_COPY:
                XF_DEBUG("doing copy");
                dest_file = g_file_get_child(special_file_icon->priv->file, name);
                break;
            case GDK_ACTION_LINK:
                XF_DEBUG("doing link");
                dest_file = g_object_ref(special_file_icon->priv->file);
                break;
            default:
                g_warning("Unsupported drag action: %d", action);
        }

        /* let the file manager service move/copy/link the file */
        if(dest_file) {
            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                               special_file_icon->priv->gscreen);

            result = TRUE;
        }

        g_object_unref(dest_file);
        g_free(name);
    }

    return result;
}