From c1d665bf9e8e48dcce19c45ba6a9e83e415a9cb6 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sun, 7 Oct 2012 17:02:49 +0200 Subject: [PATCH] scrollpad: add support for regex searching --- configure.in | 14 +++- src/scrollpad.cpp | 187 ++++++++++++++++++++++++++++------------------ src/scrollpad.h | 36 ++++----- src/statusbar.cpp | 1 + src/strbuffer.h | 1 - src/title.cpp | 1 + 6 files changed, 143 insertions(+), 97 deletions(-) diff --git a/configure.in b/configure.in index 3bc3c8bb..3ffabcda 100644 --- a/configure.in +++ b/configure.in @@ -91,13 +91,23 @@ AC_ARG_VAR([BOOST_LIB_SUFFIX], [Boost library name suffix [default=-mt]]) dnl ============================= dnl = checking for boost.locale = dnl ============================= -AC_CHECK_HEADERS([boost/locale/encoding.hpp], , - AC_MSG_ERROR(boost/locale/encoding.hpp is missing) +AC_CHECK_HEADERS([boost/locale.hpp], , + AC_MSG_ERROR(boost/locale.hpp is missing) ) AC_CHECK_LIB(boost_locale$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_locale$BOOST_LIB_SUFFIX", AC_MSG_ERROR([no boost.locale library found]) ) +dnl ============================ +dnl = checking for boost.regex = +dnl ============================ +AC_CHECK_HEADERS([boost/regex.hpp], , + AC_MSG_ERROR(boost/regex.hpp is missing) +) +AC_CHECK_LIB(boost_regex$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_regex$BOOST_LIB_SUFFIX", + AC_MSG_ERROR([no boost.regex library found]) +) + dnl ============================== dnl = checking for regex (win32) = dnl ============================== diff --git a/src/scrollpad.cpp b/src/scrollpad.cpp index 4cf7e16b..62b74fcc 100644 --- a/src/scrollpad.cpp +++ b/src/scrollpad.cpp @@ -19,9 +19,33 @@ ***************************************************************************/ #include +#include #include "scrollpad.h" -#include "utility/wide_string.h" + +namespace {// + +template +bool regexSearch(NC::Buffer &buf, PropT begin, const std::string &ws, PropT end, size_t id) +{ + try { + boost::regex rx(ws, boost::regex::icase); + auto first = boost::sregex_iterator(buf.str().begin(), buf.str().end(), rx); + auto last = boost::sregex_iterator(); + bool success = first != last; + for (; first != last; ++first) + { + buf.setProperty(first->position(), begin, id); + buf.setProperty(first->position() + first->length(), end, id); + } + return success; + } catch (boost::bad_expression &e) { + std::cerr << "regexSearch: bad_expression: " << e.what() << "\n"; + return false; + } +} + +} namespace NC {// @@ -38,6 +62,82 @@ m_real_height(height) { } + +void Scrollpad::refresh() +{ + assert(m_real_height >= m_height); + size_t max_beginning = m_real_height - m_height; + m_beginning = std::min(m_beginning, max_beginning); + prefresh(m_window, m_beginning, 0, m_start_y, m_start_x, m_start_y+m_height-1, m_start_x+m_width-1); +} + +void Scrollpad::resize(size_t new_width, size_t new_height) +{ + adjustDimensions(new_width, new_height); + flush(); +} + +void Scrollpad::scroll(Scroll where) +{ + assert(m_real_height >= m_height); + size_t max_beginning = m_real_height - m_height; + switch (where) + { + case Scroll::Up: + { + if (m_beginning > 0) + --m_beginning; + break; + } + case Scroll::Down: + { + if (m_beginning < max_beginning) + ++m_beginning; + break; + } + case Scroll::PageUp: + { + if (m_beginning > m_height) + m_beginning -= m_height; + else + m_beginning = 0; + break; + } + case Scroll::PageDown: + { + m_beginning = std::min(m_beginning + m_height, max_beginning); + break; + } + case Scroll::Home: + { + m_beginning = 0; + break; + } + case Scroll::End: + { + m_beginning = max_beginning; + break; + } + } +} + +void Scrollpad::clear() +{ + m_real_height = m_height; + m_buffer.clear(); + wclear(m_window); + delwin(m_window); + m_window = newpad(m_height, m_width); + setTimeout(m_window_timeout); + setColor(m_color, m_bg_color); + keypad(m_window, 1); +} + +const std::string &Scrollpad::buffer() +{ + return m_buffer.str(); +} + void Scrollpad::flush() { auto &w = static_cast(*this); @@ -152,79 +252,24 @@ void Scrollpad::flush() write_buffer(false); } -void Scrollpad::refresh() -{ - assert(m_real_height >= m_height); - size_t max_beginning = m_real_height - m_height; - m_beginning = std::min(m_beginning, max_beginning); - prefresh(m_window, m_beginning, 0, m_start_y, m_start_x, m_start_y+m_height-1, m_start_x+m_width-1); -} - -void Scrollpad::resize(size_t new_width, size_t new_height) -{ - adjustDimensions(new_width, new_height); - flush(); -} - -void Scrollpad::scroll(Scroll where) -{ - assert(m_real_height >= m_height); - size_t max_beginning = m_real_height - m_height; - switch (where) - { - case Scroll::Up: - { - if (m_beginning > 0) - --m_beginning; - break; - } - case Scroll::Down: - { - if (m_beginning < max_beginning) - ++m_beginning; - break; - } - case Scroll::PageUp: - { - if (m_beginning > m_height) - m_beginning -= m_height; - else - m_beginning = 0; - break; - } - case Scroll::PageDown: - { - m_beginning = std::min(m_beginning + m_height, max_beginning); - break; - } - case Scroll::Home: - { - m_beginning = 0; - break; - } - case Scroll::End: - { - m_beginning = max_beginning; - break; - } - } -} - -void Scrollpad::clear() -{ - m_real_height = m_height; - m_buffer.clear(); - wclear(m_window); - delwin(m_window); - m_window = newpad(m_height, m_width); - setTimeout(m_window_timeout); - setColor(m_color, m_bg_color); - keypad(m_window, 1); -} - void Scrollpad::reset() { m_beginning = 0; } +bool Scrollpad::setProperties(Color begin, const std::string &s, Color end, size_t id) +{ + return regexSearch(m_buffer, begin, s, end, id); +} + +bool Scrollpad::setProperties(Format begin, const std::string &s, Format end, size_t id) +{ + return regexSearch(m_buffer, begin, s, end, id); +} + +void Scrollpad::removeProperties(size_t id) +{ + m_buffer.removeProperties(id); +} + } diff --git a/src/scrollpad.h b/src/scrollpad.h index 01d9c093..d74ab629 100644 --- a/src/scrollpad.h +++ b/src/scrollpad.h @@ -35,35 +35,25 @@ struct Scrollpad: public Window Scrollpad(size_t startx, size_t starty, size_t width, size_t height, const std::string &title, Color color, Border border); - const std::string &buffer() { return m_buffer.str(); } - - void flush(); - void reset(); - - template - bool setProperties(PropertyT begin, const std::string &ws, PropertyT end, size_t id = -2) - { - bool success = false; - for (size_t i = 0; (i = m_buffer.str().find(ws, i)) != std::string::npos;) - { - success = true; - m_buffer.setProperty(i, begin, id); - i += ws.length(); - m_buffer.setProperty(i, end, id); - } - return success; - } - - void removeProperties(size_t id = -2) { m_buffer.removeProperties(id); } - + // override a few Window functions virtual void refresh() OVERRIDE; virtual void scroll(Scroll where) OVERRIDE; virtual void resize(size_t new_width, size_t new_height) OVERRIDE; virtual void clear() OVERRIDE; - template Scrollpad &operator<<(const T &obj) + const std::string &buffer(); + + void flush(); + void reset(); + + bool setProperties(Color begin, const std::string &s, Color end, size_t id = -2); + bool setProperties(Format begin, const std::string &s, Format end, size_t id = -2); + void removeProperties(size_t id = -2); + + template + Scrollpad &operator<<(const ItemT &item) { - m_buffer << obj; + m_buffer << item; return *this; } diff --git a/src/statusbar.cpp b/src/statusbar.cpp index 5b13e694..cdd7b369 100644 --- a/src/statusbar.cpp +++ b/src/statusbar.cpp @@ -23,6 +23,7 @@ #include "status.h" #include "statusbar.h" #include "bindings.h" +#include "utility/wide_string.h" using Global::wFooter; diff --git a/src/strbuffer.h b/src/strbuffer.h index 39070357..daaf90a9 100644 --- a/src/strbuffer.h +++ b/src/strbuffer.h @@ -23,7 +23,6 @@ #include #include "utility/numeric_conversions.h" -#include "utility/wide_string.h" #include "window.h" namespace NC {// diff --git a/src/title.cpp b/src/title.cpp index a0263f8d..6919eacd 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -24,6 +24,7 @@ #include "global.h" #include "settings.h" #include "title.h" +#include "utility/wide_string.h" #ifdef USE_PDCURSES void windowTitle(const std::string &) { }