diff options
author | Andrzej Rybczak <electricityispower@gmail.com> | 2009-03-07 18:23:31 +0100 |
---|---|---|
committer | Andrzej Rybczak <electricityispower@gmail.com> | 2009-03-07 18:23:31 +0100 |
commit | b21ede24f4a404c58d21b07570dbfe643e761187 (patch) | |
tree | 327d87a273f3caedaff37f59daafed158dbdcb34 | |
parent | c5f24f402ffbe718bd8fa139b505afe4f7feae56 (diff) |
move searching to Menu class, also remember last constraint
this improvement also make that list of found items is not cleared
if one switches to another screen. it's remebered until the content
of screen changes (e.g. item is deleted from playlist)
-rw-r--r-- | src/browser.cpp | 2 | ||||
-rw-r--r-- | src/clock.cpp | 1 | ||||
-rw-r--r-- | src/global.h | 3 | ||||
-rw-r--r-- | src/media_library.cpp | 4 | ||||
-rw-r--r-- | src/menu.h | 61 | ||||
-rw-r--r-- | src/ncmpcpp.cpp | 80 | ||||
-rw-r--r-- | src/ncmpcpp.h | 6 | ||||
-rw-r--r-- | src/playlist.cpp | 1 | ||||
-rw-r--r-- | src/playlist_editor.cpp | 3 | ||||
-rw-r--r-- | src/search_engine.cpp | 2 | ||||
-rw-r--r-- | src/tag_editor.cpp | 5 |
11 files changed, 75 insertions, 93 deletions
diff --git a/src/browser.cpp b/src/browser.cpp index 374c265d..5555f894 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -74,7 +74,6 @@ void Browser::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; w->Empty() ? myBrowser->GetDirectory(itsBrowsedDir) : myBrowser->UpdateItemList(); myScreen = this; redraw_header = 1; @@ -97,7 +96,6 @@ void Browser::EnterPressed() { case itDirectory: { - CLEAR_FIND_HISTORY; GetDirectory(item.name, itsBrowsedDir); redraw_header = 1; break; diff --git a/src/clock.cpp b/src/clock.cpp index 590ae34f..8cd3118a 100644 --- a/src/clock.cpp +++ b/src/clock.cpp @@ -83,7 +83,6 @@ void Clock::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; myScreen = this; myPlaylist->Main()->Hide(); redraw_header = 1; diff --git a/src/global.h b/src/global.h index 654229b0..f83896bf 100644 --- a/src/global.h +++ b/src/global.h @@ -53,9 +53,6 @@ namespace Global extern bool redraw_header; extern std::string volume_state; - - extern std::vector<int> vFoundPositions; - extern int found_pos; } #endif diff --git a/src/media_library.cpp b/src/media_library.cpp index 3e52849f..8cd890d0 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -112,7 +112,6 @@ void MediaLibrary::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; myScreen = this; redraw_header = 1; Refresh(); @@ -128,7 +127,6 @@ void MediaLibrary::Update() { if (Artists->Empty()) { - CLEAR_FIND_HISTORY; TagList list; Albums->Clear(0); Songs->Clear(0); @@ -284,7 +282,6 @@ void MediaLibrary::GetSelectedSongs(MPD::SongList &v) void MediaLibrary::NextColumn() { - CLEAR_FIND_HISTORY; if (w == Artists) { if (Songs->Empty()) @@ -307,7 +304,6 @@ void MediaLibrary::NextColumn() void MediaLibrary::PrevColumn() { - CLEAR_FIND_HISTORY; if (w == Songs) { Songs->HighlightColor(Config.main_highlight_color); @@ -21,6 +21,8 @@ #ifndef _MENU_H #define _MENU_H +#include <set> + #include "window.h" #include "strbuffer.h" #include "misc.h" @@ -52,6 +54,11 @@ namespace NCurses void ReverseSelection(size_t = 0); bool Deselect(); + virtual bool Search(const std::string &, size_t = 0, bool = 0) = 0; + virtual const std::string &GetSearchConstraint() = 0; + virtual void NextFound(bool) = 0; + virtual void PrevFound(bool) = 0; + 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; @@ -119,6 +126,11 @@ namespace NCurses virtual size_t Choice() const; virtual size_t RealChoice() const; + virtual bool Search(const std::string &constraint, size_t beginning = 0, bool case_sensitive = 0); + virtual const std::string &GetSearchConstraint() { return itsSearchConstraint; } + virtual void NextFound(bool wrap); + virtual void PrevFound(bool wrap); + 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); @@ -170,11 +182,13 @@ namespace NCurses void *itsGetStringFunctionUserData; std::string itsFilter; + std::string itsSearchConstraint; std::vector<Option *> *itsOptionsPtr; std::vector<Option *> itsOptions; std::vector<Option *> itsFilteredOptions; std::vector<size_t> itsFilteredRealPositions; + std::set<size_t> itsFound; int itsBeginning; int itsHighlight; @@ -279,6 +293,7 @@ template <class T> void NCurses::Menu<T>::DeleteOption(size_t pos) delete itsOptions.at(pos); itsOptions.erase(itsOptions.begin()+pos); } + itsFound.clear(); if (itsOptionsPtr->empty()) Window::Clear(); } @@ -490,6 +505,7 @@ template <class T> void NCurses::Menu<T>::Clear(bool clrscr) for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) delete *it; itsOptions.clear(); + itsFound.clear(); ClearFiltered(); itsOptionsPtr = &itsOptions; if (clrscr) @@ -574,10 +590,55 @@ template <class T> size_t NCurses::Menu<T>::RealChoice() const return result; } +template <class T> bool NCurses::Menu<T>::Search(const std::string &constraint, size_t beginning, bool case_sensitive) +{ + itsFound.clear(); + if (constraint.empty()) + return false; + itsSearchConstraint = constraint; + std::string option; + for (size_t i = beginning; i < itsOptionsPtr->size(); i++) + { + option = GetOption(i); + if (!case_sensitive) + ToLower(option); + if (option.find(itsSearchConstraint) != std::string::npos) + itsFound.insert(i); + } + return !itsFound.empty(); +} + +template <class T> void NCurses::Menu<T>::NextFound(bool wrap) +{ + if (itsFound.empty()) + return; + std::set<size_t>::iterator next = itsFound.upper_bound(itsHighlight); + if (next != itsFound.end()) + Highlight(*next); + else if (wrap) + Highlight(*itsFound.begin()); +} + +template <class T> void NCurses::Menu<T>::PrevFound(bool wrap) +{ + if (itsFound.empty()) + return; + std::set<size_t>::iterator prev = itsFound.lower_bound(itsHighlight); + if (prev != itsFound.begin()) + { + if (*prev == size_t(itsHighlight)) + prev--; + Highlight(*prev); + } + else if (wrap) + Highlight(*itsFound.rbegin()); +} + template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter, size_t beginning, bool case_sensitive) { if (filter == itsFilter) return; + itsFound.clear(); ClearFiltered(); itsFilter = filter; if (!case_sensitive) diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 5d99b993..0733e892 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -79,9 +79,6 @@ bool Global::block_item_list_update = 0; bool Global::messages_allowed = 0; bool Global::redraw_header = 1; -vector<int> Global::vFoundPositions; -int Global::found_pos = 0; - int main(int argc, char *argv[]) { CreateConfigDir(); @@ -1462,8 +1459,6 @@ int main(int argc, char *argv[]) if (!mList) continue; - CLEAR_FIND_HISTORY; - LockStatusbar(); Statusbar() << fmtBold << "Apply filter: " << fmtBoldEnd; wFooter->SetGetStringHelper(StatusbarApplyFilterImmediately); @@ -1491,83 +1486,36 @@ int main(int argc, char *argv[]) if (!mList) continue; - string how = Keypressed(input, Key.FindForward) ? "forward" : "backward"; LockStatusbar(); - Statusbar() << "Find " << how << ": "; - string findme = wFooter->GetString(); + Statusbar() << "Find " << (Keypressed(input, Key.FindForward) ? "forward" : "backward") << ": "; + string findme = wFooter->GetString(mList->GetSearchConstraint()); UnlockStatusbar(); time(&timer); if (findme.empty()) continue; - ToLower(findme); - - CLEAR_FIND_HISTORY; ShowMessage("Searching..."); - for (size_t i = (myScreen == mySearcher ? SearchEngine::StaticOptions : 0); i < mList->Size(); i++) - { - string name = mList->GetOption(i); - ToLower(name); - if (name.find(findme) != string::npos && !mList->isStatic(i)) - { - vFoundPositions.push_back(i); - if (Keypressed(input, Key.FindForward)) // forward - { - if (found_pos < 0 && i >= mList->Choice()) - found_pos = vFoundPositions.size()-1; - } - else // backward - { - if (i <= mList->Choice()) - found_pos = vFoundPositions.size()-1; - } - } - } - ShowMessage("Searching finished!"); - - if (Config.wrapped_search ? vFoundPositions.empty() : found_pos < 0) + if (mList->Search(findme, myScreen == mySearcher ? SearchEngine::StaticOptions : 0)) + ShowMessage("Searching finished!"); + else ShowMessage("Unable to find \"%s\"", findme.c_str()); + + if (Keypressed(input, Key.FindForward)) + mList->NextFound(Config.wrapped_search); else - { - mList->Highlight(vFoundPositions[found_pos < 0 ? 0 : found_pos]); - if (myScreen == myPlaylist) - { - time(&timer); - myPlaylist->Main()->Highlighting(1); - } - } + mList->PrevFound(Config.wrapped_search); } else if (Keypressed(input, Key.NextFoundPosition) || Keypressed(input, Key.PrevFoundPosition)) { List *mList = myScreen->GetList(); - if (!mList || vFoundPositions.empty()) + if (!mList) continue; - bool next = Keypressed(input, Key.NextFoundPosition); - - try - { - mList->Highlight(vFoundPositions.at(next ? ++found_pos : --found_pos)); - } - catch (std::out_of_range) - { - if (Config.wrapped_search) - { - if (next) - { - mList->Highlight(vFoundPositions.front()); - found_pos = 0; - } - else // prev - { - mList->Highlight(vFoundPositions.back()); - found_pos = vFoundPositions.size()-1; - } - } - else - found_pos = next ? vFoundPositions.size()-1 : 0; - } + if (Keypressed(input, Key.NextFoundPosition)) + mList->NextFound(Config.wrapped_search); + else + mList->PrevFound(Config.wrapped_search); } else if (Keypressed(input, Key.ToggleFindMode)) { diff --git a/src/ncmpcpp.h b/src/ncmpcpp.h index a918736c..2cfd2112 100644 --- a/src/ncmpcpp.h +++ b/src/ncmpcpp.h @@ -27,12 +27,6 @@ #include "menu.h" #include "scrollpad.h" -#define CLEAR_FIND_HISTORY \ - do { \ - found_pos = -1; \ - vFoundPositions.clear(); \ - } while (0) - using namespace NCurses; typedef std::pair<std::string, std::string> string_pair; diff --git a/src/playlist.cpp b/src/playlist.cpp index 8f5383ad..9d071677 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -89,7 +89,6 @@ void Playlist::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; myScreen = this; w->Window::Clear(); redraw_header = 1; diff --git a/src/playlist_editor.cpp b/src/playlist_editor.cpp index 2e624f24..d97ebed3 100644 --- a/src/playlist_editor.cpp +++ b/src/playlist_editor.cpp @@ -98,7 +98,6 @@ void PlaylistEditor::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; myScreen = this; redraw_header = 1; Refresh(); @@ -168,7 +167,6 @@ void PlaylistEditor::NextColumn() { if (w == Playlists) { - CLEAR_FIND_HISTORY; Playlists->HighlightColor(Config.main_highlight_color); w->Refresh(); w = Content; @@ -180,7 +178,6 @@ void PlaylistEditor::PrevColumn() { if (w == Content) { - CLEAR_FIND_HISTORY; Content->HighlightColor(Config.main_highlight_color); w->Refresh(); w = Playlists; diff --git a/src/search_engine.cpp b/src/search_engine.cpp index 6b054522..fc0271c7 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -67,7 +67,6 @@ void SearchEngine::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; if (w->Empty()) Prepare(); myScreen = this; @@ -214,7 +213,6 @@ void SearchEngine::EnterPressed() } case 16: { - CLEAR_FIND_HISTORY; itsPattern.Clear(); w->Reset(); Prepare(); diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 766274a7..52aec0cd 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -366,8 +366,6 @@ void TagEditor::SwitchTo() if (hasToBeResized) Resize(); - CLEAR_FIND_HISTORY; - myScreen = this; redraw_header = 1; Refresh(); @@ -410,7 +408,6 @@ void TagEditor::Update() { if (LeftColumn->Empty()) { - CLEAR_FIND_HISTORY; LeftColumn->Window::Clear(); Tags->Clear(); TagList list; @@ -763,7 +760,6 @@ List *TagEditor::GetList() void TagEditor::NextColumn() { - CLEAR_FIND_HISTORY; if (w == LeftColumn) { LeftColumn->HighlightColor(Config.main_highlight_color); @@ -782,7 +778,6 @@ void TagEditor::NextColumn() void TagEditor::PrevColumn() { - CLEAR_FIND_HISTORY; if (w == Tags) { Tags->HighlightColor(Config.main_highlight_color); |