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 gint file_open(gint fmt, gint rate, gint nch)
{
    gchar *filename = NULL, *temp = NULL;
    gchar * directory;
    gint pos;
    gint rv;
    gint playlist;

    input.format = fmt;
    input.frequency = rate;
    input.channels = nch;

    playlist = aud_playlist_get_playing ();
    if (playlist < 0)
        return 0;

    pos = aud_playlist_get_position(playlist);
    tuple = aud_playlist_entry_get_tuple (playlist, pos, FALSE);
    if (tuple == NULL)
        return 0;

    if (filenamefromtags)
    {
        gchar * utf8 = aud_playlist_entry_get_title (playlist, pos, FALSE);
        string_replace_char (utf8, '/', ' ');

        gchar buf[3 * strlen (utf8) + 1];
        str_encode_percent (utf8, -1, buf);
        str_unref (utf8);

        filename = g_strdup (buf);
    }
    else
    {
        temp = aud_playlist_entry_get_filename (playlist, pos);
        gchar * original = strrchr (temp, '/');
        g_return_val_if_fail (original != NULL, 0);
        filename = g_strdup (original + 1);
        str_unref (temp);

        if (!use_suffix)
            if ((temp = strrchr(filename, '.')) != NULL)
                *temp = '\0';
    }

    if (prependnumber)
    {
        gint number = tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL);
        if (!tuple || !number)
            number = pos + 1;

        temp = g_strdup_printf ("%d%%20%s", number, filename);
        g_free(filename);
        filename = temp;
    }

    if (save_original)
    {
        temp = aud_playlist_entry_get_filename (playlist, pos);
        directory = g_strdup (temp);
        str_unref (temp);
        temp = strrchr (directory, '/');
        g_return_val_if_fail (temp != NULL, 0);
        temp[1] = 0;
    }
    else
    {
        g_return_val_if_fail (file_path[0], 0);
        if (file_path[strlen (file_path) - 1] == '/')
            directory = g_strdup (file_path);
        else
            directory = g_strdup_printf ("%s/", file_path);
    }

    temp = g_strdup_printf ("%s%s.%s", directory, filename, fileext_str[fileext]);
    g_free (directory);
    g_free (filename);
    filename = temp;

    output_file = safe_create (filename);
    g_free (filename);

    if (output_file == NULL)
        return 0;

    convert_init (fmt, plugin->format_required (fmt), nch);

    rv = (plugin->open)();

    samples_written = 0;

    return rv;
}
static void get_value (void * user, gint row, gint column, GValue * value)
{
    PlaylistWidgetData * data = user;
    g_return_if_fail (column >= 0 && column < pw_num_cols);
    g_return_if_fail (row >= 0 && row < aud_playlist_entry_count (data->list));

    column = pw_cols[column];

    gchar * title = NULL, * artist = NULL, * album = NULL;
    Tuple * tuple = NULL;

    if (column == PW_COL_TITLE || column == PW_COL_ARTIST || column ==
     PW_COL_ALBUM)
        aud_playlist_entry_describe (data->list, row, & title, & artist,
         & album, TRUE);
    else if (column == PW_COL_YEAR || column == PW_COL_TRACK || column ==
     PW_COL_GENRE || column == PW_COL_FILENAME || column == PW_COL_PATH ||
     column == PW_COL_BITRATE)
        tuple = aud_playlist_entry_get_tuple (data->list, row, TRUE);

    switch (column)
    {
    case PW_COL_NUMBER:
        g_value_set_int (value, 1 + row);
        break;
    case PW_COL_TITLE:
        g_value_set_string (value, title);
        break;
    case PW_COL_ARTIST:
        g_value_set_string (value, artist);
        break;
    case PW_COL_YEAR:
        set_int_from_tuple (value, tuple, FIELD_YEAR);
        break;
    case PW_COL_ALBUM:
        g_value_set_string (value, album);
        break;
    case PW_COL_TRACK:
        set_int_from_tuple (value, tuple, FIELD_TRACK_NUMBER);
        break;
    case PW_COL_GENRE:
        set_string_from_tuple (value, tuple, FIELD_GENRE);
        break;
    case PW_COL_QUEUED:
        set_queued (value, data->list, row);
        break;
    case PW_COL_LENGTH:
        set_length (value, data->list, row);
        break;
    case PW_COL_FILENAME:
        set_string_from_tuple (value, tuple, FIELD_FILE_NAME);
        break;
    case PW_COL_PATH:
        set_string_from_tuple (value, tuple, FIELD_FILE_PATH);
        break;
    case PW_COL_CUSTOM:;
        gchar * custom = aud_playlist_entry_get_title (data->list, row, TRUE);
        g_value_set_string (value, custom);
        str_unref (custom);
        break;
    case PW_COL_BITRATE:
        set_int_from_tuple (value, tuple, FIELD_BITRATE);
        break;
    }

    str_unref (title);
    str_unref (artist);
    str_unref (album);
    if (tuple)
        tuple_unref (tuple);
}
/* do_command(): do @cmd after replacing the format codes
   @cmd: command to run */
static void do_command (char * cmd)
{
    int playlist = aud_playlist_get_playing ();
    int pos = aud_playlist_get_position (playlist);

    char *shstring = NULL, *temp, numbuf[32];
    gboolean playing;
    Formatter *formatter;

    if (cmd && strlen(cmd) > 0)
    {
        formatter = formatter_new();

        char * ctitle = aud_playlist_entry_get_title (playlist, pos, FALSE);
        if (ctitle)
        {
            temp = escape_shell_chars (ctitle);
            formatter_associate(formatter, 's', temp);
            formatter_associate(formatter, 'n', temp);
            g_free(temp);
            str_unref (ctitle);
        }
        else
        {
            formatter_associate(formatter, 's', "");
            formatter_associate(formatter, 'n', "");
        }

        char * filename = aud_playlist_entry_get_filename (playlist, pos);
        if (filename)
        {
            temp = escape_shell_chars (filename);
            formatter_associate(formatter, 'f', temp);
            g_free(temp);
            str_unref (filename);
        }
        else
            formatter_associate(formatter, 'f', "");

        g_snprintf(numbuf, sizeof(numbuf), "%02d", pos + 1);
        formatter_associate(formatter, 't', numbuf);

        int length = aud_playlist_entry_get_length (playlist, pos, FALSE);
        if (length > 0)
        {
            g_snprintf(numbuf, sizeof(numbuf), "%d", length);
            formatter_associate(formatter, 'l', numbuf);
        }
        else
            formatter_associate(formatter, 'l', "0");

        playing = aud_drct_get_playing();
        g_snprintf(numbuf, sizeof(numbuf), "%d", playing);
        formatter_associate(formatter, 'p', numbuf);

        if (playing)
        {
            int brate, srate, chans;
            aud_drct_get_info (& brate, & srate, & chans);
            snprintf (numbuf, sizeof numbuf, "%d", brate);
            formatter_associate (formatter, 'r', numbuf);
            snprintf (numbuf, sizeof numbuf, "%d", srate);
            formatter_associate (formatter, 'F', numbuf);
            snprintf (numbuf, sizeof numbuf, "%d", chans);
            formatter_associate (formatter, 'c', numbuf);
        }

        Tuple * tuple = aud_playlist_entry_get_tuple
            (aud_playlist_get_active (), pos, 0);

        char * artist = tuple ? tuple_get_str (tuple, FIELD_ARTIST, NULL) : NULL;
        if (artist)
        {
            formatter_associate(formatter, 'a', artist);
            str_unref(artist);
        }
        else
            formatter_associate(formatter, 'a', "");

        char * album = tuple ? tuple_get_str (tuple, FIELD_ALBUM, NULL) : NULL;
        if (album)
        {
            formatter_associate(formatter, 'b', album);
            str_unref(album);
        }
        else
            formatter_associate(formatter, 'b', "");

        char * title = tuple ? tuple_get_str (tuple, FIELD_TITLE, NULL) : NULL;
        if (title)
        {
            formatter_associate(formatter, 'T', title);
            str_unref(title);
        }
        else
            formatter_associate(formatter, 'T', "");

        if (tuple)
            tuple_unref (tuple);

        shstring = formatter_format(formatter, cmd);
        formatter_destroy(formatter);

        if (shstring)
        {
            execute_command(shstring);
            /* FIXME: This can possibly be freed too early */
            g_free(shstring);
        }
    }
}