void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, bool recursively) const { DIR *dir = opendir((directory.empty() ? itsBrowsedDir : directory).c_str()); if (!dir) return; dirent *file; struct stat file_stat; std::string full_path; size_t old_size = v.size(); while ((file = readdir(dir))) { // omit . and .. if (file->d_name[0] == '.' && (file->d_name[1] == '\0' || (file->d_name[1] == '.' && file->d_name[2] == '\0'))) continue; if (!Config.local_browser_show_hidden_files && file->d_name[0] == '.') continue; MPD::Item new_item; full_path = directory.empty() ? itsBrowsedDir : directory; if (itsBrowsedDir != "/") full_path += "/"; full_path += file->d_name; stat(full_path.c_str(), &file_stat); if (S_ISDIR(file_stat.st_mode)) { if (recursively) { GetLocalDirectory(v, full_path, 1); old_size = v.size(); } else { new_item.type = itDirectory; new_item.name = full_path; v.push_back(new_item); } } else if (hasSupportedExtension(file->d_name)) { new_item.type = itSong; mpd_pair file_pair = { "file", full_path.c_str() }; MPD::MutableSong *s = new MPD::MutableSong(mpd_song_begin(&file_pair)); new_item.song = std::shared_ptr<MPD::Song>(s); # ifdef HAVE_TAGLIB_H if (!recursively) Tags::read(*s); # endif // HAVE_TAGLIB_H v.push_back(new_item); } } closedir(dir); std::sort(v.begin()+old_size, v.end(), LocaleBasedItemSorting(std::locale(), Config.ignore_leading_the, Config.browser_sort_mode)); }
void Browser::spacePressed() { if (w.empty()) return; size_t i = itsBrowsedDir != "/" ? 1 : 0; if (Config.space_selects && w.choice() >= i) { i = w.choice(); w.at(i).setSelected(!w.at(i).isSelected()); w.scroll(NC::wDown); return; } const MPD::Item &item = w.current().value(); if (isParentDirectory(item)) return; switch (item.type) { case itDirectory: { bool result; # ifndef WIN32 if (isLocal()) { MPD::SongList list; MPD::ItemList items; Statusbar::msg("Scanning directory \"%s\"...", item.name.c_str()); myBrowser->GetLocalDirectory(items, item.name, 1); list.reserve(items.size()); for (MPD::ItemList::const_iterator it = items.begin(); it != items.end(); ++it) list.push_back(*it->song); result = addSongsToPlaylist(list, false, -1); } else # endif // !WIN32 result = Mpd.Add(item.name); if (result) Statusbar::msg("Directory \"%s\" added", item.name.c_str()); break; } case itSong: { addSongToPlaylist(*item.song, false); break; } case itPlaylist: { if (Mpd.LoadPlaylist(item.name)) Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str()); break; } } w.scroll(NC::wDown); }
void Browser::GetSelectedSongs(MPD::SongList &v) { if (w->Empty()) return; std::vector<size_t> selected; w->GetSelected(selected); if (selected.empty()) selected.push_back(w->Choice()); for (std::vector<size_t>::const_iterator it = selected.begin(); it != selected.end(); ++it) { const MPD::Item &item = w->at(*it); switch (item.type) { case itDirectory: { # ifndef WIN32 if (isLocal()) { MPD::ItemList list; GetLocalDirectory(list, item.name, 1); for (MPD::ItemList::const_iterator j = list.begin(); j != list.end(); ++j) v.push_back(j->song); } else # endif // !WIN32 Mpd.GetDirectoryRecursive(locale_to_utf_cpy(item.name), v); break; } case itSong: { v.push_back(new MPD::Song(*item.song)); break; } case itPlaylist: { Mpd.GetPlaylistContent(locale_to_utf_cpy(item.name), v); break; } } } }
MPD::SongList Browser::getSelectedSongs() { MPD::SongList result; auto item_handler = [this, &result](const MPD::Item &item) { if (item.type == itDirectory) { # ifndef WIN32 if (isLocal()) { MPD::ItemList list; GetLocalDirectory(list, item.name, true); for (auto it = list.begin(); it != list.end(); ++it) result.push_back(*it->song); } else # endif // !WIN32 { auto list = Mpd.GetDirectoryRecursive(item.name); result.insert(result.end(), list.begin(), list.end()); } } else if (item.type == itSong) result.push_back(*item.song); else if (item.type == itPlaylist) { auto list = Mpd.GetPlaylistContent(item.name); result.insert(result.end(), list.begin(), list.end()); } }; for (auto it = w.begin(); it != w.end(); ++it) if (it->isSelected()) item_handler(it->value()); // if no item is selected, add current one if (result.empty() && !w.empty()) item_handler(w.current().value()); return result; }
void Browser::GetDirectory(std::string dir, std::string subdir) { if (dir.empty()) dir = "/"; int highlightme = -1; itsScrollBeginning = 0; if (itsBrowsedDir != dir) w.reset(); itsBrowsedDir = dir; w.clear(); if (dir != "/") { MPD::Item parent; parent.name = ".."; parent.type = itDirectory; w.addItem(parent); } MPD::ItemList list; # ifndef WIN32 if (isLocal()) GetLocalDirectory(list); else list = Mpd.GetDirectory(dir); # else list = Mpd.GetDirectory(dir); # endif // !WIN32 if (!isLocal()) // local directory is already sorted std::sort(list.begin(), list.end(), LocaleBasedItemSorting(std::locale(), Config.ignore_leading_the, Config.browser_sort_mode)); for (MPD::ItemList::iterator it = list.begin(); it != list.end(); ++it) { switch (it->type) { case itPlaylist: { w.addItem(*it); break; } case itDirectory: { if (it->name == subdir) highlightme = w.size(); w.addItem(*it); break; } case itSong: { bool bold = 0; for (size_t i = 0; i < myPlaylist->main().size(); ++i) { if (myPlaylist->main().at(i).value().getHash() == it->song->getHash()) { bold = 1; break; } } w.addItem(*it, bold); break; } } } if (highlightme >= 0) w.highlight(highlightme); }
void Browser::GetDirectory(std::string dir, std::string subdir) { if (dir.empty()) dir = "/"; int highlightme = -1; itsScrollBeginning = 0; if (itsBrowsedDir != dir) w->Reset(); itsBrowsedDir = dir; locale_to_utf(dir); for (size_t i = 0; i < w->Size(); ++i) if (w->at(i).type == itSong) delete w->at(i).song; w->Clear(); if (dir != "/") { MPD::Item parent; size_t slash = dir.rfind("/"); parent.song = reinterpret_cast<MPD::Song *>(1); // in that way we assume that's really parent dir parent.name = slash != std::string::npos ? dir.substr(0, slash) : "/"; parent.type = itDirectory; utf_to_locale(parent.name); w->AddOption(parent); } MPD::ItemList list; # ifndef WIN32 isLocal() ? GetLocalDirectory(list) : Mpd.GetDirectory(dir, list); # else Mpd.GetDirectory(dir, list); # endif // !WIN32 if (!isLocal()) // local directory is already sorted sort(list.begin(), list.end(), CaseInsensitiveSorting()); for (MPD::ItemList::iterator it = list.begin(); it != list.end(); ++it) { switch (it->type) { case itPlaylist: { utf_to_locale(it->name); w->AddOption(*it); break; } case itDirectory: { utf_to_locale(it->name); if (it->name == subdir) highlightme = w->Size(); w->AddOption(*it); break; } case itSong: { bool bold = 0; for (size_t i = 0; i < myPlaylist->Items->Size(); ++i) { if (myPlaylist->Items->at(i).GetHash() == it->song->GetHash()) { bold = 1; break; } } w->AddOption(*it, bold); break; } } } if (highlightme >= 0) w->Highlight(highlightme); }
void Browser::SpacePressed() { if (w->Empty()) return; if (Config.space_selects && w->Choice() >= (itsBrowsedDir != "/" ? 1 : 0)) { w->Select(w->Choice(), !w->isSelected()); w->Scroll(wDown); return; } if (itsBrowsedDir != "/" && w->Choice() == 0 /* parent dir */) return; const MPD::Item &item = w->Current(); switch (item.type) { case itDirectory: { if (itsBrowsedDir != "/" && !w->Choice()) break; // do not let add parent dir. MPD::SongList list; # ifndef WIN32 if (isLocal()) { MPD::ItemList items; ShowMessage(_("Scanning \"%s\"..."), item.name.c_str()); myBrowser->GetLocalDirectory(items, item.name, 1); list.reserve(items.size()); for (MPD::ItemList::const_iterator it = items.begin(); it != items.end(); ++it) list.push_back(it->song); } else # endif // !WIN32 Mpd.GetDirectoryRecursive(locale_to_utf_cpy(item.name), list); if (myPlaylist->Add(list, 0)) ShowMessage(_("Added folder: %s"), item.name.c_str()); FreeSongList(list); break; } case itSong: { w->Bold(w->Choice(), myPlaylist->Add(*item.song, w->isBold(), 0)); break; } case itPlaylist: { std::string name = item.name; ShowMessage(_("Loading playlist %s..."), name.c_str()); locale_to_utf(name); if (!Mpd.LoadPlaylist(name)) ShowMessage(_("Couldn't load playlist.")); break; } } w->Scroll(wDown); }