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)
This commit is contained in:
Andrzej Rybczak
2009-03-07 18:23:31 +01:00
parent c5f24f402f
commit b21ede24f4
11 changed files with 76 additions and 94 deletions

View File

@@ -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)