implement ProxySongList for handling general operations on lists
This commit is contained in:
@@ -72,6 +72,7 @@ noinst_HEADERS = \
|
||||
mutable_song.h \
|
||||
outputs.h \
|
||||
playlist_editor.h \
|
||||
proxy_song_list.h \
|
||||
regex_filter.h \
|
||||
regexes.h \
|
||||
screen.h \
|
||||
|
||||
183
src/actions.cpp
183
src/actions.cpp
@@ -508,84 +508,96 @@ void ScrollDown::Run()
|
||||
ListsChangeFinisher();
|
||||
}
|
||||
|
||||
bool ScrollUpArtist::canBeRun() const
|
||||
{
|
||||
return proxySongList(myScreen).get();
|
||||
}
|
||||
|
||||
void ScrollUpArtist::Run()
|
||||
{
|
||||
// FIXME
|
||||
/*List *mList = myScreen->GetList();
|
||||
if (!mList || mList->Empty())
|
||||
return;
|
||||
size_t pos = mList->Choice();
|
||||
if (MPD::Song *s = myScreen->GetSong(pos))
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
size_t pos = pl->choice();
|
||||
if (MPD::Song *s = pl->getSong(pos))
|
||||
{
|
||||
std::string artist = s->getArtist();
|
||||
while (pos > 0)
|
||||
{
|
||||
s = myScreen->GetSong(--pos);
|
||||
myScreen->Scroll(wUp);
|
||||
s = pl->getSong(--pos);
|
||||
if (!s || s->getArtist() != artist)
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
pl->highlight(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollUpAlbum::canBeRun() const
|
||||
{
|
||||
return proxySongList(myScreen).get();
|
||||
}
|
||||
|
||||
void ScrollUpAlbum::Run()
|
||||
{
|
||||
// FIXME
|
||||
/*List *mList = myScreen->GetList();
|
||||
if (!mList || mList->Empty())
|
||||
return;
|
||||
size_t pos = mList->Choice();
|
||||
if (MPD::Song *s = myScreen->GetSong(pos))
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
size_t pos = pl->choice();
|
||||
if (MPD::Song *s = pl->getSong(pos))
|
||||
{
|
||||
std::string album = s->getAlbum();
|
||||
while (pos > 0)
|
||||
{
|
||||
s = myScreen->GetSong(--pos);
|
||||
myScreen->Scroll(wUp);
|
||||
s = pl->getSong(--pos);
|
||||
if (!s || s->getAlbum() != album)
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
pl->highlight(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollDownArtist::canBeRun() const
|
||||
{
|
||||
return proxySongList(myScreen).get();
|
||||
}
|
||||
|
||||
void ScrollDownArtist::Run()
|
||||
{
|
||||
// FIXME
|
||||
/*List *mList = myScreen->GetList();
|
||||
if (!mList || mList->Empty())
|
||||
return;
|
||||
size_t pos = mList->Choice();
|
||||
if (MPD::Song *s = myScreen->GetSong(pos))
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
size_t pos = pl->choice();
|
||||
if (MPD::Song *s = pl->getSong(pos))
|
||||
{
|
||||
std::string artist = s->getArtist();
|
||||
while (pos < mList->Size() - 1)
|
||||
while (pos < pl->size() - 1)
|
||||
{
|
||||
s = myScreen->GetSong(++pos);
|
||||
myScreen->Scroll(wDown);
|
||||
s = pl->getSong(++pos);
|
||||
if (!s || s->getArtist() != artist)
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
pl->highlight(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollDownAlbum::canBeRun() const
|
||||
{
|
||||
return proxySongList(myScreen).get();
|
||||
}
|
||||
|
||||
void ScrollDownAlbum::Run()
|
||||
{
|
||||
// FIXME
|
||||
/*List *mList = myScreen->GetList();
|
||||
if (!mList || mList->Empty())
|
||||
return;
|
||||
size_t pos = mList->Choice();
|
||||
if (MPD::Song *s = myScreen->GetSong(pos))
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
size_t pos = pl->choice();
|
||||
if (MPD::Song *s = pl->getSong(pos))
|
||||
{
|
||||
std::string album = s->getAlbum();
|
||||
while (pos < mList->Size() - 1)
|
||||
while (pos < pl->size() - 1)
|
||||
{
|
||||
s = myScreen->GetSong(++pos);
|
||||
myScreen->Scroll(wDown);
|
||||
s = pl->getSong(++pos);
|
||||
if (!s || s->getAlbum() != album)
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
pl->highlight(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void PageUp::Run()
|
||||
@@ -1384,8 +1396,7 @@ void SetCrossfade::Run()
|
||||
bool EditSong::canBeRun() const
|
||||
{
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->currentSong();
|
||||
return currentSong(myScreen);
|
||||
# else
|
||||
return false;
|
||||
# endif // HAVE_TAGLIB_H
|
||||
@@ -1396,9 +1407,7 @@ void EditSong::Run()
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
if (!isMPDMusicDirSet())
|
||||
return;
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
assert(w);
|
||||
auto s = w->currentSong();
|
||||
auto s = currentSong(myScreen);
|
||||
assert(s);
|
||||
myTinyTagEditor->SetEdited(*s);
|
||||
myTinyTagEditor->SwitchTo();
|
||||
@@ -1641,29 +1650,24 @@ void EditLyrics::Run()
|
||||
|
||||
bool JumpToBrowser::canBeRun() const
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->currentSong();
|
||||
return currentSong(myScreen);
|
||||
}
|
||||
|
||||
void JumpToBrowser::Run()
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
auto s = w->currentSong();
|
||||
auto s = currentSong(myScreen);
|
||||
assert(s);
|
||||
myBrowser->LocateSong(*s);
|
||||
}
|
||||
|
||||
bool JumpToMediaLibrary::canBeRun() const
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->currentSong();
|
||||
return currentSong(myScreen);
|
||||
}
|
||||
|
||||
void JumpToMediaLibrary::Run()
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
assert(w);
|
||||
auto s = w->currentSong();
|
||||
auto s = currentSong(myScreen);
|
||||
assert(s);
|
||||
myLibrary->LocateSong(*s);
|
||||
}
|
||||
@@ -1719,8 +1723,7 @@ void ToggleScreenLock::Run()
|
||||
bool JumpToTagEditor::canBeRun() const
|
||||
{
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->currentSong();
|
||||
return currentSong(myScreen);
|
||||
# else
|
||||
return false;
|
||||
# endif // HAVE_TAGLIB_H
|
||||
@@ -1731,9 +1734,7 @@ void JumpToTagEditor::Run()
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
if (!isMPDMusicDirSet())
|
||||
return;
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
assert(w);
|
||||
auto s = w->currentSong();
|
||||
auto s = currentSong(myScreen);
|
||||
assert(s);
|
||||
myTagEditor->LocateSong(*s);
|
||||
# endif // HAVE_TAGLIB_H
|
||||
@@ -1794,13 +1795,13 @@ void JumpToPositionInSong::Run()
|
||||
|
||||
bool ReverseSelection::canBeRun() const
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
auto w = hasSongs(myScreen);
|
||||
return w && w->allowsSelection();
|
||||
}
|
||||
|
||||
void ReverseSelection::Run()
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
auto w = hasSongs(myScreen);
|
||||
assert(w);
|
||||
w->reverseSelection();
|
||||
ShowMessage("Selection reversed");
|
||||
@@ -1808,58 +1809,54 @@ void ReverseSelection::Run()
|
||||
|
||||
bool DeselectItems::canBeRun() const
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->allowsSelection();
|
||||
return proxySongList(myScreen).get();
|
||||
}
|
||||
|
||||
void DeselectItems::Run()
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
assert(w);
|
||||
w->removeSelection();
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
for (size_t i = 0; i < pl->size(); ++i)
|
||||
pl->setSelected(i, false);
|
||||
}
|
||||
|
||||
bool SelectAlbum::canBeRun() const
|
||||
{
|
||||
auto w = dynamic_cast<HasSongs *>(myScreen);
|
||||
return w && w->allowsSelection()
|
||||
&& myScreen->GetList();
|
||||
auto w = hasSongs(myScreen);
|
||||
return w && w->allowsSelection() && w->getProxySongList().get();
|
||||
}
|
||||
|
||||
void SelectAlbum::Run()
|
||||
{
|
||||
// FIXME
|
||||
/*List *mList = myScreen->GetList();
|
||||
assert(mList);
|
||||
size_t pos = mList->Choice();
|
||||
if (MPD::Song *s = myScreen->GetSong(pos))
|
||||
auto pl = proxySongList(myScreen);
|
||||
assert(pl);
|
||||
size_t pos = pl->choice();
|
||||
if (MPD::Song *s = pl->getSong(pos))
|
||||
{
|
||||
std::string album = s->getAlbum();
|
||||
|
||||
// select song under cursor
|
||||
mList->Select(pos, 1);
|
||||
pl->setSelected(pos, true);
|
||||
// go up
|
||||
while (pos > 0)
|
||||
{
|
||||
s = myScreen->GetSong(--pos);
|
||||
s = pl->getSong(--pos);
|
||||
if (!s || s->getAlbum() != album)
|
||||
break;
|
||||
else
|
||||
mList->Select(pos, 1);
|
||||
pl->setSelected(pos, true);
|
||||
}
|
||||
// go down
|
||||
pos = mList->Choice();
|
||||
while (pos < mList->Size() - 1)
|
||||
pos = pl->choice();
|
||||
while (pos < pl->size() - 1)
|
||||
{
|
||||
s = myScreen->GetSong(++pos);
|
||||
s = pl->getSong(++pos);
|
||||
if (!s || s->getAlbum() != album)
|
||||
break;
|
||||
else
|
||||
mList->Select(pos, 1);
|
||||
pl->setSelected(pos, true);
|
||||
}
|
||||
ShowMessage("Album around cursor position selected");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void AddSelectedItems::Run()
|
||||
@@ -2354,7 +2351,11 @@ void ShowSongInfo::Run()
|
||||
bool ShowArtistInfo::canBeRun() const
|
||||
{
|
||||
#ifdef HAVE_CURL_CURL_H
|
||||
return myScreen == myLastfm || dynamic_cast<HasSongs *>(myScreen);
|
||||
return myScreen == myLastfm
|
||||
|| (myScreen->ActiveWindow() == myLibrary->Tags
|
||||
&& !myLibrary->Tags->Empty()
|
||||
&& Config.media_lib_primary_tag == MPD_TAG_ARTIST)
|
||||
|| currentSong(myScreen);
|
||||
# else
|
||||
return false;
|
||||
# endif // NOT HAVE_CURL_CURL_H
|
||||
@@ -2370,14 +2371,18 @@ void ShowArtistInfo::Run()
|
||||
}
|
||||
|
||||
std::string artist;
|
||||
auto hs = dynamic_cast<HasSongs *>(myScreen);
|
||||
assert(hs);
|
||||
auto s = hs->currentSong();
|
||||
|
||||
if (s)
|
||||
artist = s->getArtist();
|
||||
else if (myScreen == myLibrary && myLibrary->Main() == myLibrary->Tags && !myLibrary->Tags->Empty())
|
||||
if (myScreen->ActiveWindow() == myLibrary->Tags)
|
||||
{
|
||||
assert(!myLibrary->Tags->Empty());
|
||||
assert(Config.media_lib_primary_tag == MPD_TAG_ARTIST);
|
||||
artist = myLibrary->Tags->Current().value();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = currentSong(myScreen);
|
||||
assert(s);
|
||||
artist = s->getArtist();
|
||||
}
|
||||
|
||||
if (!artist.empty() && myLastfm->SetArtistInfoArgs(artist, Config.lastfm_preferred_language))
|
||||
myLastfm->SwitchTo();
|
||||
|
||||
@@ -168,24 +168,28 @@ struct ScrollDown : public Action
|
||||
struct ScrollUpArtist : public Action
|
||||
{
|
||||
ScrollUpArtist() : Action(aScrollUpArtist, "scroll_up_artist") { }
|
||||
virtual bool canBeRun() const;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
struct ScrollUpAlbum : public Action
|
||||
{
|
||||
ScrollUpAlbum() : Action(aScrollUpAlbum, "scroll_up_album") { }
|
||||
virtual bool canBeRun() const;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
struct ScrollDownArtist : public Action
|
||||
{
|
||||
ScrollDownArtist() : Action(aScrollDownArtist, "scroll_down_artist") { }
|
||||
virtual bool canBeRun() const;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
struct ScrollDownAlbum : public Action
|
||||
{
|
||||
ScrollDownAlbum() : Action(aScrollDownAlbum, "scroll_down_album") { }
|
||||
virtual bool canBeRun() const;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
|
||||
@@ -301,6 +301,16 @@ void Browser::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
std::shared_ptr<ProxySongList> Browser::getProxySongList()
|
||||
{
|
||||
return mkProxySongList(*w, [](NC::Menu<MPD::Item>::Item &item) {
|
||||
MPD::Song *ptr = 0;
|
||||
if (item.value().type == itSong)
|
||||
ptr = item.value().song.get();
|
||||
return ptr;
|
||||
});
|
||||
}
|
||||
|
||||
MPD::Song *Browser::getSong(size_t pos)
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
@@ -322,11 +332,6 @@ bool Browser::allowsSelection()
|
||||
return true;
|
||||
}
|
||||
|
||||
void Browser::removeSelection()
|
||||
{
|
||||
removeSelectionHelper(w->Begin(), w->End());
|
||||
}
|
||||
|
||||
void Browser::reverseSelection()
|
||||
{
|
||||
reverseSelectionHelper(w->Begin()+(itsBrowsedDir == "/" ? 0 : 1), w->End());
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define _BROWSER_H
|
||||
|
||||
#include "interfaces.h"
|
||||
#include "mpdpp.h"
|
||||
#include "screen.h"
|
||||
|
||||
class Browser : public Screen< NC::Menu<MPD::Item> >, public Filterable, public HasSongs, public Searchable
|
||||
@@ -51,10 +52,10 @@ class Browser : public Screen< NC::Menu<MPD::Item> >, public Filterable, public
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual NC::List *GetList() { return w; }
|
||||
|
||||
@@ -79,7 +79,9 @@ void setProperties(NC::Menu<T> &menu, const MPD::Song &s, HasSongs &screen, bool
|
||||
separate_albums = false;
|
||||
if (Config.playlist_separate_albums)
|
||||
{
|
||||
auto next = screen.getSong(menu.DrawnPosition()+1);
|
||||
auto pl = screen.getProxySongList();
|
||||
assert(pl);
|
||||
auto next = pl->getSong(menu.DrawnPosition()+1);
|
||||
if (next && next->getAlbum() != s.getAlbum())
|
||||
separate_albums = true;
|
||||
}
|
||||
|
||||
@@ -32,10 +32,22 @@ inline HasSongs *hasSongs(BasicScreen *screen)
|
||||
return dynamic_cast<HasSongs *>(screen);
|
||||
}
|
||||
|
||||
template <typename Iterator> void removeSelectionHelper(Iterator first, Iterator last)
|
||||
inline std::shared_ptr<ProxySongList> proxySongList(BasicScreen *screen)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
first->setSelected(false);
|
||||
auto ptr = nullProxySongList();
|
||||
auto hs = hasSongs(screen);
|
||||
if (hs)
|
||||
ptr = hs->getProxySongList();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline MPD::Song *currentSong(BasicScreen *screen)
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
auto pl = proxySongList(screen);
|
||||
if (pl)
|
||||
ptr = pl->currentSong();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename Iterator> void reverseSelectionHelper(Iterator first, Iterator last)
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
#define _INTERFACES_H
|
||||
|
||||
#include <string>
|
||||
#include "mpdpp.h"
|
||||
#include "gcc.h"
|
||||
#include "song.h"
|
||||
#include "proxy_song_list.h"
|
||||
|
||||
struct Filterable
|
||||
{
|
||||
@@ -40,12 +41,10 @@ struct Searchable
|
||||
|
||||
struct HasSongs
|
||||
{
|
||||
virtual MPD::Song *getSong(size_t pos) = 0;
|
||||
virtual MPD::Song *currentSong() = 0;
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList() = 0;
|
||||
|
||||
virtual bool allowsSelection() = 0;
|
||||
virtual void reverseSelection() = 0;
|
||||
virtual void removeSelection() = 0;
|
||||
virtual MPD::SongList getSelectedSongs() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -117,28 +117,26 @@ void Lyrics::SwitchTo()
|
||||
}
|
||||
# endif // HAVE_CURL_CURL_H
|
||||
|
||||
auto hs = dynamic_cast<HasSongs *>(myScreen);
|
||||
if (!hs)
|
||||
const MPD::Song *s = currentSong(myScreen);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
if (const MPD::Song *s = hs->currentSong())
|
||||
if (!s->getArtist().empty() && !s->getTitle().empty())
|
||||
{
|
||||
if (!s->getArtist().empty() && !s->getTitle().empty())
|
||||
{
|
||||
myOldScreen = myScreen;
|
||||
myScreen = this;
|
||||
myOldScreen = myScreen;
|
||||
myScreen = this;
|
||||
|
||||
itsSong = *s;
|
||||
Load();
|
||||
itsSong = *s;
|
||||
Load();
|
||||
|
||||
Global::RedrawHeader = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMessage("Song must have both artist and title tag set");
|
||||
return;
|
||||
}
|
||||
Global::RedrawHeader = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMessage("Song must have both artist and title tag set");
|
||||
return;
|
||||
}
|
||||
|
||||
// if we resize for locked screen, we have to do that in the end since
|
||||
// fetching lyrics may fail (eg. if tags are missing) and we don't want
|
||||
// to adjust screen size then.
|
||||
|
||||
@@ -531,37 +531,21 @@ void MediaLibrary::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
MPD::Song *MediaLibrary::getSong(size_t pos)
|
||||
std::shared_ptr<ProxySongList> MediaLibrary::getProxySongList()
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
auto ptr = nullProxySongList();
|
||||
if (w == Songs)
|
||||
ptr = &(*Songs)[pos].value();
|
||||
ptr = mkProxySongList(*Songs, [](NC::Menu<MPD::Song>::Item &item) {
|
||||
return &item.value();
|
||||
});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MPD::Song *MediaLibrary::currentSong()
|
||||
{
|
||||
if (w == Songs && !Songs->Empty())
|
||||
return getSong(Songs->Choice());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MediaLibrary::allowsSelection()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void MediaLibrary::removeSelection()
|
||||
{
|
||||
if (w == Tags)
|
||||
removeSelectionHelper(Tags->Begin(), Tags->End());
|
||||
else if (w == Albums)
|
||||
removeSelectionHelper(Albums->Begin(), Albums->End());
|
||||
else if (w == Songs)
|
||||
removeSelectionHelper(Songs->Begin(), Songs->End());
|
||||
}
|
||||
|
||||
void MediaLibrary::reverseSelection()
|
||||
{
|
||||
if (w == Tags)
|
||||
|
||||
@@ -50,12 +50,10 @@ class MediaLibrary : public Screen<NC::Window>, public Filterable, public HasSon
|
||||
virtual void prevFound(bool wrap);
|
||||
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual NC::List *GetList();
|
||||
|
||||
@@ -1193,7 +1193,7 @@ MPD::ItemList MPD::Connection::GetDirectory(const std::string &path)
|
||||
it.type = itDirectory;
|
||||
break;
|
||||
case MPD_ENTITY_TYPE_SONG:
|
||||
it.song = std::shared_ptr<Song>(new Song(mpd_song_dup(mpd_entity_get_song(item))));
|
||||
it.song = std::make_shared<Song>(Song(mpd_song_dup(mpd_entity_get_song(item))));
|
||||
it.type = itSong;
|
||||
break;
|
||||
case MPD_ENTITY_TYPE_PLAYLIST:
|
||||
|
||||
@@ -318,6 +318,16 @@ void Playlist::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
std::shared_ptr<ProxySongList> Playlist::getProxySongList()
|
||||
{
|
||||
auto ptr = nullProxySongList();
|
||||
if (w == Items)
|
||||
ptr = mkProxySongList(*Items, [](NC::Menu<MPD::Song>::Item &item) {
|
||||
return &item.value();
|
||||
});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MPD::Song *Playlist::getSong(size_t pos)
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
@@ -339,11 +349,6 @@ bool Playlist::allowsSelection()
|
||||
return w == Items;
|
||||
}
|
||||
|
||||
void Playlist::removeSelection()
|
||||
{
|
||||
removeSelectionHelper(Items->Begin(), Items->End());
|
||||
}
|
||||
|
||||
void Playlist::reverseSelection()
|
||||
{
|
||||
reverseSelectionHelper(Items->Begin(), Items->End());
|
||||
|
||||
@@ -55,10 +55,10 @@ class Playlist : public Screen<NC::Window>, public Filterable, public HasSongs,
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual NC::List *GetList() { return w == Items ? Items : 0; }
|
||||
|
||||
@@ -486,35 +486,21 @@ void PlaylistEditor::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
MPD::Song *PlaylistEditor::getSong(size_t pos)
|
||||
std::shared_ptr<ProxySongList> PlaylistEditor::getProxySongList()
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
auto ptr = nullProxySongList();
|
||||
if (w == Content)
|
||||
ptr = &(*Content)[pos].value();
|
||||
ptr = mkProxySongList(*Content, [](NC::Menu<MPD::Song>::Item &item) {
|
||||
return &item.value();
|
||||
});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MPD::Song *PlaylistEditor::currentSong()
|
||||
{
|
||||
if (w == Content && !Content->Empty())
|
||||
return getSong(Content->Choice());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PlaylistEditor::allowsSelection()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlaylistEditor::removeSelection()
|
||||
{
|
||||
if (w == Playlists)
|
||||
removeSelectionHelper(Playlists->Begin(), Playlists->End());
|
||||
else if (w == Content)
|
||||
removeSelectionHelper(Content->Begin(), Content->End());
|
||||
}
|
||||
|
||||
void PlaylistEditor::reverseSelection()
|
||||
{
|
||||
if (w == Playlists)
|
||||
|
||||
@@ -49,12 +49,10 @@ class PlaylistEditor : public Screen<NC::Window>, public Filterable, public HasS
|
||||
virtual void prevFound(bool wrap);
|
||||
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual void Locate(const std::string &);
|
||||
|
||||
110
src/proxy_song_list.h
Normal file
110
src/proxy_song_list.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2008-2012 by Andrzej Rybczak *
|
||||
* electricityispower@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _PROXY_SONG_LIST
|
||||
#define _PROXY_SONG_LIST
|
||||
|
||||
#include "menu.h"
|
||||
#include "song.h"
|
||||
|
||||
class ProxySongList
|
||||
{
|
||||
struct Interface
|
||||
{
|
||||
virtual ~Interface() { }
|
||||
|
||||
virtual bool empty() = 0;
|
||||
virtual size_t size() = 0;
|
||||
virtual size_t choice() = 0;
|
||||
virtual void highlight(size_t pos) = 0;
|
||||
|
||||
virtual bool isSelected(size_t pos) = 0;
|
||||
virtual void setSelected(size_t pos, bool selected) = 0;
|
||||
|
||||
virtual MPD::Song *getSong(size_t pos) = 0;
|
||||
virtual MPD::Song *currentSong() = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename F> struct Impl : Interface
|
||||
{
|
||||
typedef typename NC::Menu<T> Menu;
|
||||
|
||||
Impl(Menu &menu, F f) : m_menu(menu), m_song_getter(f) { }
|
||||
virtual ~Impl() { }
|
||||
|
||||
virtual bool empty() { return m_menu.Empty(); }
|
||||
virtual size_t size() { return m_menu.Size(); }
|
||||
virtual size_t choice() { return m_menu.Choice(); }
|
||||
virtual void highlight(size_t pos) { m_menu.Highlight(pos); }
|
||||
|
||||
virtual bool isSelected(size_t pos) {
|
||||
return m_menu[pos].isSelected();
|
||||
}
|
||||
|
||||
virtual void setSelected(size_t pos, bool selected) {
|
||||
m_menu[pos].setSelected(selected);
|
||||
}
|
||||
|
||||
virtual MPD::Song *getSong(size_t pos) {
|
||||
return m_song_getter(m_menu[pos]);
|
||||
}
|
||||
|
||||
virtual MPD::Song *currentSong() {
|
||||
if (!m_menu.Empty())
|
||||
return getSong(m_menu.Choice());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Menu &m_menu;
|
||||
F m_song_getter;
|
||||
};
|
||||
|
||||
std::shared_ptr<Interface> m_impl;
|
||||
|
||||
public:
|
||||
template <typename T, typename F>
|
||||
ProxySongList(typename NC::Menu<T> &menu, F f) : m_impl(new Impl<T, F>(menu, f)) { }
|
||||
|
||||
bool empty() { return m_impl->empty(); }
|
||||
size_t size() { return m_impl->size(); }
|
||||
size_t choice() { return m_impl->choice(); }
|
||||
void highlight(size_t pos) { m_impl->highlight(pos); }
|
||||
|
||||
bool isSelected(size_t pos) { return m_impl->isSelected(pos); }
|
||||
void setSelected(size_t pos, bool selected) { m_impl->setSelected(pos, selected); }
|
||||
|
||||
MPD::Song *getSong(size_t pos) { return m_impl->getSong(pos); }
|
||||
MPD::Song *currentSong() { return m_impl->currentSong(); }
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
std::shared_ptr<ProxySongList> mkProxySongList(typename NC::Menu<T> &menu, F f)
|
||||
{
|
||||
return std::make_shared<ProxySongList>(ProxySongList(menu, f));
|
||||
}
|
||||
|
||||
inline std::shared_ptr<ProxySongList> nullProxySongList()
|
||||
{
|
||||
return std::shared_ptr<ProxySongList>();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -314,21 +314,14 @@ void SearchEngine::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
MPD::Song *SearchEngine::getSong(size_t pos)
|
||||
std::shared_ptr< ProxySongList > SearchEngine::getProxySongList()
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
auto &item = (*w)[pos];
|
||||
if (!item.isSeparator() && item.value().isSong())
|
||||
ptr = &item.value().song();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MPD::Song *SearchEngine::currentSong()
|
||||
{
|
||||
if (w->Empty())
|
||||
return 0;
|
||||
else
|
||||
return getSong(w->Choice());
|
||||
return mkProxySongList(*w, [](NC::Menu<SEItem>::Item &item) {
|
||||
MPD::Song *ptr = 0;
|
||||
if (!item.isSeparator() && item.value().isSong())
|
||||
ptr = &item.value().song();
|
||||
return ptr;
|
||||
});
|
||||
}
|
||||
|
||||
bool SearchEngine::allowsSelection()
|
||||
@@ -336,11 +329,6 @@ bool SearchEngine::allowsSelection()
|
||||
return w->Current().value().isSong();
|
||||
}
|
||||
|
||||
void SearchEngine::removeSelection()
|
||||
{
|
||||
removeSelectionHelper(w->Begin(), w->End());
|
||||
}
|
||||
|
||||
void SearchEngine::reverseSelection()
|
||||
{
|
||||
reverseSelectionHelper(w->Begin()+std::min(StaticOptions, w->Size()), w->End());
|
||||
|
||||
@@ -96,12 +96,10 @@ class SearchEngine : public Screen< NC::Menu<SEItem> >, public Filterable, publi
|
||||
virtual void prevFound(bool wrap);
|
||||
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual NC::List *GetList() { return w->Size() >= StaticOptions ? w : 0; }
|
||||
|
||||
@@ -84,10 +84,7 @@ void SongInfo::SwitchTo()
|
||||
if (myLockedScreen)
|
||||
UpdateInactiveScreen(this);
|
||||
|
||||
auto hs = dynamic_cast<HasSongs *>(myScreen);
|
||||
if (!hs)
|
||||
return;
|
||||
auto s = hs->currentSong();
|
||||
auto s = currentSong(myScreen);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
|
||||
@@ -854,33 +854,21 @@ void TagEditor::prevFound(bool wrap)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
MPD::Song *TagEditor::getSong(size_t pos)
|
||||
std::shared_ptr<ProxySongList> TagEditor::getProxySongList()
|
||||
{
|
||||
MPD::Song *ptr = 0;
|
||||
auto ptr = nullProxySongList();
|
||||
if (w == Tags)
|
||||
ptr = &(*Tags)[pos].value();
|
||||
ptr = mkProxySongList(*Tags, [](NC::Menu<MPD::MutableSong>::Item &item) {
|
||||
return &item.value();
|
||||
});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
MPD::Song *TagEditor::currentSong()
|
||||
{
|
||||
if (w == Tags && !Tags->Empty())
|
||||
return getSong(Tags->Choice());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TagEditor::allowsSelection()
|
||||
{
|
||||
return w == Tags;
|
||||
}
|
||||
|
||||
void TagEditor::removeSelection()
|
||||
{
|
||||
if (w == Tags)
|
||||
removeSelectionHelper(Tags->Begin(), Tags->End());
|
||||
}
|
||||
|
||||
void TagEditor::reverseSelection()
|
||||
{
|
||||
if (w == Tags)
|
||||
|
||||
@@ -61,12 +61,10 @@ class TagEditor : public Screen<NC::Window>, public Filterable, public HasSongs,
|
||||
virtual void prevFound(bool wrap);
|
||||
|
||||
/// HasSongs implementation
|
||||
virtual MPD::Song *getSong(size_t pos);
|
||||
virtual MPD::Song *currentSong();
|
||||
virtual std::shared_ptr<ProxySongList> getProxySongList();
|
||||
|
||||
virtual bool allowsSelection();
|
||||
virtual void reverseSelection();
|
||||
virtual void removeSelection();
|
||||
virtual MPD::SongList getSelectedSongs();
|
||||
|
||||
virtual NC::List *GetList();
|
||||
|
||||
Reference in New Issue
Block a user