fluxbox/src/FbTk/TypeAhead.hh
2007-03-03 19:35:34 +00:00

174 lines
5.4 KiB
C++

// TypeAhead.hh for FbTk - Fluxbox Toolkit
// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef FBTK_TYPEAHEAD_HH
#define FBTK_TYPEAHEAD_HH
#include "ITypeAheadable.hh"
#include <vector>
#include "SearchResult.hh"
namespace FbTk {
template <typename Items, typename Item_Type>
class TypeAhead {
/*
a class template can't be split into separate interface + implementation files, an interface summary is given here:
public:
void init(Items const &items);
// accessors:
inline int stringSize() const { return m_searchstr.size(); }
Items matched() const;
// modifiers:
Items putCharacter(char ch);
void putBackSpace();
void reset()
private:
SearchResults m_search_results;
std::string m_searchstr;
Items const *m_ref;
// helper
void fillValues(BaseItems const &search, ValueVec &fillin) const;
// reverts to searchstate before current
void revert();
// search performs iteration and sets state
void search(char char_to_test);
void doSearch(char to_test,
Items const &items,
SearchResult &mySearchResult) const;
void doSearch(char to_test,
BaseItems const &search,
SearchResult &mySearchResult) const;
*/
public:
typedef std::vector < ITypeAheadable* > BaseItems;
typedef BaseItems::const_iterator BaseItemscIt;
typedef std::vector < SearchResult > SearchResults;
typedef typename Items::const_iterator ItemscIt;
void init(Items const &items) { m_ref = &items; }
inline size_t stringSize() const { return m_searchstr.size(); }
void seek() {
if (!m_search_results.empty())
m_searchstr = m_search_results.back().seekedString();
}
Items putCharacter(char ch) {
if (isprint(ch))
search(ch);
return matched();
}
void putBackSpace() {
if (!m_search_results.empty())
revert();
}
void reset() {
m_searchstr.clear();
m_search_results.clear();
}
Items matched() const {
Items last_matched;
if (!m_search_results.empty())
fillValues(m_search_results.back().result(), last_matched);
return last_matched;
}
private:
SearchResults m_search_results;
std::string m_searchstr;
Items const *m_ref; // reference to vector we are operating on
void fillValues(BaseItems const &search, Items &fillin) const {
for (BaseItemscIt it = search.begin(); it != search.end(); it++) {
Item_Type tmp = dynamic_cast<Item_Type>(*it);
if (tmp)
fillin.push_back(tmp);
}
}
void revert() {
m_search_results.pop_back();
if (m_search_results.empty())
m_searchstr.clear();
else
m_searchstr = m_search_results.back().seekedString();
}
void search(char char_to_test) {
SearchResult mySearchResult(m_searchstr + char_to_test);
size_t num_items = m_ref->size();
// check if we have already a searched set
if (m_search_results.empty())
doSearch(char_to_test, *m_ref, mySearchResult);
else {
num_items = m_search_results.back().size();
doSearch(char_to_test, m_search_results.back().result(),
mySearchResult);
}
if (mySearchResult.size() > 0 ) {
if (mySearchResult.size() < num_items) {
mySearchResult.seek();
m_search_results.push_back(mySearchResult);
}
m_searchstr += char_to_test;
}
}
// iteration based on original list of items
void doSearch(char to_test, Items const &items,
SearchResult &mySearchResult) const {
for (ItemscIt it = items.begin(); it != items.end(); it++) {
if ((*it)->iTypeCompareChar(to_test, stringSize()) && (*it)->isEnabled())
mySearchResult.add(*it);
}
}
// iteration based on last SearchResult
void doSearch(char to_test, BaseItems const &search,
SearchResult &mySearchResult) const {
for (BaseItemscIt it = search.begin(); it != search.end(); it++) {
if ((*it)->iTypeCompareChar(to_test, stringSize()) && (*it)->isEnabled())
mySearchResult.add(*it);
}
}
}; // end Class TypeAhead
} // end namespace FbTk
#endif // FBTK_TYPEAHEAD_HH