add support for unicode aware regular expressions if available
This commit is contained in:
1
NEWS
1
NEWS
@@ -14,6 +14,7 @@ ncmpcpp-0.7 (????-??-??)
|
|||||||
* Support for PDCurses has been removed due to the library being unmaintained and buggy.
|
* Support for PDCurses has been removed due to the library being unmaintained and buggy.
|
||||||
* Current MPD host may now be shown in playlist (playlist_show_mpd_host configuration variable, disabled by default).
|
* Current MPD host may now be shown in playlist (playlist_show_mpd_host configuration variable, disabled by default).
|
||||||
* Random album artists can now be added to the playlist.
|
* Random album artists can now be added to the playlist.
|
||||||
|
* Case insensitive searching is now Unicode aware as long as boost was compiled with ICU support.
|
||||||
|
|
||||||
ncmpcpp-0.6.3 (2015-03-02)
|
ncmpcpp-0.6.3 (2015-03-02)
|
||||||
|
|
||||||
|
|||||||
58
configure.ac
58
configure.ac
@@ -114,10 +114,10 @@ dnl =================================
|
|||||||
AC_CHECK_HEADERS([boost/filesystem.hpp], ,
|
AC_CHECK_HEADERS([boost/filesystem.hpp], ,
|
||||||
AC_MSG_ERROR(boost/filesystem.hpp is missing)
|
AC_MSG_ERROR(boost/filesystem.hpp is missing)
|
||||||
)
|
)
|
||||||
AC_CHECK_LIB(boost_filesystem$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_filesystem$BOOST_LIB_SUFFIX",
|
AC_CHECK_LIB(boost_filesystem$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_filesystem$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.filesystem library found])
|
AC_MSG_ERROR([no boost.filesystem library found])
|
||||||
)
|
)
|
||||||
AC_CHECK_LIB(boost_system$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_system$BOOST_LIB_SUFFIX",
|
AC_CHECK_LIB(boost_system$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_system$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.system library found])
|
AC_MSG_ERROR([no boost.system library found])
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ dnl =============================
|
|||||||
AC_CHECK_HEADERS([boost/locale.hpp], ,
|
AC_CHECK_HEADERS([boost/locale.hpp], ,
|
||||||
AC_MSG_ERROR(boost/locale.hpp is missing)
|
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_CHECK_LIB(boost_locale$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_locale$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.locale library found])
|
AC_MSG_ERROR([no boost.locale library found])
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ dnl ======================================
|
|||||||
AC_CHECK_HEADERS([boost/program_options.hpp], ,
|
AC_CHECK_HEADERS([boost/program_options.hpp], ,
|
||||||
AC_MSG_ERROR(boost/program_options.hpp is missing)
|
AC_MSG_ERROR(boost/program_options.hpp is missing)
|
||||||
)
|
)
|
||||||
AC_CHECK_LIB(boost_program_options$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_program_options$BOOST_LIB_SUFFIX",
|
AC_CHECK_LIB(boost_program_options$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_program_options$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.program_options library found])
|
AC_MSG_ERROR([no boost.program_options library found])
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -161,10 +161,31 @@ dnl ============================
|
|||||||
AC_CHECK_HEADERS([boost/regex.hpp], ,
|
AC_CHECK_HEADERS([boost/regex.hpp], ,
|
||||||
AC_MSG_ERROR(boost/regex.hpp is missing)
|
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_CHECK_LIB(boost_regex$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_regex$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.regex library found])
|
AC_MSG_ERROR([no boost.regex library found])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dnl ====================
|
||||||
|
dnl = checking for icu =
|
||||||
|
dnl ====================
|
||||||
|
AH_TEMPLATE([BOOST_REGEX_ICU], [boost.regex was compiled with ICU support])
|
||||||
|
PKG_CHECK_MODULES([ICU], [icu-uc], [
|
||||||
|
old_CPPFLAGS="$CPPFLAGS"
|
||||||
|
old_LIBS="$LIBS"
|
||||||
|
AC_SUBST(ICU_CFLAGS)
|
||||||
|
AC_SUBST(ICU_LIBS)
|
||||||
|
CPPFLAGS="$CPPFLAGS $ICU_CFLAGS"
|
||||||
|
LIBS="$LIBS $ICU_LIBS"
|
||||||
|
AC_MSG_CHECKING([whether boost.regex was compiled with ICU support])
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/regex/icu.hpp>]], [[boost::u32regex rx = boost::make_u32regex("foo"); if (boost::u32regex_search("foobar", rx)) { }]])],
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE([BOOST_REGEX_ICU], [1]),
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
CPPFLAGS="$old_CPPFLAGS"
|
||||||
|
LIBS="$old_LIBS",
|
||||||
|
)
|
||||||
|
],)
|
||||||
|
|
||||||
dnl =============================
|
dnl =============================
|
||||||
dnl = checking for boost.thread =
|
dnl = checking for boost.thread =
|
||||||
dnl =============================
|
dnl =============================
|
||||||
@@ -172,15 +193,10 @@ AC_DEFINE([BOOST_THREAD_VERSION], [3], [require boost.thread v3])
|
|||||||
AC_CHECK_HEADERS([boost/thread.hpp], ,
|
AC_CHECK_HEADERS([boost/thread.hpp], ,
|
||||||
AC_MSG_ERROR([boost/thread.hpp is missing or your boost version is too old (boost.thread v3 is required)])
|
AC_MSG_ERROR([boost/thread.hpp is missing or your boost version is too old (boost.thread v3 is required)])
|
||||||
)
|
)
|
||||||
AC_CHECK_LIB(boost_thread$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_thread$BOOST_LIB_SUFFIX",
|
AC_CHECK_LIB(boost_thread$BOOST_LIB_SUFFIX, main, LIBS="$LIBS -lboost_thread$BOOST_LIB_SUFFIX",
|
||||||
AC_MSG_ERROR([no boost.thread library found])
|
AC_MSG_ERROR([no boost.thread library found])
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl ==============================
|
|
||||||
dnl = checking for regex (win32) =
|
|
||||||
dnl ==============================
|
|
||||||
AC_CHECK_LIB(regex, regcomp, LDFLAGS="$LDFLAGS -lregex", )
|
|
||||||
|
|
||||||
dnl ================================
|
dnl ================================
|
||||||
dnl = checking for various headers =
|
dnl = checking for various headers =
|
||||||
dnl ================================
|
dnl ================================
|
||||||
@@ -191,11 +207,11 @@ dnl ==============================
|
|||||||
dnl = checking for libmpdclient2 =
|
dnl = checking for libmpdclient2 =
|
||||||
dnl ==============================
|
dnl ==============================
|
||||||
PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.8], [
|
PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.8], [
|
||||||
AC_SUBST(libmpdclient_LIBS)
|
|
||||||
AC_SUBST(libmpdclient_CFLAGS)
|
AC_SUBST(libmpdclient_CFLAGS)
|
||||||
|
AC_SUBST(libmpdclient_LIBS)
|
||||||
CPPFLAGS="$CPPFLAGS $libmpdclient_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $libmpdclient_CFLAGS"
|
||||||
AC_CHECK_HEADERS([mpd/client.h],
|
AC_CHECK_HEADERS([mpd/client.h],
|
||||||
LDFLAGS="$LDFLAGS $libmpdclient_LIBS"
|
LIBS="$LIBS $libmpdclient_LIBS"
|
||||||
,
|
,
|
||||||
AC_MSG_ERROR([missing mpd/client.h header])
|
AC_MSG_ERROR([missing mpd/client.h header])
|
||||||
)
|
)
|
||||||
@@ -207,7 +223,7 @@ dnl =========================
|
|||||||
dnl = checking for readline =
|
dnl = checking for readline =
|
||||||
dnl =========================
|
dnl =========================
|
||||||
AC_CHECK_HEADERS([readline/readline.h readline/history.h],
|
AC_CHECK_HEADERS([readline/readline.h readline/history.h],
|
||||||
AC_CHECK_LIB(readline, rl_initialize, LDFLAGS="$LDFLAGS -lreadline",
|
AC_CHECK_LIB(readline, rl_initialize, LIBS="$LIBS -lreadline",
|
||||||
AC_MSG_ERROR([readline headers found but there is no readline library to make use of])
|
AC_MSG_ERROR([readline headers found but there is no readline library to make use of])
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -217,7 +233,7 @@ dnl ========================
|
|||||||
dnl = checking for pthread =
|
dnl = checking for pthread =
|
||||||
dnl ========================
|
dnl ========================
|
||||||
AC_CHECK_HEADERS([pthread.h],
|
AC_CHECK_HEADERS([pthread.h],
|
||||||
AC_CHECK_LIB(pthread, pthread_create, LDFLAGS="$LDFLAGS -lpthread",
|
AC_CHECK_LIB(pthread, pthread_create, LIBS="$LIBS -lpthread",
|
||||||
AC_MSG_ERROR([pthread.h found but there is no pthread library to make use of])
|
AC_MSG_ERROR([pthread.h found but there is no pthread library to make use of])
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -235,7 +251,7 @@ fi
|
|||||||
AC_PATH_PROGS(CURSES_CONFIG, $curses_config_bin)
|
AC_PATH_PROGS(CURSES_CONFIG, $curses_config_bin)
|
||||||
if test "$CURSES_CONFIG" != "" ; then
|
if test "$CURSES_CONFIG" != "" ; then
|
||||||
CPPFLAGS="$CPPFLAGS `$CURSES_CONFIG --cflags`"
|
CPPFLAGS="$CPPFLAGS `$CURSES_CONFIG --cflags`"
|
||||||
LDFLAGS="$LDFLAGS `$CURSES_CONFIG --libs`"
|
LIBS="$LIBS `$CURSES_CONFIG --libs`"
|
||||||
fi
|
fi
|
||||||
AC_CHECK_LIB(ncursesw, initscr,
|
AC_CHECK_LIB(ncursesw, initscr,
|
||||||
curses_lib=ncursesw,
|
curses_lib=ncursesw,
|
||||||
@@ -244,7 +260,7 @@ AC_CHECK_LIB(ncursesw, initscr,
|
|||||||
|
|
||||||
AC_CHECK_LIB($curses_lib, initscr,
|
AC_CHECK_LIB($curses_lib, initscr,
|
||||||
if test "$CURSES_CONFIG" = "" ; then
|
if test "$CURSES_CONFIG" = "" ; then
|
||||||
LDFLAGS="$LDFLAGS -l$curses_lib"
|
LIBS="$LIBS -l$curses_lib"
|
||||||
fi
|
fi
|
||||||
,
|
,
|
||||||
AC_MSG_ERROR([$curses_lib library is required])
|
AC_MSG_ERROR([$curses_lib library is required])
|
||||||
@@ -261,7 +277,7 @@ if test "$visualizer" = "yes" ; then
|
|||||||
AC_SUBST(fftw3_CFLAGS)
|
AC_SUBST(fftw3_CFLAGS)
|
||||||
CPPFLAGS="$CPPFLAGS $fftw3_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $fftw3_CFLAGS"
|
||||||
AC_CHECK_HEADERS([fftw3.h],
|
AC_CHECK_HEADERS([fftw3.h],
|
||||||
LDFLAGS="$LDFLAGS $fftw3_LIBS"
|
LIBS="$LIBS $fftw3_LIBS"
|
||||||
,
|
,
|
||||||
if test "$fftw" = "yes" ; then
|
if test "$fftw" = "yes" ; then
|
||||||
AC_MSG_ERROR([missing fftw3.h header])
|
AC_MSG_ERROR([missing fftw3.h header])
|
||||||
@@ -283,7 +299,7 @@ if test "$curl" != "no" ; then
|
|||||||
AC_PATH_PROG(CURL_CONFIG, curl-config)
|
AC_PATH_PROG(CURL_CONFIG, curl-config)
|
||||||
if test "$CURL_CONFIG" != "" ; then
|
if test "$CURL_CONFIG" != "" ; then
|
||||||
CPPFLAGS="$CPPFLAGS `$CURL_CONFIG --cflags`"
|
CPPFLAGS="$CPPFLAGS `$CURL_CONFIG --cflags`"
|
||||||
AC_CHECK_LIB(curl, curl_easy_init, LDFLAGS="$LDFLAGS `$CURL_CONFIG --libs`",
|
AC_CHECK_LIB(curl, curl_easy_init, LIBS="$LIBS `$CURL_CONFIG --libs`",
|
||||||
if test "$curl" = "yes" ; then
|
if test "$curl" = "yes" ; then
|
||||||
AC_MSG_ERROR([curl library is required])
|
AC_MSG_ERROR([curl library is required])
|
||||||
fi
|
fi
|
||||||
@@ -294,7 +310,7 @@ if test "$curl" != "no" ; then
|
|||||||
fi
|
fi
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
AC_CHECK_LIB(curl, curl_easy_init, LDFLAGS="$LDFLAGS -lcurl",
|
AC_CHECK_LIB(curl, curl_easy_init, LIBS="$LIBS -lcurl",
|
||||||
if test "$curl" = "yes" ; then
|
if test "$curl" = "yes" ; then
|
||||||
AC_MSG_ERROR([curl library is required])
|
AC_MSG_ERROR([curl library is required])
|
||||||
fi
|
fi
|
||||||
@@ -309,7 +325,7 @@ if test "$taglib" != "no" ; then
|
|||||||
AC_PATH_PROG(TAGLIB_CONFIG, taglib-config)
|
AC_PATH_PROG(TAGLIB_CONFIG, taglib-config)
|
||||||
if test "$TAGLIB_CONFIG" != "" ; then
|
if test "$TAGLIB_CONFIG" != "" ; then
|
||||||
CPPFLAGS="$CPPFLAGS `$TAGLIB_CONFIG --cflags`"
|
CPPFLAGS="$CPPFLAGS `$TAGLIB_CONFIG --cflags`"
|
||||||
LDFLAGS="$LDFLAGS `$TAGLIB_CONFIG --libs`"
|
LIBS="$LIBS `$TAGLIB_CONFIG --libs`"
|
||||||
AC_CHECK_HEADERS([taglib.h], ,
|
AC_CHECK_HEADERS([taglib.h], ,
|
||||||
if test "$taglib" = "yes" ; then
|
if test "$taglib" = "yes" ; then
|
||||||
AC_MSG_ERROR([missing taglib.h header])
|
AC_MSG_ERROR([missing taglib.h header])
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void getLocalDirectoryRecursively(std::vector<MPD::Song> &songs, const std::stri
|
|||||||
void clearDirectory(const std::string &directory);
|
void clearDirectory(const std::string &directory);
|
||||||
|
|
||||||
std::string itemToString(const MPD::Item &item);
|
std::string itemToString(const MPD::Item &item);
|
||||||
bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter);
|
bool browserEntryMatcher(const Regex::Regex &rx, const MPD::Item &item, bool filter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,8 +287,8 @@ bool Browser::allowsSearching()
|
|||||||
|
|
||||||
void Browser::setSearchConstraint(const std::string &constraint)
|
void Browser::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
m_search_predicate = RegexFilter<MPD::Item>(
|
m_search_predicate = Regex::Filter<MPD::Item>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
boost::bind(browserEntryMatcher, _1, _2, false)
|
boost::bind(browserEntryMatcher, _1, _2, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -693,11 +693,11 @@ std::string itemToString(const MPD::Item &item)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter)
|
bool browserEntryMatcher(const Regex::Regex &rx, const MPD::Item &item, bool filter)
|
||||||
{
|
{
|
||||||
if (isItemParentDirectory(item))
|
if (isItemParentDirectory(item))
|
||||||
return filter;
|
return filter;
|
||||||
return boost::regex_search(itemToString(item), rx);
|
return Regex::search(itemToString(item), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ private:
|
|||||||
bool m_local_browser;
|
bool m_local_browser;
|
||||||
size_t m_scroll_beginning;
|
size_t m_scroll_beginning;
|
||||||
std::string m_current_directory;
|
std::string m_current_directory;
|
||||||
RegexFilter<MPD::Item> m_search_predicate;
|
Regex::Filter<MPD::Item> m_search_predicate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Browser *myBrowser;
|
extern Browser *myBrowser;
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ MPD::SongIterator getSongsFromAlbum(const AlbumEntry &album)
|
|||||||
std::string AlbumToString(const AlbumEntry &ae);
|
std::string AlbumToString(const AlbumEntry &ae);
|
||||||
std::string SongToString(const MPD::Song &s);
|
std::string SongToString(const MPD::Song &s);
|
||||||
|
|
||||||
bool TagEntryMatcher(const boost::regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
|
bool TagEntryMatcher(const Regex::Regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
|
||||||
bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
|
bool AlbumEntryMatcher(const Regex::Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
|
||||||
|
|
||||||
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag);
|
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag);
|
||||||
bool MoveToAlbum(NC::Menu<AlbumEntry> &albums, const std::string &primary_tag, const MPD::Song &s);
|
bool MoveToAlbum(NC::Menu<AlbumEntry> &albums, const std::string &primary_tag, const MPD::Song &s);
|
||||||
@@ -583,22 +583,22 @@ void MediaLibrary::setSearchConstraint(const std::string &constraint)
|
|||||||
{
|
{
|
||||||
if (isActiveWindow(Tags))
|
if (isActiveWindow(Tags))
|
||||||
{
|
{
|
||||||
m_tags_search_predicate = RegexFilter<PrimaryTag>(
|
m_tags_search_predicate = Regex::Filter<PrimaryTag>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
TagEntryMatcher
|
TagEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Albums))
|
else if (isActiveWindow(Albums))
|
||||||
{
|
{
|
||||||
m_albums_search_predicate = RegexItemFilter<AlbumEntry>(
|
m_albums_search_predicate = Regex::ItemFilter<AlbumEntry>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
boost::bind(AlbumEntryMatcher, _1, _2, false)
|
boost::bind(AlbumEntryMatcher, _1, _2, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Songs))
|
else if (isActiveWindow(Songs))
|
||||||
{
|
{
|
||||||
m_songs_search_predicate = RegexFilter<MPD::Song>(
|
m_songs_search_predicate = Regex::Filter<MPD::Song>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
SongEntryMatcher
|
SongEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1065,21 +1065,21 @@ std::string SongToString(const MPD::Song &s)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TagEntryMatcher(const boost::regex &rx, const PrimaryTag &pt)
|
bool TagEntryMatcher(const Regex::Regex &rx, const PrimaryTag &pt)
|
||||||
{
|
{
|
||||||
return boost::regex_search(pt.tag(), rx);
|
return Regex::search(pt.tag(), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter)
|
bool AlbumEntryMatcher(const Regex::Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter)
|
||||||
{
|
{
|
||||||
if (item.isSeparator() || item.value().isAllTracksEntry())
|
if (item.isSeparator() || item.value().isAllTracksEntry())
|
||||||
return filter;
|
return filter;
|
||||||
return boost::regex_search(AlbumToString(item.value()), rx);
|
return Regex::search(AlbumToString(item.value()), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
|
||||||
{
|
{
|
||||||
return boost::regex_search(SongToString(s), rx);
|
return Regex::search(SongToString(s), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag)
|
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag)
|
||||||
|
|||||||
@@ -148,9 +148,9 @@ private:
|
|||||||
const int m_window_timeout;
|
const int m_window_timeout;
|
||||||
const boost::posix_time::time_duration m_fetching_delay;
|
const boost::posix_time::time_duration m_fetching_delay;
|
||||||
|
|
||||||
RegexFilter<PrimaryTag> m_tags_search_predicate;
|
Regex::Filter<PrimaryTag> m_tags_search_predicate;
|
||||||
RegexItemFilter<AlbumEntry> m_albums_search_predicate;
|
Regex::ItemFilter<AlbumEntry> m_albums_search_predicate;
|
||||||
RegexFilter<MPD::Song> m_songs_search_predicate;
|
Regex::Filter<MPD::Song> m_songs_search_predicate;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Playlist *myPlaylist;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::string songToString(const MPD::Song &s);
|
std::string songToString(const MPD::Song &s);
|
||||||
bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s);
|
bool playlistEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,8 +167,8 @@ bool Playlist::allowsSearching()
|
|||||||
|
|
||||||
void Playlist::setSearchConstraint(const std::string &constraint)
|
void Playlist::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
m_search_predicate = RegexFilter<MPD::Song>(
|
m_search_predicate = Regex::Filter<MPD::Song>(
|
||||||
boost::regex(constraint, Config.regex_type), playlistEntryMatcher
|
Regex::make(constraint, Config.regex_type), playlistEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,9 +325,9 @@ std::string songToString(const MPD::Song &s)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s)
|
bool playlistEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
|
||||||
{
|
{
|
||||||
return boost::regex_search(songToString(s), rx);
|
return Regex::search(songToString(s), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ private:
|
|||||||
bool m_reload_total_length;
|
bool m_reload_total_length;
|
||||||
bool m_reload_remaining;
|
bool m_reload_remaining;
|
||||||
|
|
||||||
RegexFilter<MPD::Song> m_search_predicate;
|
Regex::Filter<MPD::Song> m_search_predicate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Playlist *myPlaylist;
|
extern Playlist *myPlaylist;
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ size_t RightColumnStartX;
|
|||||||
size_t RightColumnWidth;
|
size_t RightColumnWidth;
|
||||||
|
|
||||||
std::string SongToString(const MPD::Song &s);
|
std::string SongToString(const MPD::Song &s);
|
||||||
bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist);
|
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist);
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,15 +337,15 @@ void PlaylistEditor::setSearchConstraint(const std::string &constraint)
|
|||||||
{
|
{
|
||||||
if (isActiveWindow(Playlists))
|
if (isActiveWindow(Playlists))
|
||||||
{
|
{
|
||||||
m_playlists_search_predicate = RegexFilter<MPD::Playlist>(
|
m_playlists_search_predicate = Regex::Filter<MPD::Playlist>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
PlaylistEntryMatcher
|
PlaylistEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
{
|
{
|
||||||
m_content_search_predicate = RegexFilter<MPD::Song>(
|
m_content_search_predicate = Regex::Filter<MPD::Song>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
SongEntryMatcher
|
SongEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -513,14 +513,14 @@ std::string SongToString(const MPD::Song &s)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist)
|
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist)
|
||||||
{
|
{
|
||||||
return boost::regex_search(playlist.path(), rx);
|
return Regex::search(playlist.path(), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
|
||||||
{
|
{
|
||||||
return boost::regex_search(SongToString(s), rx);
|
return Regex::search(SongToString(s), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ private:
|
|||||||
const int m_window_timeout;
|
const int m_window_timeout;
|
||||||
const boost::posix_time::time_duration m_fetching_delay;
|
const boost::posix_time::time_duration m_fetching_delay;
|
||||||
|
|
||||||
RegexFilter<MPD::Playlist> m_playlists_search_predicate;
|
Regex::Filter<MPD::Playlist> m_playlists_search_predicate;
|
||||||
RegexFilter<MPD::Song> m_content_search_predicate;
|
Regex::Filter<MPD::Song> m_content_search_predicate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PlaylistEditor *myPlaylistEditor;
|
extern PlaylistEditor *myPlaylistEditor;
|
||||||
|
|||||||
@@ -21,18 +21,59 @@
|
|||||||
#ifndef NCMPCPP_REGEX_FILTER_H
|
#ifndef NCMPCPP_REGEX_FILTER_H
|
||||||
#define NCMPCPP_REGEX_FILTER_H
|
#define NCMPCPP_REGEX_FILTER_H
|
||||||
|
|
||||||
#include <boost/regex.hpp>
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef BOOST_REGEX_ICU
|
||||||
|
# include <boost/regex/icu.hpp>
|
||||||
|
#else
|
||||||
|
# include <boost/regex.hpp>
|
||||||
|
#endif // BOOST_REGEX_ICU
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace Regex {
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef BOOST_REGEX_ICU
|
||||||
|
boost::u32regex
|
||||||
|
#else
|
||||||
|
boost::regex
|
||||||
|
#endif // BOOST_REGEX_ICU
|
||||||
|
Regex;
|
||||||
|
|
||||||
|
template <typename StringT>
|
||||||
|
inline Regex make(StringT &&s, boost::regex_constants::syntax_option_type flags)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
# ifdef BOOST_REGEX_ICU
|
||||||
|
boost::make_u32regex
|
||||||
|
# else
|
||||||
|
boost::regex
|
||||||
|
# endif // BOOST_REGEX_ICU
|
||||||
|
(std::forward<StringT>(s), flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StringT>
|
||||||
|
inline bool search(StringT &&s, const Regex &rx)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
# ifdef BOOST_REGEX_ICU
|
||||||
|
boost::u32regex_search
|
||||||
|
# else
|
||||||
|
boost::regex_search
|
||||||
|
# endif // BOOST_REGEX_ICU
|
||||||
|
(std::forward<StringT>(s), rx);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct RegexFilter
|
struct Filter
|
||||||
{
|
{
|
||||||
typedef NC::Menu<T> MenuT;
|
typedef NC::Menu<T> MenuT;
|
||||||
typedef typename NC::Menu<T>::Item Item;
|
typedef typename NC::Menu<T>::Item Item;
|
||||||
typedef std::function<bool(const boost::regex &, const T &)> FilterFunction;
|
typedef std::function<bool(const Regex &, const T &)> FilterFunction;
|
||||||
|
|
||||||
RegexFilter() { }
|
Filter() { }
|
||||||
RegexFilter(boost::regex rx, FilterFunction filter)
|
Filter(Regex rx, FilterFunction filter)
|
||||||
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
|
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
@@ -51,18 +92,18 @@ struct RegexFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::regex m_rx;
|
Regex m_rx;
|
||||||
FilterFunction m_filter;
|
FilterFunction m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct RegexItemFilter
|
template <typename T> struct ItemFilter
|
||||||
{
|
{
|
||||||
typedef NC::Menu<T> MenuT;
|
typedef NC::Menu<T> MenuT;
|
||||||
typedef typename NC::Menu<T>::Item Item;
|
typedef typename NC::Menu<T>::Item Item;
|
||||||
typedef std::function<bool(const boost::regex &, const Item &)> FilterFunction;
|
typedef std::function<bool(const Regex &, const Item &)> FilterFunction;
|
||||||
|
|
||||||
RegexItemFilter() { }
|
ItemFilter() { }
|
||||||
RegexItemFilter(boost::regex rx, FilterFunction filter)
|
ItemFilter(Regex rx, FilterFunction filter)
|
||||||
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
|
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
@@ -80,8 +121,10 @@ template <typename T> struct RegexItemFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::regex m_rx;
|
Regex m_rx;
|
||||||
FilterFunction m_filter;
|
FilterFunction m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // NCMPCPP_REGEX_FILTER_H
|
#endif // NCMPCPP_REGEX_FILTER_H
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace pos {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
std::string SEItemToString(const SEItem &ei);
|
std::string SEItemToString(const SEItem &ei);
|
||||||
bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
|
bool SEItemEntryMatcher(const Regex::Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,8 +264,8 @@ bool SearchEngine::allowsSearching()
|
|||||||
|
|
||||||
void SearchEngine::setSearchConstraint(const std::string &constraint)
|
void SearchEngine::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
m_search_predicate = RegexItemFilter<SEItem>(
|
m_search_predicate = Regex::ItemFilter<SEItem>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
boost::bind(SEItemEntryMatcher, _1, _2, false)
|
boost::bind(SEItemEntryMatcher, _1, _2, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -401,7 +401,7 @@ void SearchEngine::Search()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::regex rx[ConstraintsNumber];
|
Regex::Regex rx[ConstraintsNumber];
|
||||||
if (SearchMode != &SearchModes[2]) // match to pattern
|
if (SearchMode != &SearchModes[2]) // match to pattern
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < ConstraintsNumber; ++i)
|
for (size_t i = 0; i < ConstraintsNumber; ++i)
|
||||||
@@ -410,7 +410,7 @@ void SearchEngine::Search()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
rx[i].assign(itsConstraints[i], Config.regex_type);
|
rx[i] = Regex::make(itsConstraints[i], Config.regex_type);
|
||||||
}
|
}
|
||||||
catch (boost::bad_expression &) { }
|
catch (boost::bad_expression &) { }
|
||||||
}
|
}
|
||||||
@@ -444,36 +444,36 @@ void SearchEngine::Search()
|
|||||||
{
|
{
|
||||||
if (!rx[0].empty())
|
if (!rx[0].empty())
|
||||||
any_found =
|
any_found =
|
||||||
boost::regex_search(s->getArtist(), rx[0])
|
Regex::search(s->getArtist(), rx[0])
|
||||||
|| boost::regex_search(s->getAlbumArtist(), rx[0])
|
|| Regex::search(s->getAlbumArtist(), rx[0])
|
||||||
|| boost::regex_search(s->getTitle(), rx[0])
|
|| Regex::search(s->getTitle(), rx[0])
|
||||||
|| boost::regex_search(s->getAlbum(), rx[0])
|
|| Regex::search(s->getAlbum(), rx[0])
|
||||||
|| boost::regex_search(s->getName(), rx[0])
|
|| Regex::search(s->getName(), rx[0])
|
||||||
|| boost::regex_search(s->getComposer(), rx[0])
|
|| Regex::search(s->getComposer(), rx[0])
|
||||||
|| boost::regex_search(s->getPerformer(), rx[0])
|
|| Regex::search(s->getPerformer(), rx[0])
|
||||||
|| boost::regex_search(s->getGenre(), rx[0])
|
|| Regex::search(s->getGenre(), rx[0])
|
||||||
|| boost::regex_search(s->getDate(), rx[0])
|
|| Regex::search(s->getDate(), rx[0])
|
||||||
|| boost::regex_search(s->getComment(), rx[0]);
|
|| Regex::search(s->getComment(), rx[0]);
|
||||||
if (found && !rx[1].empty())
|
if (found && !rx[1].empty())
|
||||||
found = boost::regex_search(s->getArtist(), rx[1]);
|
found = Regex::search(s->getArtist(), rx[1]);
|
||||||
if (found && !rx[2].empty())
|
if (found && !rx[2].empty())
|
||||||
found = boost::regex_search(s->getAlbumArtist(), rx[2]);
|
found = Regex::search(s->getAlbumArtist(), rx[2]);
|
||||||
if (found && !rx[3].empty())
|
if (found && !rx[3].empty())
|
||||||
found = boost::regex_search(s->getTitle(), rx[3]);
|
found = Regex::search(s->getTitle(), rx[3]);
|
||||||
if (found && !rx[4].empty())
|
if (found && !rx[4].empty())
|
||||||
found = boost::regex_search(s->getAlbum(), rx[4]);
|
found = Regex::search(s->getAlbum(), rx[4]);
|
||||||
if (found && !rx[5].empty())
|
if (found && !rx[5].empty())
|
||||||
found = boost::regex_search(s->getName(), rx[5]);
|
found = Regex::search(s->getName(), rx[5]);
|
||||||
if (found && !rx[6].empty())
|
if (found && !rx[6].empty())
|
||||||
found = boost::regex_search(s->getComposer(), rx[6]);
|
found = Regex::search(s->getComposer(), rx[6]);
|
||||||
if (found && !rx[7].empty())
|
if (found && !rx[7].empty())
|
||||||
found = boost::regex_search(s->getPerformer(), rx[7]);
|
found = Regex::search(s->getPerformer(), rx[7]);
|
||||||
if (found && !rx[8].empty())
|
if (found && !rx[8].empty())
|
||||||
found = boost::regex_search(s->getGenre(), rx[8]);
|
found = Regex::search(s->getGenre(), rx[8]);
|
||||||
if (found && !rx[9].empty())
|
if (found && !rx[9].empty())
|
||||||
found = boost::regex_search(s->getDate(), rx[9]);
|
found = Regex::search(s->getDate(), rx[9]);
|
||||||
if (found && !rx[10].empty())
|
if (found && !rx[10].empty())
|
||||||
found = boost::regex_search(s->getComment(), rx[10]);
|
found = Regex::search(s->getComment(), rx[10]);
|
||||||
}
|
}
|
||||||
else // match only if values are equal
|
else // match only if values are equal
|
||||||
{
|
{
|
||||||
@@ -539,11 +539,11 @@ std::string SEItemToString(const SEItem &ei)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter)
|
bool SEItemEntryMatcher(const Regex::Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter)
|
||||||
{
|
{
|
||||||
if (item.isSeparator() || !item.value().isSong())
|
if (item.isSeparator() || !item.value().isSong())
|
||||||
return filter;
|
return filter;
|
||||||
return boost::regex_search(SEItemToString(item.value()), rx);
|
return Regex::search(SEItemToString(item.value()), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ private:
|
|||||||
void Prepare();
|
void Prepare();
|
||||||
void Search();
|
void Search();
|
||||||
|
|
||||||
RegexItemFilter<SEItem> m_search_predicate;
|
Regex::ItemFilter<SEItem> m_search_predicate;
|
||||||
|
|
||||||
const char **SearchMode;
|
const char **SearchMode;
|
||||||
|
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ std::string GenerateFilename(const MPD::MutableSong &s, const std::string &patte
|
|||||||
std::string ParseFilename(MPD::MutableSong &s, std::string mask, bool preview);
|
std::string ParseFilename(MPD::MutableSong &s, std::string mask, bool preview);
|
||||||
|
|
||||||
std::string SongToString(const MPD::MutableSong &s);
|
std::string SongToString(const MPD::MutableSong &s);
|
||||||
bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
|
bool DirEntryMatcher(const Regex::Regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s);
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::MutableSong &s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,15 +726,15 @@ void TagEditor::setSearchConstraint(const std::string &constraint)
|
|||||||
{
|
{
|
||||||
if (w == Dirs)
|
if (w == Dirs)
|
||||||
{
|
{
|
||||||
m_directories_search_predicate = RegexFilter<std::pair<std::string, std::string>>(
|
m_directories_search_predicate = Regex::Filter<std::pair<std::string, std::string>>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
boost::bind(DirEntryMatcher, _1, _2, false)
|
boost::bind(DirEntryMatcher, _1, _2, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (w == Tags)
|
else if (w == Tags)
|
||||||
{
|
{
|
||||||
m_songs_search_predicate = RegexFilter<MPD::MutableSong>(
|
m_songs_search_predicate = Regex::Filter<MPD::MutableSong>(
|
||||||
boost::regex(constraint, Config.regex_type),
|
Regex::make(constraint, Config.regex_type),
|
||||||
SongEntryMatcher
|
SongEntryMatcher
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1125,16 +1125,16 @@ std::string SongToString(const MPD::MutableSong &s)
|
|||||||
return result.empty() ? Config.empty_tag : result;
|
return result.empty() ? Config.empty_tag : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter)
|
bool DirEntryMatcher(const Regex::Regex &rx, const std::pair<std::string, std::string> &dir, bool filter)
|
||||||
{
|
{
|
||||||
if (dir.first == "." || dir.first == "..")
|
if (dir.first == "." || dir.first == "..")
|
||||||
return filter;
|
return filter;
|
||||||
return boost::regex_search(dir.first, rx);
|
return Regex::search(dir.first, rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s)
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::MutableSong &s)
|
||||||
{
|
{
|
||||||
return boost::regex_search(SongToString(s), rx);
|
return Regex::search(SongToString(s), rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ private:
|
|||||||
std::string itsBrowsedDir;
|
std::string itsBrowsedDir;
|
||||||
std::string itsHighlightedDir;
|
std::string itsHighlightedDir;
|
||||||
|
|
||||||
RegexFilter<std::pair<std::string, std::string>> m_directories_search_predicate;
|
Regex::Filter<std::pair<std::string, std::string>> m_directories_search_predicate;
|
||||||
RegexFilter<MPD::MutableSong> m_songs_search_predicate;
|
Regex::Filter<MPD::MutableSong> m_songs_search_predicate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TagEditor *myTagEditor;
|
extern TagEditor *myTagEditor;
|
||||||
|
|||||||
Reference in New Issue
Block a user