diff --git a/doc/keys b/doc/keys index 0cdf9958..7b58233c 100644 --- a/doc/keys +++ b/doc/keys @@ -82,6 +82,8 @@ # #key_update_db = 'u' # +#key_apply_filter = 6 +# #key_find_forward = '/' # #key_find_backward = '?' diff --git a/src/browser.cpp b/src/browser.cpp index 80ff52a3..01467921 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -48,6 +48,7 @@ void Browser::Init() w->SetSelectPrefix(&Config.selected_item_prefix); w->SetSelectSuffix(&Config.selected_item_suffix); w->SetItemDisplayer(Display::Items); + w->SetGetStringFunction(ItemToString); } void Browser::Resize() @@ -437,3 +438,31 @@ void Browser::UpdateItemList() w->Refresh(); } +std::string Browser::ItemToString(const MPD::Item &item, void *) +{ + switch (item.type) + { + case MPD::itDirectory: + { + if (item.song) + return "[..]"; + return "[" + ExtractTopDirectory(item.name) + "]"; + } + case MPD::itSong: + { + if (!Config.columns_in_browser) + return item.song->toString(Config.song_list_format); + else + return Playlist::SongInColumnsToString(*item.song, &Config.song_columns_list_format); + } + case MPD::itPlaylist: + { + return Config.browser_playlist_prefix.Str() + item.name; + } + default: + { + return ""; + } + } +} + diff --git a/src/browser.h b/src/browser.h index 1da91caf..b7c667a9 100644 --- a/src/browser.h +++ b/src/browser.h @@ -44,6 +44,8 @@ class Browser : public Screen< Menu > virtual void ReverseSelection(); virtual void GetSelectedSongs(MPD::SongList &); + virtual void ApplyFilter(const std::string &s) { w->ApplyFilter(s, itsBrowsedDir == "/" ? 0 : 1); } + virtual List *GetList() { return w; } const std::string &CurrentDir() { return itsBrowsedDir; } @@ -53,6 +55,8 @@ class Browser : public Screen< Menu > void UpdateItemList(); protected: + static std::string ItemToString(const MPD::Item &, void *); + size_t itsScrollBeginning; std::string itsBrowsedDir; diff --git a/src/help.cpp b/src/help.cpp index cddab32c..97da3c67 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -168,6 +168,7 @@ void Help::GetKeybindings() *w << DisplayKeys(Key.SetCrossfade) << "Set crossfade\n"; *w << DisplayKeys(Key.UpdateDB) << "Start a music database update\n\n"; + *w << DisplayKeys(Key.ApplyFilter) << "Apply filter\n"; *w << DisplayKeys(Key.FindForward) << "Forward find\n"; *w << DisplayKeys(Key.FindBackward) << "Backward find\n"; *w << DisplayKeys(Key.PrevFoundPosition) << "Go to previous found position\n"; diff --git a/src/helpers.h b/src/helpers.h index bec05e97..d610be52 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -24,6 +24,7 @@ #include "mpdpp.h" #include "ncmpcpp.h" #include "settings.h" +#include "status.h" bool ConnectToMPD(); void ParseArgv(int, char **); diff --git a/src/media_library.cpp b/src/media_library.cpp index 63d929e7..e3167f3d 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -58,6 +58,7 @@ void MediaLibrary::Init() Albums->HighlightColor(Config.main_highlight_color); Albums->SetTimeout(ncmpcpp_window_timeout); Albums->SetItemDisplayer(Display::StringPairs); + Albums->SetGetStringFunction(StringPairToString); Songs = new Menu(itsRightColStartX, main_start_y, itsRightColWidth, main_height, "Songs", Config.main_color, brNone); Songs->HighlightColor(Config.main_highlight_color); @@ -66,6 +67,7 @@ void MediaLibrary::Init() Songs->SetSelectSuffix(&Config.selected_item_suffix); Songs->SetItemDisplayer(Display::Songs); Songs->SetItemDisplayerUserData(&Config.song_library_format); + Songs->SetGetStringFunction(SongToString); w = Artists; } @@ -428,6 +430,16 @@ void MediaLibrary::AddToPlaylist(bool add_n_play) } } +std::string MediaLibrary::StringPairToString(const string_pair &pair, void *) +{ + return pair.first; +} + +std::string MediaLibrary::SongToString(const MPD::Song &s, void *) +{ + return s.toString(Config.song_library_format); +} + bool MediaLibrary::SortSongsByTrack(Song *a, Song *b) { if (a->GetDisc() == b->GetDisc()) diff --git a/src/media_library.h b/src/media_library.h index ca4b9476..cf445887 100644 --- a/src/media_library.h +++ b/src/media_library.h @@ -45,11 +45,15 @@ class MediaLibrary : public Screen virtual void ReverseSelection() { Songs->ReverseSelection(); } virtual void GetSelectedSongs(MPD::SongList &); + virtual void ApplyFilter(const std::string &s) { GetList()->ApplyFilter(s); } + virtual List *GetList(); void NextColumn(); void PrevColumn(); + static std::string StringPairToString(const string_pair &pair, void *); + Menu *Artists; Menu *Albums; Menu *Songs; @@ -57,6 +61,8 @@ class MediaLibrary : public Screen protected: void AddToPlaylist(bool); + static std::string SongToString(const MPD::Song &s, void *); + static bool SortSongsByTrack(MPD::Song *, MPD::Song *); static size_t itsLeftColWidth; diff --git a/src/menu.cpp b/src/menu.cpp index f74c570f..2fd5d525 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -43,3 +43,7 @@ bool List::Deselect() return true; } +template <> std::string Menu::GetOption(size_t pos) +{ + return itsOptionsPtr->at(pos) ? (*itsOptionsPtr)[pos]->Item : ""; +} diff --git a/src/menu.h b/src/menu.h index 5172e7ee..7e300368 100644 --- a/src/menu.h +++ b/src/menu.h @@ -23,6 +23,7 @@ #include "window.h" #include "strbuffer.h" +#include "misc.h" class List { @@ -48,11 +49,21 @@ class List void SelectCurrent(); void ReverseSelection(size_t = 0); bool Deselect(); + + virtual void ApplyFilter(const std::string &, size_t = 0, bool = 0) = 0; + virtual const std::string &GetFilter() = 0; + virtual std::string GetOption(size_t) = 0; + + virtual bool isFiltered() = 0; + //virtual void ShowAll() = 0; + //virtual void ShowFiltered() = 0; + }; template class Menu : public Window, public List { typedef void (*ItemDisplayer) (const T &, void *, Menu *); + typedef std::string (*GetStringFunction) (const T &, void *); struct Option { @@ -77,6 +88,9 @@ template class Menu : public Window, public List void SetItemDisplayer(ItemDisplayer ptr) { itsItemDisplayer = ptr; } void SetItemDisplayerUserData(void *data) { itsItemDisplayerUserdata = data; } + void SetGetStringFunction(GetStringFunction f) { itsGetStringFunction = f; } + void SetGetStringFunctionUserData(void *data) { itsGetStringFunctionUserData = data; } + void Reserve(size_t size); void ResizeBuffer(size_t size); void AddOption(const T &item, bool is_bold = 0, bool is_static = 0); @@ -101,6 +115,15 @@ template class Menu : public Window, public List virtual size_t Choice() const; virtual size_t RealChoice() const; + virtual void ApplyFilter(const std::string &filter, size_t beginning = 0, bool case_sensitive = 0); + virtual const std::string &GetFilter(); + virtual std::string GetOption(size_t pos); + + virtual bool isFiltered() { return itsOptionsPtr == &itsFilteredOptions; } + + void ShowAll() { itsOptionsPtr = &itsOptions; } + void ShowFiltered() { itsOptionsPtr = &itsFilteredOptions; } + virtual void Refresh(); virtual void Scroll(Where); virtual void Reset(); @@ -112,7 +135,7 @@ template class Menu : public Window, public List void HighlightColor(Color col) { itsHighlightColor = col; } void Highlighting(bool hl) { highlightEnabled = hl; } - virtual bool Empty() const { return itsOptions.empty(); } + virtual bool Empty() const { return itsOptionsPtr->empty(); } T &Back(); const T &Back() const; @@ -129,8 +152,15 @@ template class Menu : public Window, public List protected: ItemDisplayer itsItemDisplayer; void *itsItemDisplayerUserdata; + GetStringFunction itsGetStringFunction; + void *itsGetStringFunctionUserData; + + std::string itsFilter; + std::vector