bool Connection::AddRandomSongs(size_t number) { prechecksNoCommandsList(); std::vector<std::string> files; mpd_send_list_all(m_connection.get(), "/"); while (mpd_pair *item = mpd_recv_pair_named(m_connection.get(), "file")) { files.push_back(item->value); mpd_return_pair(m_connection.get(), item); } mpd_response_finish(m_connection.get()); checkErrors(); if (number > files.size()) { //if (itsErrorHandler) // itsErrorHandler(this, 0, "Requested number of random songs is bigger than size of your library", itsErrorHandlerUserdata); return false; } else { std::random_shuffle(files.begin(), files.end()); StartCommandsList(); auto it = files.begin()+rand()%(std::max(size_t(1), files.size()-number)); for (size_t i = 0; i < number && it != files.end(); ++i, ++it) AddSong(*it); CommitCommandsList(); } return true; }
bool Connection::AddRandomTag(mpd_tag_type tag, size_t number) { std::vector<std::string> tags( std::make_move_iterator(GetList(tag)), std::make_move_iterator(StringIterator()) ); if (number > tags.size()) return false; std::random_shuffle(tags.begin(), tags.end()); auto it = tags.begin()+rand()%(tags.size()-number); for (size_t i = 0; i < number && it != tags.end(); ++i) { StartSearch(true); AddSearch(tag, *it++); std::vector<std::string> paths; MPD::SongIterator s = CommitSearchSongs(), end; for (; s != end; ++s) paths.push_back(s->getURI()); StartCommandsList(); for (const auto &path : paths) AddSong(path); CommitCommandsList(); } return true; }
void LoadSongs(const char *path, struct SongDef **songList) { FILE *f; char s[100]; char *p; debug(D_VERBOSE, "LoadSongs path: %s...\n", path); f = fopen(path, "r"); if (f) { debug(D_VERBOSE, "reading lines...\n"); while (fgets(s, sizeof(s), f)) { debug(D_VERBOSE, "song is: %s\n", s); p = s + strlen(s); while (p >= s && !isgraph(*p)) { *p-- = 0; } if (s[0]) { debug(D_VERBOSE, "Added song: %s\n", s); AddSong(songList, s); } } fclose(f); } else { debug(D_VERBOSE, "failed to open songlist?\n"); } }
void TrackSelectionDialog::UpdateStack() { const int row = ui_->song_list->currentRow(); if (row < 0 || row >= data_.count()) return; const Data& data = data_[row]; if (data.pending_) { ui_->stack->setCurrentWidget(ui_->loading_page); ui_->progress->set_text(data.progress_string_ + "..."); return; } else if (data.results_.isEmpty()) { ui_->stack->setCurrentWidget(ui_->error_page); return; } ui_->stack->setCurrentWidget(ui_->results_page); // Clear tree widget ui_->results->clear(); // Put the original tags at the top AddDivider(tr("Original tags"), ui_->results); AddSong(data.original_song_, -1, ui_->results); // Fill tree view with songs AddDivider(tr("Suggested tags"), ui_->results); int song_index = 0; for (const Song& song : data.results_) { AddSong(song, song_index++, ui_->results); } // Find the item that was selected last time for (int i = 0; i < ui_->results->model()->rowCount(); ++i) { const QModelIndex index = ui_->results->model()->index(i, 0); const QVariant id = index.data(Qt::UserRole); if (!id.isNull() && id.toInt() == data.selected_result_) { ui_->results->setCurrentIndex(index); break; } } }
void LoadSongList(struct SongDef **songList, const char *dirPath) { tinydir_dir dir; int errsv; if (tinydir_open(&dir, dirPath) == -1) { errsv = errno; printf("Cannot open music dir: %s\n", strerror(errsv)); goto bail; } for (; dir.has_next; tinydir_next(&dir)) { Mix_Music *m; tinydir_file file; if (tinydir_readfile(&dir, &file) == -1) { errsv = errno; debug(D_VERBOSE, "cannot read file: %s\n", strerror(errsv)); goto bail; } if (!file.is_reg) { debug(D_VERBOSE, "not a regular file %s\n", file.name); continue; } if (strcmp(file.extension, "txt") == 0 || strcmp(file.extension, "TXT") == 0) { debug(D_VERBOSE, "Skipping text file %s\n", file.name); continue; } m = Mix_LoadMUS(file.path); if (m == NULL) { debug(D_VERBOSE, "not a music file %s\n", file.name); continue; } Mix_FreeMusic(m); AddSong(songList, file.path); } bail: tinydir_close(&dir); }
int Connection::AddSong(const Song &s, int pos) { return AddSong((!s.isFromDatabase() ? "file://" : "") + s.getURI(), pos); }