summaryrefslogtreecommitdiff
path: root/src/browser.cpp
diff options
context:
space:
mode:
authorAndrzej Rybczak <electricityispower@gmail.com>2014-11-02 00:22:02 +0100
committerAndrzej Rybczak <electricityispower@gmail.com>2014-11-02 22:14:29 +0100
commit0457af36fef70d795afaf56c13a105b2016caad6 (patch)
tree7891f7cea36ec7b8c6f1ce0108dd903e9825fe0b /src/browser.cpp
parent30d57afcace02b6347cd5e644bd0a987717237fc (diff)
mpd: redesign Item and adjust browser
Diffstat (limited to 'src/browser.cpp')
-rw-r--r--src/browser.cpp589
1 files changed, 324 insertions, 265 deletions
diff --git a/src/browser.cpp b/src/browser.cpp
index 79074610..62898489 100644
--- a/src/browser.cpp
+++ b/src/browser.cpp
@@ -18,10 +18,12 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
+#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/locale/conversion.hpp>
-#include <algorithm>
+#include <time.h>
#include "browser.h"
#include "charset.h"
@@ -50,17 +52,27 @@ namespace fs = boost::filesystem;
Browser *myBrowser;
-namespace {//
+namespace {
+
+std::set<std::string> lm_supported_extensions;
-std::set<std::string> SupportedExtensions;
-bool hasSupportedExtension(const std::string &file);
+std::string realPath(bool local_browser, std::string path);
+bool isStringParentDirectory(const std::string &directory);
+bool isItemParentDirectory(const MPD::Item &item);
+bool isRootDirectory(const std::string &directory);
+bool isHidden(const fs::directory_iterator &entry);
+bool hasSupportedExtension(const fs::directory_entry &entry);
+MPD::Song getLocalSong(const fs::directory_entry &entry, bool read_tags);
+void getLocalDirectory(MPD::ItemList &items, const std::string &directory);
+void getLocalDirectoryRecursively(MPD::SongList &songs, const std::string &directory);
+void clearDirectory(const std::string &directory);
-std::string ItemToString(const MPD::Item &item);
-bool BrowserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter);
+std::string itemToString(const MPD::Item &item);
+bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter);
}
-Browser::Browser() : itsBrowseLocally(0), itsScrollBeginning(0), itsBrowsedDir("/")
+Browser::Browser() : m_local_browser(false), m_scroll_beginning(0), m_current_directory("/")
{
w = NC::Menu<MPD::Item>(0, MainStartY, COLS, MainHeight, Config.browser_display_mode == DisplayMode::Columns && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, NC::Border::None);
w.setHighlightColor(Config.main_highlight_color);
@@ -97,7 +109,7 @@ void Browser::switchTo()
SwitchTo::execute(this);
if (w.empty())
- GetDirectory(itsBrowsedDir);
+ getDirectory(m_current_directory);
else
markSongsInPlaylist(proxySongList());
@@ -107,7 +119,7 @@ void Browser::switchTo()
std::wstring Browser::title()
{
std::wstring result = L"Browse: ";
- result += Scroller(ToWString(itsBrowsedDir), itsScrollBeginning, COLS-result.length()-(Config.design == Design::Alternative ? 2 : Global::VolumeState.length()));
+ result += Scroller(ToWString(m_current_directory), m_scroll_beginning, COLS-result.length()-(Config.design == Design::Alternative ? 2 : Global::VolumeState.length()));
return result;
}
@@ -117,31 +129,29 @@ void Browser::enterPressed()
return;
const MPD::Item &item = w.current().value();
- switch (item.type)
+ switch (item.type())
{
case MPD::Item::Type::Directory:
{
- if (isParentDirectory(item))
- GetDirectory(getParentDirectory(itsBrowsedDir), itsBrowsedDir);
- else
- GetDirectory(item.name, itsBrowsedDir);
+ getDirectory(item.directory().path());
drawHeader();
break;
}
case MPD::Item::Type::Song:
{
- addSongToPlaylist(item.song, true, -1);
+ addSongToPlaylist(item.song(), true, -1);
break;
}
case MPD::Item::Type::Playlist:
{
MPD::SongList list(
- std::make_move_iterator(Mpd.GetPlaylistContentNoInfo(item.name)),
+ std::make_move_iterator(Mpd.GetPlaylistContentNoInfo(item.playlist().path())),
std::make_move_iterator(MPD::SongIterator())
);
+ // TODO: ask on failure if we want to continue
bool success = addSongsToPlaylist(list.begin(), list.end(), true, -1);
Statusbar::printf("Playlist \"%1%\" loaded%2%",
- item.name, withErrors(success)
+ item.playlist().path(), withErrors(success)
);
}
}
@@ -152,60 +162,47 @@ void Browser::spacePressed()
if (w.empty())
return;
- size_t i = itsBrowsedDir != "/" ? 1 : 0;
+ size_t i = inRootDirectory() ? 0 : 1;
if (Config.space_selects && w.choice() >= i)
{
i = w.choice();
- w.at(i).setSelected(!w.at(i).isSelected());
+ w[i].setSelected(!w[i].isSelected());
w.scroll(NC::Scroll::Down);
return;
}
-
+
const MPD::Item &item = w.current().value();
-
+ // ignore parent directory
if (isParentDirectory(item))
return;
-
- switch (item.type)
+
+ switch (item.type())
{
case MPD::Item::Type::Directory:
{
- bool success;
-# ifndef WIN32
- if (isLocal())
+ bool success = true;
+ if (m_local_browser)
{
- MPD::SongList list;
- MPD::ItemList items;
- Statusbar::printf("Scanning directory \"%1%\"...", item.name);
- 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);
- success = addSongsToPlaylist(list.begin(), list.end(), false, -1);
+ MPD::SongList songs;
+ getLocalDirectoryRecursively(songs, item.directory().path());
+ success = addSongsToPlaylist(songs.begin(), songs.end(), false, -1);
}
else
-# endif // !WIN32
- {
- Mpd.Add(item.name);
- success = true;
- }
+ Mpd.Add(item.directory().path());
Statusbar::printf("Directory \"%1%\" added%2%",
- item.name, withErrors(success)
+ item.directory().path(), withErrors(success)
);
break;
}
case MPD::Item::Type::Song:
- {
- addSongToPlaylist(item.song, false);
+ addSongToPlaylist(item.song(), false);
break;
- }
case MPD::Item::Type::Playlist:
- {
- Mpd.LoadPlaylist(item.name);
- Statusbar::printf("Playlist \"%1%\" loaded", item.name);
+ Mpd.LoadPlaylist(item.playlist().path());
+ Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path());
break;
- }
}
+
w.scroll(NC::Scroll::Down);
}
@@ -216,12 +213,12 @@ void Browser::mouseButtonPressed(MEVENT me)
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
{
w.Goto(me.y);
- switch (w.current().value().type)
+ switch (w.current().value().type())
{
case MPD::Item::Type::Directory:
if (me.bstate & BUTTON1_PRESSED)
{
- GetDirectory(w.current().value().name);
+ getDirectory(w.current().value().directory().path());
drawHeader();
}
else
@@ -273,7 +270,7 @@ void Browser::applyFilter(const std::string &filter)
try
{
w.showAll();
- auto fun = boost::bind(BrowserEntryMatcher, _1, _2, true);
+ auto fun = boost::bind(browserEntryMatcher, _1, _2, true);
auto rx = RegexFilter<MPD::Item>(
boost::regex(filter, Config.regex_type), fun);
w.filter(w.begin(), w.end(), rx);
@@ -297,7 +294,7 @@ bool Browser::search(const std::string &constraint)
}
try
{
- auto fun = boost::bind(BrowserEntryMatcher, _1, _2, false);
+ auto fun = boost::bind(browserEntryMatcher, _1, _2, false);
auto rx = RegexFilter<MPD::Item>(
boost::regex(constraint, Config.regex_type), fun);
return w.search(w.begin(), w.end(), rx);
@@ -324,8 +321,8 @@ ProxySongList Browser::proxySongList()
{
return ProxySongList(w, [](NC::Menu<MPD::Item>::Item &item) -> MPD::Song * {
MPD::Song *ptr = 0;
- if (item.value().type == MPD::Item::Type::Song)
- ptr = &item.value().song;
+ if (item.value().type() == MPD::Item::Type::Song)
+ ptr = const_cast<MPD::Song *>(&item.value().song());
return ptr;
});
}
@@ -337,201 +334,167 @@ bool Browser::allowsSelection()
void Browser::reverseSelection()
{
- reverseSelectionHelper(w.begin()+(itsBrowsedDir == "/" ? 0 : 1), w.end());
+ size_t offset = inRootDirectory() ? 0 : 1;
+ reverseSelectionHelper(w.begin()+offset, w.end());
}
MPD::SongList Browser::getSelectedSongs()
{
- MPD::SongList result;
- auto item_handler = [this, &result](const MPD::Item &item) {
- if (item.type == MPD::Item::Type::Directory)
- {
-# 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
- {
- Mpd.GetDirectoryRecursive(item.name, vectorMoveInserter(result));
- }
- }
- else if (item.type == MPD::Item::Type::Song)
- result.push_back(item.song);
- else if (item.type == MPD::Item::Type::Playlist)
+ MPD::SongList songs;
+ auto item_handler = [this, &songs](const MPD::Item &item) {
+ switch (item.type())
{
- std::copy(
- std::make_move_iterator(Mpd.GetPlaylistContent(item.name)),
- std::make_move_iterator(MPD::SongIterator()),
- std::back_inserter(result)
- );
+ case MPD::Item::Type::Directory:
+ if (m_local_browser)
+ {
+ MPD::ItemList items;
+ getLocalDirectoryRecursively(songs, item.directory().path());
+ }
+ else
+ {
+ MPD::ItemIterator it = Mpd.GetDirectoryRecursive(item.directory().path()), end;
+ for (; it != end; ++it)
+ if (it->type() == MPD::Item::Type::Song)
+ songs.push_back(std::move(it->song()));
+ }
+ break;
+ case MPD::Item::Type::Song:
+ songs.push_back(item.song());
+ break;
+ case MPD::Item::Type::Playlist:
+ std::copy(
+ std::make_move_iterator(Mpd.GetPlaylistContent(item.playlist().path())),
+ std::make_move_iterator(MPD::SongIterator()),
+ std::back_inserter(songs)
+ );
+ break;
}
};
- for (auto it = w.begin(); it != w.end(); ++it)
- if (it->isSelected())
- item_handler(it->value());
+ for (const auto &item : w)
+ if (item.isSelected())
+ item_handler(item.value());
// if no item is selected, add current one
- if (result.empty() && !w.empty())
+ if (songs.empty() && !w.empty())
item_handler(w.current().value());
- return result;
+ return songs;
}
-void Browser::fetchSupportedExtensions()
+/***********************************************************************/
+
+bool Browser::inRootDirectory()
+{
+ return isRootDirectory(m_current_directory);
+}
+
+bool Browser::isParentDirectory(const MPD::Item &item)
+{
+ return isItemParentDirectory(item);
+}
+
+const std::string& Browser::currentDirectory()
{
- SupportedExtensions.clear();
- Mpd.GetSupportedExtensions(SupportedExtensions);
+ return m_current_directory;
}
-void Browser::LocateSong(const MPD::Song &s)
+void Browser::locateSong(const MPD::Song &s)
{
if (s.getDirectory().empty())
- return;
+ throw std::runtime_error("Song's directory is empty");
- itsBrowseLocally = !s.isFromDatabase();
+ m_local_browser = !s.isFromDatabase();
if (myScreen != this)
switchTo();
- if (itsBrowsedDir != s.getDirectory())
- GetDirectory(s.getDirectory());
- for (size_t i = 0; i < w.size(); ++i)
+ // change to relevant directory
+ if (m_current_directory != s.getDirectory())
{
- if (w[i].value().type == MPD::Item::Type::Song && s == w[i].value().song)
- {
- w.highlight(i);
- break;
- }
+ getDirectory(s.getDirectory());
+ drawHeader();
}
- drawHeader();
+
+ // highlight the item
+ auto begin = w.beginV(), end = w.endV();
+ auto it = std::find(begin, end, MPD::Item(s));
+ if (it != end)
+ w.highlight(it-begin);
}
-void Browser::GetDirectory(std::string dir, std::string subdir)
+void Browser::getDirectory(std::string directory)
{
- if (dir.empty())
- dir = "/";
-
- int highlightme = -1;
- itsScrollBeginning = 0;
- if (itsBrowsedDir != dir)
- w.reset();
- itsBrowsedDir = dir;
-
+ m_scroll_beginning = 0;
w.clear();
-
- if (dir != "/")
+
+ // reset the position if we change directories
+ if (m_current_directory != directory)
+ w.reset();
+
+ // check if it's a parent directory
+ if (isStringParentDirectory(directory))
{
- MPD::Item parent;
- parent.name = "..";
- parent.type = MPD::Item::Type::Directory;
- w.addItem(parent);
+ directory.resize(directory.length()-3);
+ directory = getParentDirectory(directory);
}
-
- MPD::ItemList list;
-# ifndef WIN32
- if (isLocal())
- GetLocalDirectory(list, itsBrowsedDir, false);
+ // when we go down to root, it can be empty
+ if (directory.empty())
+ directory = "/";
+
+ MPD::ItemList items;
+ if (m_local_browser)
+ getLocalDirectory(items, directory);
else
- Mpd.GetDirectory(dir, vectorMoveInserter(list));
-# else
- list = Mpd.GetDirectory(dir);
-# endif // !WIN32
- if (Config.browser_sort_mode != SortMode::NoOp && !isLocal()) // local directory is already sorted
- std::sort(list.begin(), list.end(),
+ {
+ std::copy(
+ std::make_move_iterator(Mpd.GetDirectory(directory)),
+ std::make_move_iterator(MPD::ItemIterator()),
+ std::back_inserter(items)
+ );
+ }
+
+ // sort items
+ if (Config.browser_sort_mode != SortMode::NoOp)
+ {
+ std::sort(items.begin(), items.end(),
LocaleBasedItemSorting(std::locale(), Config.ignore_leading_the, Config.browser_sort_mode)
);
-
- for (MPD::ItemList::iterator it = list.begin(); it != list.end(); ++it)
+ }
+
+ // if the requested directory is not root, add parent directory
+ if (!isRootDirectory(directory))
+ {
+ // make it so that display function doesn't have to handle special cases
+ w.addItem(MPD::Directory(directory + "/.."));
+ }
+
+ for (const auto &item : items)
{
- switch (it->type)
+ switch (item.type())
{
case MPD::Item::Type::Playlist:
{
- w.addItem(*it);
+ w.addItem(std::move(item));
break;
}
case MPD::Item::Type::Directory:
{
- if (it->name == subdir)
- highlightme = w.size();
- w.addItem(*it);
+ bool is_current = item.directory().path() == m_current_directory;
+ w.addItem(std::move(item));
+ if (is_current)
+ w.highlight(w.size()-1);
break;
}
case MPD::Item::Type::Song:
{
- w.addItem(*it, myPlaylist->checkForSong(it->song));
+ bool is_bold = myPlaylist->checkForSong(item.song());
+ w.addItem(std::move(item), is_bold);
break;
}
}
}
- if (highlightme >= 0)
- w.highlight(highlightme);
-}
-
-#ifndef WIN32
-void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, bool recursively) const
-{
- size_t start_size = v.size();
- fs::path dir(directory);
- std::for_each(fs::directory_iterator(dir), fs::directory_iterator(), [&](fs::directory_entry &e) {
- if (!Config.local_browser_show_hidden_files && e.path().filename().native()[0] == '.')
- return;
- MPD::Item item;
- if (fs::is_directory(e))
- {
- if (recursively)
- {
- GetLocalDirectory(v, e.path().native(), true);
- start_size = v.size();
- }
- else
- {
- item.type = MPD::Item::Type::Directory;
- item.name = e.path().native();
- v.push_back(item);
- }
- }
- else if (hasSupportedExtension(e.path().native()))
- {
- item.type = MPD::Item::Type::Song;
- mpd_pair file_pair = { "file", e.path().native().c_str() };
- item.song = mpd_song_begin(&file_pair);
- // FIXME no tag reading for now
- /*
-# ifdef HAVE_TAGLIB_H
- if (!recursively)
- {
- s->setMTime(fs::last_write_time(e.path()));
- Tags::read(*s);
- }
-# endif // HAVE_TAGLIB_H
- */
- v.push_back(item);
- }
- });
-
- if (Config.browser_sort_mode != SortMode::NoOp)
- std::sort(v.begin()+start_size, v.end(),
- LocaleBasedItemSorting(std::locale(), Config.ignore_leading_the, Config.browser_sort_mode)
- );
+ m_current_directory = directory;
}
-void Browser::ClearDirectory(const std::string &path) const
-{
- fs::path dir(path);
- std::for_each(fs::directory_iterator(dir), fs::directory_iterator(), [&](fs::directory_entry &e) {
- if (!fs::is_symlink(e) && fs::is_directory(e))
- ClearDirectory(e.path().native());
- const char msg[] = "Deleting \"%1%\"...";
- Statusbar::printf(msg, wideShorten(e.path().native(), COLS-const_strlen(msg)));
- fs::remove(e.path());
- });
-}
-
-void Browser::ChangeBrowseMode()
+void Browser::changeBrowseMode()
{
if (Mpd.GetHostname()[0] != '/')
{
@@ -539,120 +502,216 @@ void Browser::ChangeBrowseMode()
return;
}
- itsBrowseLocally = !itsBrowseLocally;
+ m_local_browser = !m_local_browser;
Statusbar::printf("Browse mode: %1%",
- itsBrowseLocally ? "local filesystem" : "MPD database"
+ m_local_browser ? "local filesystem" : "MPD database"
);
- if (itsBrowseLocally)
+ if (m_local_browser)
{
- itsBrowsedDir = "~";
- expand_home(itsBrowsedDir);
- if (*itsBrowsedDir.rbegin() == '/')
- itsBrowsedDir.resize(itsBrowsedDir.length()-1);
+ m_current_directory = "~";
+ expand_home(m_current_directory);
}
else
- itsBrowsedDir = "/";
+ m_current_directory = "/";
w.reset();
- GetDirectory(itsBrowsedDir);
+ getDirectory(m_current_directory);
drawHeader();
}
-bool Browser::deleteItem(const MPD::Item &item, std::string &errmsg)
+void Browser::remove(const MPD::Item &item)
{
if (!Config.allow_for_physical_item_deletion)
- FatalError("Browser::deleteItem invoked with allow_for_physical_item_deletion = false");
+ throw std::runtime_error("physical deletion is forbidden");
if (isParentDirectory((item)))
- FatalError("Parent directory passed to Browser::deleteItem");
-
- // playlist created by mpd
- if (!isLocal() && item.type == MPD::Item::Type::Playlist && CurrentDir() == "/")
+ throw std::runtime_error("deletion of parent directory is forbidden");
+
+ std::string path;
+ switch (item.type())
{
- try
- {
- Mpd.DeletePlaylist(item.name);
- return true;
- }
- catch (MPD::ServerError &e)
- {
- // if there is no such mpd playlist, we assume it's users's playlist.
- if (e.code() != MPD_SERVER_ERROR_NO_EXIST)
- throw;
- }
+ case MPD::Item::Type::Directory:
+ path = realPath(m_local_browser, item.directory().path());
+ clearDirectory(path);
+ fs::remove(path);
+ break;
+ case MPD::Item::Type::Song:
+ path = realPath(m_local_browser, item.song().getURI());
+ fs::remove(path);
+ break;
+ case MPD::Item::Type::Playlist:
+ path = item.playlist().path();
+ try {
+ Mpd.DeletePlaylist(path);
+ } catch (MPD::ServerError &e) {
+ // if there is no such mpd playlist, it's a local one
+ if (e.code() == MPD_SERVER_ERROR_NO_EXIST)
+ {
+ path = realPath(m_local_browser, std::move(path));
+ fs::remove(path);
+ }
+ else
+ throw;
+ }
+ break;
}
-
- std::string path;
- if (!isLocal())
- path = Config.mpd_music_dir;
- path += item.type == MPD::Item::Type::Song ? item.song.getURI() : item.name;
+}
- bool rv;
- try
+/***********************************************************************/
+
+void Browser::fetchSupportedExtensions()
+{
+ lm_supported_extensions.clear();
+ Mpd.GetSupportedExtensions([&](std::string extension) {
+ lm_supported_extensions.insert("." + std::move(extension));
+ });
+}
+
+/***********************************************************************/
+
+namespace {
+
+std::string realPath(bool local_browser, std::string path)
+{
+ if (!local_browser)
+ path = Config.mpd_music_dir + path;
+ return path;
+}
+
+bool isStringParentDirectory(const std::string &directory)
+{
+ return boost::algorithm::ends_with(directory, "/..");
+}
+
+bool isItemParentDirectory(const MPD::Item &item)
+{
+ return item.type() == MPD::Item::Type::Directory
+ && isStringParentDirectory(item.directory().path());
+}
+
+bool isRootDirectory(const std::string &directory)
+{
+ return directory == "/";
+}
+
+bool isHidden(const fs::directory_iterator &entry)
+{
+ return entry->path().filename().native()[0] == '.';
+}
+
+bool hasSupportedExtension(const fs::directory_entry &entry)
+{
+ return lm_supported_extensions.find(entry.path().extension().native())
+ != lm_supported_extensions.end();
+}
+
+MPD::Song getLocalSong(const fs::directory_entry &entry, bool read_tags)
+{
+ mpd_pair pair = { "file", entry.path().c_str() };
+ mpd_song *s = mpd_song_begin(&pair);
+ if (s == nullptr)
+ throw std::runtime_error("invalid path: " + entry.path().native());
+# ifdef HAVE_TAGLIB_H
+ if (read_tags)
{
- if (item.type == MPD::Item::Type::Directory)
- ClearDirectory(path);
- if (!boost::filesystem::exists(path))
- {
- errmsg = "No such item: " + path;
- rv = false;
- }
- else
- {
- boost::filesystem::remove(path);
- rv = true;
- }
+ Tags::setAttribute(s, "Last-Modified",
+ timeFormat("%Y-%m-%dT%H:%M:%SZ", fs::last_write_time(entry.path()))
+ );
+ // read tags
+ Tags::read(s);
}
- catch (boost::filesystem::filesystem_error &err)
+# endif // HAVE_TAGLIB_H
+ return s;
+}
+
+void getLocalDirectory(MPD::ItemList &items, const std::string &directory)
+{
+ for (fs::directory_iterator entry(directory), end; entry != end; ++entry)
{
- errmsg = err.what();
- rv = false;
+ if (!Config.local_browser_show_hidden_files && isHidden(entry))
+ continue;
+
+ if (fs::is_directory(*entry))
+ {
+ items.push_back(MPD::Directory(
+ entry->path().native(),
+ fs::last_write_time(entry->path())
+ ));
+ }
+ else if (hasSupportedExtension(*entry))
+ items.push_back(getLocalSong(*entry, true));
}
- return rv;
}
-#endif // !WIN32
-namespace {//
+void getLocalDirectoryRecursively(MPD::SongList &songs, const std::string &directory)
+{
+ size_t sort_offset = songs.size();
+ for (fs::directory_iterator entry(directory), end; entry != end; ++entry)
+ {
+ if (!Config.local_browser_show_hidden_files && isHidden(entry))
+ continue;
+
+ if (fs::is_directory(*entry))
+ {
+ getLocalDirectoryRecursively(songs, entry->path().native());
+ sort_offset = songs.size();
+ }
+ else if (hasSupportedExtension(*entry))
+ songs.push_back(getLocalSong(*entry, false));
+ };
+
+ if (Config.browser_sort_mode != SortMode::NoOp)
+ {
+ std::sort(songs.begin()+sort_offset, songs.end(),
+ LocaleBasedSorting(std::locale(), Config.ignore_leading_the)
+ );
+ }
+}
-bool hasSupportedExtension(const std::string &file)
+void clearDirectory(const std::string &directory)
{
- size_t last_dot = file.rfind(".");
- if (last_dot > file.length())
- return false;
-
- std::string ext = boost::locale::to_lower(file.substr(last_dot+1));
- return SupportedExtensions.find(ext) != SupportedExtensions.end();
+ for (fs::directory_iterator entry(directory), end; entry != end; ++entry)
+ {
+ if (!fs::is_symlink(*entry) && fs::is_directory(*entry))
+ clearDirectory(entry->path().native());
+ const char msg[] = "Deleting \"%1%\"...";
+ Statusbar::printf(msg, wideShorten(entry->path().native(), COLS-const_strlen(msg)));
+ fs::remove(entry->path());
+ };
}
-std::string ItemToString(const MPD::Item &item)
+/***********************************************************************/
+
+std::string itemToString(const MPD::Item &item)
{
std::string result;
- switch (item.type)
+ switch (item.type())
{
case MPD::Item::Type::Directory:
- result = "[" + getBasename(item.name) + "]";
+ result = "[" + getBasename(item.directory().path()) + "]";
break;
case MPD::Item::Type::Song:
switch (Config.browser_display_mode)
{
case DisplayMode::Classic:
- result = item.song.toString(Config.song_list_format_dollar_free, Config.tags_separator);
+ result = item.song().toString(Config.song_list_format_dollar_free, Config.tags_separator);
break;
case DisplayMode::Columns:
- result = item.song.toString(Config.song_in_columns_to_string_format, Config.tags_separator);
+ result = item.song().toString(Config.song_in_columns_to_string_format, Config.tags_separator);
break;
}
break;
case MPD::Item::Type::Playlist:
- result = Config.browser_playlist_prefix.str() + getBasename(item.name);
+ result = Config.browser_playlist_prefix.str();
+ result += getBasename(item.playlist().path());
break;
}
return result;
}
-bool BrowserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter)
+bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter)
{
- if (Browser::isParentDirectory(item))
+ if (isItemParentDirectory(item))
return filter;
- return boost::regex_search(ItemToString(item), rx);
+ return boost::regex_search(itemToString(item), rx);
}
}