browser: use boost::filesystem for local browsing

This commit is contained in:
Andrzej Rybczak
2013-05-16 20:55:29 +02:00
parent a1b57a45af
commit 1c6c9e9c5a
4 changed files with 38 additions and 52 deletions

View File

@@ -107,6 +107,16 @@ AC_CHECK_HEADERS([boost/lexical_cast.hpp], ,
AC_CHECK_HEADERS([boost/algorithm/string.hpp], , AC_CHECK_HEADERS([boost/algorithm/string.hpp], ,
AC_MSG_ERROR(boost/algorithm/string.hpp is missing)) AC_MSG_ERROR(boost/algorithm/string.hpp is missing))
dnl =============================
dnl = checking for boost.locale =
dnl =============================
AC_CHECK_HEADERS([boost/filesystem.hpp], ,
AC_MSG_ERROR(boost/filesystem.hpp is missing)
)
AC_CHECK_LIB(boost_filesystem$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_filesystem$BOOST_LIB_SUFFIX",
AC_MSG_ERROR([no boost.filesystem library found])
)
dnl ============================= dnl =============================
dnl = checking for boost.locale = dnl = checking for boost.locale =
dnl ============================= dnl =============================

View File

@@ -1976,13 +1976,9 @@ void ToggleBrowserSortMode::run()
switch (Config.browser_sort_mode) switch (Config.browser_sort_mode)
{ {
case smName: case smName:
if (!myBrowser->isLocal()) Config.browser_sort_mode = smMTime;
{ Statusbar::msg("Sort songs by: Modification time");
Config.browser_sort_mode = smMTime; break;
Statusbar::msg("Sort songs by: Modification time");
break;
}
// local browser doesn't support sorting by mtime, so we just skip it.
case smMTime: case smMTime:
Config.browser_sort_mode = smCustomFormat; Config.browser_sort_mode = smCustomFormat;
Statusbar::msg("Sort songs by: Custom format"); Statusbar::msg("Sort songs by: Custom format");

View File

@@ -22,6 +22,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <boost/filesystem.hpp>
#include <boost/locale/conversion.hpp> #include <boost/locale/conversion.hpp>
#include <algorithm> #include <algorithm>
@@ -90,10 +91,6 @@ void Browser::switchTo()
{ {
SwitchTo::execute(this); SwitchTo::execute(this);
// local browser doesn't support sorting by mtime
if (isLocal() && Config.browser_sort_mode == smMTime)
Config.browser_sort_mode = smName;
if (w.empty()) if (w.empty())
GetDirectory(itsBrowsedDir); GetDirectory(itsBrowsedDir);
else else
@@ -420,7 +417,7 @@ void Browser::GetDirectory(std::string dir, std::string subdir)
MPD::ItemList list; MPD::ItemList list;
# ifndef WIN32 # ifndef WIN32
if (isLocal()) if (isLocal())
GetLocalDirectory(list); GetLocalDirectory(list, itsBrowsedDir, false);
else else
Mpd.GetDirectory(dir, [&list](MPD::Item &&item) { Mpd.GetDirectory(dir, [&list](MPD::Item &&item) {
list.push_back(item); list.push_back(item);
@@ -471,61 +468,44 @@ void Browser::GetDirectory(std::string dir, std::string subdir)
#ifndef WIN32 #ifndef WIN32
void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, bool recursively) const void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, bool recursively) const
{ {
DIR *dir = opendir((directory.empty() ? itsBrowsedDir : directory).c_str()); namespace fs = boost::filesystem;
if (!dir) size_t start_size = v.size();
return; fs::path dir(directory);
std::for_each(fs::directory_iterator(dir), fs::directory_iterator(), [&](fs::directory_entry &e) {
dirent *file; if (!Config.local_browser_show_hidden_files && e.path().filename().native()[0] == '.')
return;
struct stat file_stat; MPD::Item item;
std::string full_path; if (fs::is_directory(e))
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) if (recursively)
{ {
GetLocalDirectory(v, full_path, 1); GetLocalDirectory(v, e.path().native(), true);
old_size = v.size(); start_size = v.size();
} }
else else
{ {
new_item.type = itDirectory; item.type = itDirectory;
new_item.name = full_path; item.name = e.path().native();
v.push_back(new_item); v.push_back(item);
} }
} }
else if (hasSupportedExtension(file->d_name)) else if (hasSupportedExtension(e.path().native()))
{ {
new_item.type = itSong; item.type = itSong;
mpd_pair file_pair = { "file", full_path.c_str() }; mpd_pair file_pair = { "file", e.path().native().c_str() };
MPD::MutableSong *s = new MPD::MutableSong(mpd_song_begin(&file_pair)); MPD::MutableSong *s = new MPD::MutableSong(mpd_song_begin(&file_pair));
new_item.song = std::shared_ptr<MPD::Song>(s); item.song = std::shared_ptr<MPD::Song>(s);
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
if (!recursively) if (!recursively)
Tags::read(*s); Tags::read(*s);
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
v.push_back(new_item); v.push_back(item);
} }
} });
closedir(dir);
std::sort(v.begin()+old_size, v.end(), std::sort(v.begin()+start_size, v.end(), LocaleBasedItemSorting(std::locale(),
LocaleBasedItemSorting(std::locale(), Config.ignore_leading_the, Config.browser_sort_mode)); Config.ignore_leading_the, Config.browser_sort_mode));
} }
void Browser::ClearDirectory(const std::string &path) const void Browser::ClearDirectory(const std::string &path) const

View File

@@ -71,7 +71,7 @@ struct Browser: Screen<NC::Menu<MPD::Item>>, Filterable, HasSongs, Searchable, T
void LocateSong(const MPD::Song &); void LocateSong(const MPD::Song &);
void GetDirectory(std::string, std::string = "/"); void GetDirectory(std::string, std::string = "/");
# ifndef WIN32 # ifndef WIN32
void GetLocalDirectory(MPD::ItemList &, const std::string & = "", bool = 0) const; void GetLocalDirectory(MPD::ItemList &, const std::string &, bool) const;
void ClearDirectory(const std::string &) const; void ClearDirectory(const std::string &) const;
void ChangeBrowseMode(); void ChangeBrowseMode();
bool deleteItem(const MPD::Item &); bool deleteItem(const MPD::Item &);