/* Fix me: This considers empty fields as duplicates. */ void playlist_remove_duplicates_by_scheme (int playlist, int scheme) { int entries = playlist_entry_count (playlist); int count; if (entries < 1) return; playlist_select_all (playlist, FALSE); if (filename_comparisons[scheme] != NULL) { int (* compare) (const char * a, const char * b) = filename_comparisons[scheme]; playlist_sort_by_filename (playlist, compare); char * last = playlist_entry_get_filename (playlist, 0); for (count = 1; count < entries; count ++) { char * current = playlist_entry_get_filename (playlist, count); if (compare (last, current) == 0) playlist_entry_set_selected (playlist, count, TRUE); str_unref (last); last = current; } str_unref (last); } else if (tuple_comparisons[scheme] != NULL) { int (* compare) (const Tuple * a, const Tuple * b) = tuple_comparisons[scheme]; playlist_sort_by_tuple (playlist, compare); Tuple * last = playlist_entry_get_tuple (playlist, 0, FALSE); for (count = 1; count < entries; count ++) { Tuple * current = playlist_entry_get_tuple (playlist, count, FALSE); if (last != NULL && current != NULL && compare (last, current) == 0) playlist_entry_set_selected (playlist, count, TRUE); if (last) tuple_unref (last); last = current; } if (last) tuple_unref (last); } playlist_delete_selected (playlist); }
static gboolean get_mpris_metadata_cb(void *data) { struct MprisMetadataRequest *request = data; g_mutex_lock(info_mutex); real_position(&request->playlist, &request->entry); gchar * filename = playlist_entry_get_filename (request->playlist, request->entry); Tuple * tuple = playlist_entry_get_tuple (request->playlist, request->entry, FALSE); if (filename && tuple) request->metadata = make_mpris_metadata (filename, tuple); else request->metadata = NULL; g_free (filename); if (tuple) tuple_free (tuple); g_cond_signal(info_cond); g_mutex_unlock(info_mutex); return FALSE; }
bool_t playlist_save (int list, const char * filename) { AUDDBG ("Saving playlist %s.\n", filename); PluginHandle * plugin = get_plugin (filename, TRUE); if (! plugin) return FALSE; PlaylistPlugin * pp = plugin_get_header (plugin); g_return_val_if_fail (pp && PLUGIN_HAS_FUNC (pp, load), FALSE); bool_t fast = get_bool (NULL, "metadata_on_play"); VFSFile * file = vfs_fopen (filename, "w"); if (! file) return FALSE; char * title = playlist_get_title (list); int entries = playlist_entry_count (list); Index * filenames = index_new (); index_allocate (filenames, entries); Index * tuples = index_new (); index_allocate (tuples, entries); for (int i = 0; i < entries; i ++) { index_append (filenames, playlist_entry_get_filename (list, i)); index_append (tuples, playlist_entry_get_tuple (list, i, fast)); } bool_t success = pp->save (filename, file, title, filenames, tuples); vfs_fclose (file); str_unref (title); for (int i = 0; i < entries; i ++) { str_unref (index_get (filenames, i)); Tuple * tuple = index_get (tuples, i); if (tuple) tuple_unref (tuple); } index_free (filenames); index_free (tuples); return success; }
static gboolean get_field_cb(void *data) { struct FieldRequest *request = data; g_mutex_lock(info_mutex); real_position(&request->playlist, &request->entry); Tuple * tuple = playlist_entry_get_tuple (request->playlist, request->entry, FALSE); request->value = (tuple == NULL) ? NULL : tuple_value_to_gvalue(tuple, request->field); if (tuple) tuple_free (tuple) g_cond_signal(info_cond); g_mutex_unlock(info_mutex); return FALSE; }
void playlist_select_by_patterns (int playlist, const Tuple * patterns) { const int fields[] = {FIELD_TITLE, FIELD_ALBUM, FIELD_ARTIST, FIELD_FILE_NAME}; int entries = playlist_entry_count (playlist); int field, entry; playlist_select_all (playlist, TRUE); for (field = 0; field < G_N_ELEMENTS (fields); field ++) { char * pattern = tuple_get_str (patterns, fields[field], NULL); regex_t regex; if (! pattern || ! pattern[0] || regcomp (& regex, pattern, REG_ICASE)) { str_unref (pattern); continue; } for (entry = 0; entry < entries; entry ++) { if (! playlist_entry_get_selected (playlist, entry)) continue; Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE); char * string = tuple ? tuple_get_str (tuple, fields[field], NULL) : NULL; if (! string || regexec (& regex, string, 0, NULL, 0)) playlist_entry_set_selected (playlist, entry, FALSE); str_unref (string); if (tuple) tuple_unref (tuple); } regfree (& regex); str_unref (pattern); } }
gboolean mpris_emit_track_change(MprisPlayer * obj) { gint playlist, entry; GHashTable *metadata; playlist = playlist_get_playing(); entry = playlist_get_position(playlist); gchar * filename = playlist_entry_get_filename (playlist, entry); Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE); if (filename && tuple) { metadata = make_mpris_metadata (filename, tuple); g_signal_emit (obj, signals[TRACK_CHANGE_SIG], 0, metadata); g_hash_table_destroy (metadata); } g_free (filename); if (tuple) tuple_free (tuple); return (filename && tuple); }