From 30d57afcace02b6347cd5e644bd0a987717237fc Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sat, 1 Nov 2014 23:16:06 +0100 Subject: [PATCH] playlist editor: hold MPD::PlaylistS instead of std::stringS --- src/actions.cpp | 20 ++++++++++---------- src/mpdpp.cpp | 10 +++++----- src/mpdpp.h | 5 +++-- src/playlist_editor.cpp | 36 ++++++++++++++++++------------------ src/playlist_editor.h | 2 +- src/sel_items_adder.cpp | 9 +++++---- src/utility/comparators.cpp | 6 ++---- src/utility/comparators.h | 15 +++++++++++++-- 8 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 744e6a82..9f391424 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -642,7 +642,7 @@ void DeletePlaylistItems::run() } else if (myScreen->isActiveWindow(myPlaylistEditor->Content)) { - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); auto delete_fun = boost::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2); Statusbar::print("Deleting items..."); deleteSelectedSongs(myPlaylistEditor->Content, delete_fun); @@ -726,7 +726,7 @@ void DeleteStoredPlaylist::run() question = boost::format("Delete selected playlists?"); else question = boost::format("Delete playlist \"%1%\"?") - % wideShorten(myPlaylistEditor->Playlists.current().value(), COLS-question.size()-10); + % wideShorten(myPlaylistEditor->Playlists.current().value().path(), COLS-question.size()-10); confirmAction(question); auto list = getSelectedOrCurrent( myPlaylistEditor->Playlists.begin(), @@ -734,7 +734,7 @@ void DeleteStoredPlaylist::run() myPlaylistEditor->Playlists.currentI() ); for (const auto &item : list) - Mpd.DeletePlaylist(item->value()); + Mpd.DeletePlaylist(item->value().path()); Statusbar::printf("%1% deleted", list.size() == 1 ? "Playlist" : "Playlists"); // force playlists update. this happens automatically, but only after call // to Key::read, therefore when we call PlaylistEditor::Update, it won't @@ -880,7 +880,7 @@ void MoveSelectedItemsUp::run() else if (myScreen == myPlaylistEditor) { assert(!myPlaylistEditor->Playlists.empty()); - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); auto move_fun = boost::bind(&MPD::Connection::PlaylistMove, _1, playlist, _2, _3); moveSelectedItemsUp(myPlaylistEditor->Content, move_fun); } @@ -905,7 +905,7 @@ void MoveSelectedItemsDown::run() else if (myScreen == myPlaylistEditor) { assert(!myPlaylistEditor->Playlists.empty()); - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); auto move_fun = boost::bind(&MPD::Connection::PlaylistMove, _1, playlist, _2, _3); moveSelectedItemsDown(myPlaylistEditor->Content, move_fun); } @@ -927,7 +927,7 @@ void MoveSelectedItemsTo::run() else { assert(!myPlaylistEditor->Playlists.empty()); - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); auto move_fun = boost::bind(&MPD::Connection::PlaylistMove, _1, playlist, _2, _3); moveSelectedItemsTo(myPlaylistEditor->Content, move_fun); } @@ -953,7 +953,7 @@ void Add::run() Statusbar::put() << "Adding..."; wFooter->refresh(); if (myScreen == myPlaylistEditor) - Mpd.AddToPlaylist(myPlaylistEditor->Playlists.current().value(), path); + Mpd.AddToPlaylist(myPlaylistEditor->Playlists.current().value().path(), path); else { const char lastfm_url[] = "lastfm://"; @@ -1504,7 +1504,7 @@ void EditPlaylistName::run() // FIXME: support local browser more generally std::string old_name, new_name; if (myScreen->isActiveWindow(myPlaylistEditor->Playlists)) - old_name = myPlaylistEditor->Playlists.current().value(); + old_name = myPlaylistEditor->Playlists.current().value().path(); else old_name = myBrowser->main().current().value().name; { @@ -1759,7 +1759,7 @@ void CropPlaylist::run() if (w.size() <= 1) return; assert(!myPlaylistEditor->Playlists.empty()); - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); if (Config.ask_before_clearing_playlists) confirmAction(boost::format("Do you really want to crop playlist \"%1%\"?") % playlist); selectCurrentIfNoneSelected(w); @@ -1789,7 +1789,7 @@ void ClearPlaylist::run() { if (myPlaylistEditor->Playlists.empty()) return; - std::string playlist = myPlaylistEditor->Playlists.current().value(); + std::string playlist = myPlaylistEditor->Playlists.current().value().path(); if (Config.ask_before_clearing_playlists) confirmAction(boost::format("Do you really want to clear playlist \"%1%\"?") % playlist); auto delete_fun = boost::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2); diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index ee832a31..48241f39 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -604,12 +604,12 @@ void Connection::SavePlaylist(const std::string &name) checkErrors(); } -void Connection::GetPlaylists(StringConsumer f) +PlaylistIterator Connection::GetPlaylists() { - GetDirectory("/", [&f](Item &&item) { - if (item.type == MPD::Item::Type::Playlist) - f(std::move(item.name)); - }); + prechecksNoCommandsList(); + mpd_send_list_playlists(m_connection.get()); + checkErrors(); + return PlaylistIterator(m_connection.get(), mpd_recv_playlist); } void Connection::GetList(mpd_tag_type type, StringConsumer f) diff --git a/src/mpdpp.h b/src/mpdpp.h index 1a51e365..291983a6 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -305,8 +305,9 @@ private: DestT m_object; }; -typedef Iterator SongIterator; typedef Iterator OutputIterator; +typedef Iterator PlaylistIterator; +typedef Iterator SongIterator; class Connection { @@ -402,7 +403,7 @@ public: SongIterator CommitSearchSongs(); void CommitSearchTags(StringConsumer f); - void GetPlaylists(StringConsumer f); + PlaylistIterator GetPlaylists(); void GetList(mpd_tag_type type, StringConsumer f); void GetDirectory(const std::string &directory, ItemConsumer f); void GetDirectoryRecursive(const std::string &directory, SongConsumer f); diff --git a/src/playlist_editor.cpp b/src/playlist_editor.cpp index 86feb7c9..d9b53ad4 100644 --- a/src/playlist_editor.cpp +++ b/src/playlist_editor.cpp @@ -51,7 +51,7 @@ size_t RightColumnStartX; size_t RightColumnWidth; std::string SongToString(const MPD::Song &s); -bool PlaylistEntryMatcher(const boost::regex &rx, const std::string &playlist); +bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist); bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s); } @@ -65,14 +65,14 @@ PlaylistEditor::PlaylistEditor() RightColumnStartX = LeftColumnWidth+1; RightColumnWidth = COLS-LeftColumnWidth-1; - Playlists = NC::Menu(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Playlists" : "", Config.main_color, NC::Border::None); + Playlists = NC::Menu(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Playlists" : "", Config.main_color, NC::Border::None); Playlists.setHighlightColor(Config.active_column_color); Playlists.cyclicScrolling(Config.use_cyclic_scrolling); Playlists.centeredCursor(Config.centered_cursor); Playlists.setSelectedPrefix(Config.selected_item_prefix); Playlists.setSelectedSuffix(Config.selected_item_suffix); - Playlists.setItemDisplayer([](NC::Menu &menu) { - menu << Charset::utf8ToLocale(menu.drawn()->value()); + Playlists.setItemDisplayer([](NC::Menu &menu) { + menu << Charset::utf8ToLocale(menu.drawn()->value().path()); }); Content = NC::Menu(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Playlist content" : "", Config.main_color, NC::Border::None); @@ -141,13 +141,13 @@ void PlaylistEditor::update() Playlists.clearSearchResults(); withUnfilteredMenuReapplyFilter(Playlists, [this]() { size_t idx = 0; - Mpd.GetPlaylists([this, &idx](std::string playlist) { + for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it, ++idx) + { if (idx < Playlists.size()) - Playlists[idx].value() = playlist; + Playlists[idx].value() = std::move(*it); else - Playlists.addItem(playlist); - ++idx; - }); + Playlists.addItem(std::move(*it)); + }; if (idx < Playlists.size()) Playlists.resizeList(idx); std::sort(Playlists.beginV(), Playlists.endV(), @@ -167,7 +167,7 @@ void PlaylistEditor::update() Content.clearSearchResults(); withUnfilteredMenuReapplyFilter(Content, [this]() { size_t idx = 0; - MPD::SongIterator s = Mpd.GetPlaylistContent(Playlists.current().value()), end; + MPD::SongIterator s = Mpd.GetPlaylistContent(Playlists.current().value().path()), end; for (; s != end; ++s, ++idx) { bool is_bold = myPlaylist->checkForSong(*s); @@ -250,7 +250,7 @@ void PlaylistEditor::AddToPlaylist(bool add_n_play) success = addSongsToPlaylist(Content.beginV(), Content.endV(), add_n_play, -1); }); Statusbar::printf("Playlist \"%1%\" loaded%2%", - Playlists.current().value(), withErrors(success) + Playlists.current().value().path(), withErrors(success) ); } else if (isActiveWindow(Content) && !Content.empty()) @@ -354,7 +354,7 @@ std::string PlaylistEditor::currentFilter() { std::string filter; if (isActiveWindow(Playlists)) - filter = RegexFilter::currentFilter(Playlists); + filter = RegexFilter::currentFilter(Playlists); else if (isActiveWindow(Content)) filter = RegexFilter::currentFilter(Content); return filter; @@ -381,7 +381,7 @@ void PlaylistEditor::applyFilter(const std::string &filter) if (isActiveWindow(Playlists)) { Playlists.showAll(); - auto rx = RegexFilter( + auto rx = RegexFilter( boost::regex(filter, Config.regex_type), PlaylistEntryMatcher); Playlists.filter(Playlists.begin(), Playlists.end(), rx); } @@ -418,7 +418,7 @@ bool PlaylistEditor::search(const std::string &constraint) bool result = false; if (isActiveWindow(Playlists)) { - auto rx = RegexFilter( + auto rx = RegexFilter( boost::regex(constraint, Config.regex_type), PlaylistEntryMatcher); result = Playlists.search(Playlists.begin(), Playlists.end(), rx); } @@ -487,7 +487,7 @@ MPD::SongList PlaylistEditor::getSelectedSongs() { any_selected = true; std::copy( - std::make_move_iterator(Mpd.GetPlaylistContent(e.value())), + std::make_move_iterator(Mpd.GetPlaylistContent(e.value().path())), std::make_move_iterator(MPD::SongIterator()), std::back_inserter(result) ); @@ -569,7 +569,7 @@ void PlaylistEditor::Locate(const std::string &name) update(); for (size_t i = 0; i < Playlists.size(); ++i) { - if (name == Playlists[i].value()) + if (name == Playlists[i].value().path()) { Playlists.highlight(i); Content.clear(); @@ -596,9 +596,9 @@ std::string SongToString(const MPD::Song &s) return result; } -bool PlaylistEntryMatcher(const boost::regex &rx, const std::string &playlist) +bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist) { - return boost::regex_search(playlist, rx); + return boost::regex_search(playlist.path(), rx); } bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s) diff --git a/src/playlist_editor.h b/src/playlist_editor.h index ce5a9943..b4c8af23 100644 --- a/src/playlist_editor.h +++ b/src/playlist_editor.h @@ -82,7 +82,7 @@ struct PlaylistEditor: Screen, Filterable, HasColumns, HasSongs, S bool isContentFiltered(); ProxySongList contentProxyList(); - NC::Menu Playlists; + NC::Menu Playlists; NC::Menu Content; protected: diff --git a/src/sel_items_adder.cpp b/src/sel_items_adder.cpp index db6d17df..0d398283 100644 --- a/src/sel_items_adder.cpp +++ b/src/sel_items_adder.cpp @@ -200,11 +200,12 @@ void SelectedItemsAdder::populatePlaylistSelector(BaseScreen *old_screen) if (!in_local_browser) { size_t begin = m_playlist_selector.size(); - Mpd.GetPlaylists([this](std::string playlist) { - m_playlist_selector.addItem(Entry(playlist, - boost::bind(&Self::addToExistingPlaylist, this, playlist) + for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it) + { + m_playlist_selector.addItem(Entry(it->path(), + boost::bind(&Self::addToExistingPlaylist, this, it->path()) )); - }); + }; std::sort(m_playlist_selector.beginV()+begin, m_playlist_selector.endV(), LocaleBasedSorting(std::locale(), Config.ignore_leading_the)); if (begin < m_playlist_selector.size()) diff --git a/src/utility/comparators.cpp b/src/utility/comparators.cpp index 3414898b..cc4ab321 100644 --- a/src/utility/comparators.cpp +++ b/src/utility/comparators.cpp @@ -35,10 +35,8 @@ bool hasTheWord(const std::string &s) } -int LocaleStringComparison::operator()(const std::string &a, const std::string &b) const +int LocaleStringComparison::compare(const char *a, size_t a_len, const char *b, size_t b_len) const { - const char *ac = a.c_str(); - const char *bc = b.c_str(); size_t ac_off = 0, bc_off = 0; if (m_ignore_the) { @@ -48,7 +46,7 @@ int LocaleStringComparison::operator()(const std::string &a, const std::string & bc_off += 4; } return std::use_facet>(m_locale).compare( - ac+ac_off, ac+a.length(), bc+bc_off, bc+b.length() + a+ac_off, a+a_len, b+bc_off, b+b_len ); } diff --git a/src/utility/comparators.h b/src/utility/comparators.h index 40d88e6f..40fd6109 100644 --- a/src/utility/comparators.h +++ b/src/utility/comparators.h @@ -35,8 +35,15 @@ class LocaleStringComparison public: LocaleStringComparison(const std::locale &loc, bool ignore_the) : m_locale(loc), m_ignore_the(ignore_the) { } - - int operator()(const std::string &a, const std::string &b) const; + + int operator()(const char *a, const char *b) const { + return compare(a, strlen(a), b, strlen(b)); + } + int operator()(const std::string &a, const std::string &b) const { + return compare(a.c_str(), a.length(), b.c_str(), b.length()); + } + + int compare(const char *a, size_t a_len, const char *b, size_t b_len) const; }; class LocaleBasedSorting @@ -50,6 +57,10 @@ public: return m_cmp(a, b) < 0; } + bool operator()(const MPD::Playlist &a, const MPD::Playlist &b) const { + return m_cmp(a.path(), b.path()) < 0; + } + bool operator()(const MPD::Song &a, const MPD::Song &b) const { return m_cmp(a.getName(), b.getName()) < 0; }