static void shift_rows (void * user, gint row, gint before)
{
    GArray * shift = g_array_new (FALSE, FALSE, sizeof (gint));
    gint list = aud_playlist_get_active ();
    gint count = aud_playlist_queue_count (list);

    for (gint i = 0; i < count; i ++)
    {
        gint entry = aud_playlist_queue_get_entry (list, i);

        if (aud_playlist_entry_get_selected (list, entry))
        {
            g_array_append_val (shift, entry);

            if (i < before)
                before --;
        }
    }

    aud_playlist_queue_delete_selected (list);

    for (gint i = 0; i < shift->len; i ++)
        aud_playlist_queue_insert (list, before + i, g_array_index (shift, gint, i));

    g_array_free (shift, TRUE);
}
static void select_all (void * user, gboolean selected)
{
    gint list = aud_playlist_get_active ();
    gint count = aud_playlist_queue_count (list);

    for (gint i = 0; i < count; i ++)
        aud_playlist_entry_set_selected (list, aud_playlist_queue_get_entry (list, i), selected);
}
static void update_queue (GtkWidget * widget, PlaylistWidgetData * data)
{
    for (GList * node = data->queue; node; node = node->next)
        audgui_list_update_rows (widget, GPOINTER_TO_INT (node->data), 1);

    g_list_free (data->queue);
    data->queue = NULL;

    for (gint i = aud_playlist_queue_count (data->list); i --; )
        data->queue = g_list_prepend (data->queue, GINT_TO_POINTER
         (aud_playlist_queue_get_entry (data->list, i)));

    for (GList * node = data->queue; node; node = node->next)
        audgui_list_update_rows (widget, GPOINTER_TO_INT (node->data), 1);
}
static void get_value (void * user, gint row, gint column, GValue * value)
{
    gint list = aud_playlist_get_active ();
    gint entry = aud_playlist_queue_get_entry (list, row);

    switch (column)
    {
    case COLUMN_ENTRY:
        g_value_set_int (value, 1 + entry);
        break;
    case COLUMN_TITLE:;
        gchar * title = aud_playlist_entry_get_title (list, entry, TRUE);
        g_value_take_string (value, title);
        break;
    }
}
static void remove_selected (void)
{
    gint list = aud_playlist_get_active ();
    gint count = aud_playlist_queue_count (list);

    for (gint i = 0; i < count; )
    {
        gint entry = aud_playlist_queue_get_entry (list, i);

        if (aud_playlist_entry_get_selected (list, entry))
        {
            aud_playlist_queue_delete (list, i, 1);
            aud_playlist_entry_set_selected (list, entry, FALSE);
            count --;
        }
        else
            i ++;
    }
}
static void set_selected (void * user, gint row, gboolean selected)
{
    gint list = aud_playlist_get_active ();
    aud_playlist_entry_set_selected (list, aud_playlist_queue_get_entry (list, row), selected);
}
static gboolean get_selected (void * user, gint row)
{
    gint list = aud_playlist_get_active ();
    return aud_playlist_entry_get_selected (list, aud_playlist_queue_get_entry (list, row));
}