From 43a8e2284eb87eefb9309cfc98d85a415001a8ac Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Mon, 16 Feb 2009 18:20:45 +0100 Subject: [PATCH] provide generic interface for dealing with selected items --- src/Makefile.am | 4 +- src/browser.cpp | 35 ++++++++++++- src/browser.h | 5 ++ src/clock.h | 4 +- src/help.h | 2 + src/info.h | 2 + src/lyrics.h | 2 + src/media_library.cpp | 12 ++++- src/media_library.h | 5 ++ src/{screen.cpp => menu.cpp} | 25 ++++++++-- src/menu.h | 7 ++- src/ncmpcpp.cpp | 96 ++++-------------------------------- src/playlist.cpp | 12 ++++- src/playlist.h | 5 ++ src/playlist_editor.cpp | 12 ++++- src/playlist_editor.h | 5 ++ src/screen.h | 9 ++-- src/search_engine.cpp | 12 ++++- src/search_engine.h | 5 ++ src/tag_editor.cpp | 12 ++++- src/tag_editor.h | 7 +++ 21 files changed, 172 insertions(+), 106 deletions(-) rename src/{screen.cpp => menu.cpp} (79%) diff --git a/src/Makefile.am b/src/Makefile.am index 3eab11aa..1b5d1a31 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = ncmpcpp ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp display.cpp help.cpp \ - helpers.cpp info.cpp libmpdclient.c lyrics.cpp media_library.cpp misc.cpp mpdpp.cpp \ - ncmpcpp.cpp playlist.cpp playlist_editor.cpp screen.cpp scrollpad.cpp \ + helpers.cpp info.cpp libmpdclient.c lyrics.cpp media_library.cpp menu.cpp misc.cpp \ + mpdpp.cpp ncmpcpp.cpp playlist.cpp playlist_editor.cpp scrollpad.cpp \ search_engine.cpp settings.cpp song.cpp status.cpp str_pool.c tag_editor.cpp window.cpp # set the include path found by configure diff --git a/src/browser.cpp b/src/browser.cpp index 527ce41f..032cf762 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -146,7 +146,7 @@ void Browser::SpacePressed() { if (Config.space_selects && w->Choice() >= (itsBrowsedDir != "/" ? 1 : 0)) { - Select(w); + w->SelectCurrent(); w->Scroll(wDown); return; } @@ -238,6 +238,39 @@ MPD::Song *Browser::CurrentSong() return !w->Empty() && w->Current().type == itSong ? w->Current().song : 0; } +void Browser::ReverseSelection() +{ + w->ReverseSelection(itsBrowsedDir == "/" ? 0 : 1); +} + +void Browser::GetSelectedSongs(MPD::SongList &v) +{ + std::vector selected; + w->GetSelected(selected); + for (std::vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + const Item &item = w->at(*it); + switch (item.type) + { + case itDirectory: + { + Mpd->GetDirectoryRecursive(locale_to_utf_cpy(item.name), v); + break; + } + case itSong: + { + v.push_back(new Song(*item.song)); + break; + } + case itPlaylist: + { + Mpd->GetPlaylistContent(locale_to_utf_cpy(item.name), v); + break; + } + } + } +} + namespace { const char *supported_extensions[] = { "wma", "asf", "rm", "mp1", "mp2", "mp3", "mp4", "m4a", "flac", "ogg", "wav", "au", "aiff", "aif", "ac3", "aac", "mpc", "it", "mod", "s3m", "xm", "wv", 0 }; diff --git a/src/browser.h b/src/browser.h index 40f2c8f7..91fbfd1e 100644 --- a/src/browser.h +++ b/src/browser.h @@ -40,6 +40,11 @@ class Browser : public Screen< Menu > virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return true; } + virtual void ReverseSelection(); + virtual bool Deselect() { return w->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + const std::string &CurrentDir() { return itsBrowsedDir; } void GetDirectory(std::string, std::string = "/"); diff --git a/src/clock.h b/src/clock.h index 6129a340..ada4c480 100644 --- a/src/clock.h +++ b/src/clock.h @@ -41,7 +41,9 @@ class Clock : public Screen virtual void Update(); virtual void Scroll() { } - + + virtual bool allowsSelection() { return false; } + protected: static void Prepare(); static void Set(int, int); diff --git a/src/help.h b/src/help.h index 8397f333..3a022ef0 100644 --- a/src/help.h +++ b/src/help.h @@ -33,6 +33,8 @@ class Help : public Screen virtual std::string Title(); + virtual bool allowsSelection() { return false; } + protected: std::string DisplayKeys(int *, int = 2); void GetKeybindings(); diff --git a/src/info.h b/src/info.h index c7be4cfd..74fc940a 100644 --- a/src/info.h +++ b/src/info.h @@ -36,6 +36,8 @@ class Info : public Screen virtual void Update(); + virtual bool allowsSelection() { return false; } + void GetSong(); # ifdef HAVE_CURL_CURL_H void GetArtist(); diff --git a/src/lyrics.h b/src/lyrics.h index 1dfdae0c..c9ffe60d 100644 --- a/src/lyrics.h +++ b/src/lyrics.h @@ -54,6 +54,8 @@ class Lyrics : public Screen virtual void SpacePressed(); + virtual bool allowsSelection() { return false; } + static bool Reload; # ifdef HAVE_CURL_CURL_H diff --git a/src/media_library.cpp b/src/media_library.cpp index 49245610..4481f00a 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -246,7 +246,7 @@ void MediaLibrary::SpacePressed() { if (Config.space_selects && w == Songs) { - Select(Songs); + Songs->SelectCurrent(); w->Scroll(wDown); return; } @@ -258,6 +258,16 @@ MPD::Song *MediaLibrary::CurrentSong() return w == Songs && !Songs->Empty() ? &Songs->Current() : 0; } +void MediaLibrary::GetSelectedSongs(MPD::SongList &v) +{ + std::vector selected; + Songs->GetSelected(selected); + for (std::vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + v.push_back(new MPD::Song(Songs->at(*it))); + } +} + void MediaLibrary::NextColumn() { CLEAR_FIND_HISTORY; diff --git a/src/media_library.h b/src/media_library.h index f3530bde..d682c0c5 100644 --- a/src/media_library.h +++ b/src/media_library.h @@ -41,6 +41,11 @@ class MediaLibrary : public Screen virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return w == Songs; } + virtual void ReverseSelection() { Songs->ReverseSelection(); } + virtual bool Deselect() { return Songs->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + void NextColumn(); void PrevColumn(); diff --git a/src/screen.cpp b/src/menu.cpp similarity index 79% rename from src/screen.cpp rename to src/menu.cpp index 0e49ea32..f74c570f 100644 --- a/src/screen.cpp +++ b/src/menu.cpp @@ -18,13 +18,28 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#include "screen.h" +#include "menu.h" -void BasicScreen::Select(List *l) +void List::SelectCurrent() { - if (l->Empty()) + if (Empty()) return; - size_t i = l->Choice(); - l->Select(i, !l->isSelected(i)); + size_t i = Choice(); + Select(i, !isSelected(i)); +} + +void List::ReverseSelection(size_t beginning) +{ + for (size_t i = beginning; i < Size(); i++) + Select(i, !isSelected(i) && !isStatic(i)); +} + +bool List::Deselect() +{ + if (!hasSelected()) + return false; + for (size_t i = 0; i < Size(); i++) + Select(i, 0); + return true; } diff --git a/src/menu.h b/src/menu.h index 64c999e7..f60621de 100644 --- a/src/menu.h +++ b/src/menu.h @@ -31,7 +31,8 @@ class List class InvalidItem { }; List() { } - virtual ~List() { }; + virtual ~List() { } + virtual void Select(int, bool) = 0; virtual void Static(int, bool) = 0; virtual bool Empty() const = 0; @@ -43,6 +44,10 @@ class List virtual size_t Size() const = 0; virtual size_t Choice() const = 0; virtual size_t RealChoice() const = 0; + + void SelectCurrent(); + void ReverseSelection(size_t = 0); + bool Deselect(); }; template class Menu : public Window, public List diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 9b6604b3..8bb91776 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -1184,114 +1184,36 @@ int main(int argc, char *argv[]) } else if (Keypressed(input, Key.ReverseSelection)) { - if (myScreen == myPlaylist - || myScreen == myBrowser - || (myScreen == mySearcher && !mySearcher->Main()->Current().first) - || myScreen->Cmp() == myLibrary->Songs - || myScreen->Cmp() == myPlaylistEditor->Content -# ifdef HAVE_TAGLIB_H - || myScreen->Cmp() == myTagEditor->Tags -# endif // HAVE_TAGLIB_H - ) + if (myScreen->allowsSelection()) { - List *mList = reinterpret_cast *>(myWindow->Main()); - for (size_t i = 0; i < mList->Size(); i++) - mList->Select(i, !mList->isSelected(i) && !mList->isStatic(i)); - // hackish shit begins - if (myScreen == myBrowser && myBrowser->CurrentDir() != "/") - mList->Select(0, 0); // [..] cannot be selected, uhm. - if (myScreen == mySearcher) - mList->Select(SearchEngine::ResetButton, 0); // 'Reset' cannot be selected, omgplz. - // hacking shit ends. + myScreen->ReverseSelection(); ShowMessage("Selection reversed!"); } } else if (Keypressed(input, Key.DeselectAll)) { - if (myScreen == myPlaylist - || myScreen == myBrowser - || myScreen == mySearcher - || myScreen->Cmp() == myLibrary->Songs - || myScreen->Cmp() == myPlaylistEditor->Content -# ifdef HAVE_TAGLIB_H - || myScreen->Cmp() == myTagEditor->Tags -# endif // HAVE_TAGLIB_H - ) + if (myScreen->allowsSelection()) { - List *mList = reinterpret_cast *>(myWindow->Main()); - if (mList->hasSelected()) + if (myScreen->Deselect()) { - for (size_t i = 0; i < mList->Size(); i++) - mList->Select(i, 0); ShowMessage("Items deselected!"); } } } else if (Keypressed(input, Key.AddSelected)) { - if (myScreen != myPlaylist - && myScreen != myBrowser - && myScreen != mySearcher - && myScreen->Cmp() != myLibrary->Songs - && myScreen->Cmp() != myPlaylistEditor->Content) + if (!myScreen->allowsSelection()) continue; - List *mList = reinterpret_cast *>(myWindow->Main()); - if (!mList->hasSelected()) + SongList result; + myScreen->GetSelectedSongs(result); + + if (result.empty()) { ShowMessage("No selected items!"); continue; } - vector list; - mList->GetSelected(list); - SongList result; - for (vector::const_iterator it = list.begin(); it != list.end(); it++) - { - if (myScreen == myPlaylist) - { - Song *s = new Song(myPlaylist->Main()->at(*it)); - result.push_back(s); - } - else if (myScreen == myBrowser) - { - const Item &item = myBrowser->Main()->at(*it); - switch (item.type) - { - case itDirectory: - { - Mpd->GetDirectoryRecursive(locale_to_utf_cpy(item.name), result); - break; - } - case itSong: - { - Song *s = new Song(*item.song); - result.push_back(s); - break; - } - case itPlaylist: - { - Mpd->GetPlaylistContent(locale_to_utf_cpy(item.name), result); - break; - } - } - } - else if (myScreen == mySearcher) - { - Song *s = new Song(*mySearcher->Main()->at(*it).second); - result.push_back(s); - } - else if (myScreen == myLibrary) - { - Song *s = new Song(myLibrary->Songs->at(*it)); - result.push_back(s); - } - else if (myScreen == myPlaylistEditor) - { - Song *s = new Song(myPlaylistEditor->Content->at(*it)); - result.push_back(s); - } - } size_t dialog_width = COLS*0.8; size_t dialog_height = LINES*0.6; Menu *mDialog = new Menu((COLS-dialog_width)/2, (LINES-dialog_height)/2, dialog_width, dialog_height, "Add selected items to...", Config.main_color, Config.window_border); diff --git a/src/playlist.cpp b/src/playlist.cpp index 13e876e5..36f17509 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -81,7 +81,7 @@ void Playlist::EnterPressed() void Playlist::SpacePressed() { - Select(w); + w->SelectCurrent(); w->Scroll(wDown); } @@ -90,6 +90,16 @@ MPD::Song *Playlist::CurrentSong() return !w->Empty() ? &w->Current() : 0; } +void Playlist::GetSelectedSongs(MPD::SongList &v) +{ + vector selected; + w->GetSelected(selected); + for (vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + v.push_back(new MPD::Song(w->at(*it))); + } +} + std::string Playlist::TotalLength() { std::ostringstream result; diff --git a/src/playlist.h b/src/playlist.h index ce8695f0..d45dc70b 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -42,6 +42,11 @@ class Playlist : public Screen< Menu > virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return true; } + virtual void ReverseSelection() { w->ReverseSelection(); } + virtual bool Deselect() { return w->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + bool isPlaying() { return NowPlaying >= 0 && !w->Empty(); } const MPD::Song &NowPlayingSong(); diff --git a/src/playlist_editor.cpp b/src/playlist_editor.cpp index 0a695be5..c312cecd 100644 --- a/src/playlist_editor.cpp +++ b/src/playlist_editor.cpp @@ -266,7 +266,7 @@ void PlaylistEditor::SpacePressed() { if (Config.space_selects && w == Content) { - Select(Content); + Content->SelectCurrent(); w->Scroll(wDown); return; } @@ -278,3 +278,13 @@ MPD::Song *PlaylistEditor::CurrentSong() return w == Content && !Content->Empty() ? &Content->Current() : 0; } +void PlaylistEditor::GetSelectedSongs(MPD::SongList &v) +{ + std::vector selected; + Content->GetSelected(selected); + for (std::vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + v.push_back(new MPD::Song(Content->at(*it))); + } +} + diff --git a/src/playlist_editor.h b/src/playlist_editor.h index bbdc1a1c..f71f9113 100644 --- a/src/playlist_editor.h +++ b/src/playlist_editor.h @@ -40,6 +40,11 @@ class PlaylistEditor : public Screen virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return w == Content; } + virtual void ReverseSelection() { Content->ReverseSelection(); } + virtual bool Deselect() { return Content->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + void NextColumn(); void PrevColumn(); diff --git a/src/screen.h b/src/screen.h index c05e258e..9c6956ca 100644 --- a/src/screen.h +++ b/src/screen.h @@ -50,10 +50,12 @@ class BasicScreen virtual MPD::Song *CurrentSong() { return 0; } - bool hasToBeResized; + virtual bool allowsSelection() = 0; + virtual void ReverseSelection() { } + virtual bool Deselect() { return false; } + virtual void GetSelectedSongs(MPD::SongList &) { } - protected: - void Select(List *); + bool hasToBeResized; }; template class Screen : public BasicScreen @@ -78,7 +80,6 @@ template void *&Screen::Cmp() return *(void **)(void *)&w; } - template WindowType *&Screen::Main() { return w; diff --git a/src/search_engine.cpp b/src/search_engine.cpp index 43a9fbb9..5c665488 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -254,7 +254,7 @@ void SearchEngine::SpacePressed() if (Config.space_selects) { - Select(w); + w->SelectCurrent(); w->Scroll(wDown); return; } @@ -293,6 +293,16 @@ MPD::Song *SearchEngine::CurrentSong() return !w->Empty() ? w->Current().second : 0; } +void SearchEngine::GetSelectedSongs(MPD::SongList &v) +{ + std::vector selected; + w->GetSelected(selected); + for (std::vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + v.push_back(new MPD::Song(*w->at(*it).second)); + } +} + void SearchEngine::UpdateFoundList() { bool bold = 0; diff --git a/src/search_engine.h b/src/search_engine.h index cff8365e..81fd7c29 100644 --- a/src/search_engine.h +++ b/src/search_engine.h @@ -51,6 +51,11 @@ class SearchEngine : public Screen< Menu< std::pair > > virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return w->Choice() >= StaticOptions; } + virtual void ReverseSelection() { w->ReverseSelection(StaticOptions); } + virtual bool Deselect() { return w->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + void UpdateFoundList(); static size_t StaticOptions; diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 608acf11..5882583b 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -704,7 +704,7 @@ void TagEditor::SpacePressed() { if (w == Tags) { - Select(Tags); + Tags->SelectCurrent(); w->Scroll(wDown); return; } @@ -723,6 +723,16 @@ MPD::Song *TagEditor::CurrentSong() return w == Tags && !Tags->Empty() ? &Tags->Current() : 0; } +void TagEditor::GetSelectedSongs(MPD::SongList &v) +{ + std::vector selected; + Tags->GetSelected(selected); + for (std::vector::const_iterator it = selected.begin(); it != selected.end(); it++) + { + v.push_back(new MPD::Song(Tags->at(*it))); + } +} + void TagEditor::NextColumn() { CLEAR_FIND_HISTORY; diff --git a/src/tag_editor.h b/src/tag_editor.h index 73780a39..78b3f52c 100644 --- a/src/tag_editor.h +++ b/src/tag_editor.h @@ -44,6 +44,8 @@ class TinyTagEditor : public Screen< Menu > virtual void EnterPressed(); + virtual bool allowsSelection() { return false; } + bool SetEdited(MPD::Song *); protected: @@ -70,6 +72,11 @@ class TagEditor : public Screen virtual MPD::Song *CurrentSong(); + virtual bool allowsSelection() { return w == Tags; } + virtual void ReverseSelection() { Tags->ReverseSelection(); } + virtual bool Deselect() { return Tags->Deselect(); } + virtual void GetSelectedSongs(MPD::SongList &); + void NextColumn(); void PrevColumn();