static void equalizerwin_delete_preset (Index * list, gchar * name, gchar * filename)
{
    int p = equalizerwin_find_preset (list, name);
    if (p < 0)
        return;

    index_delete_full (list, p, 1, (IndexFreeFunc) aud_equalizer_preset_free);

    aud_equalizer_write_presets (list, filename);
}
static bool_t search_cb (GtkTreeModel * model, int column, const char * search,
 GtkTreeIter * iter, void * user)
{
    GtkTreePath * path = gtk_tree_model_get_path (model, iter);
    g_return_val_if_fail (path, TRUE);
    int row = gtk_tree_path_get_indices (path)[0];
    g_return_val_if_fail (row >= 0, TRUE);
    gtk_tree_path_free (path);

    Index * keys = str_list_to_index (search, " ");
    int n_keys = index_count (keys);

    bool_t matched = FALSE;

    if (n_keys)
    {
        char * s[3] = {NULL, NULL, NULL};
        aud_playlist_entry_describe (((PlaylistWidgetData *) user)->list, row,
         & s[0], & s[1], & s[2], FALSE);

        for (int i = 0; i < ARRAY_LEN (s); i ++)
        {
            if (! s[i])
                continue;

            for (int j = 0; j < n_keys;)
            {
                if (strstr_nocase_utf8 (s[i], index_get (keys, j)))
                {
                    index_delete_full (keys, j, 1, (IndexFreeFunc) str_unref);
                    n_keys --;
                }
                else
                    j ++;
            }

            str_unref (s[i]);
        }

        matched = ! n_keys;
    }

    index_free_full (keys, (IndexFreeFunc) str_unref);

    return ! matched;
}
static void close_modules (void)
{
    index_delete_full (plugins, 0, -1, (IndexFreeFunc) close_plugin);
    index_delete_full (modules, 0, -1, (IndexFreeFunc) g_module_close);
}