+ if (entry_type.empty())
+ return;
+
+ vector<docstring>::iterator it = keyVector.begin();
+ vector<docstring>::iterator end = keyVector.end();
+
+ vector<docstring> result;
+ for (; it != end; ++it) {
+ docstring const key = *it;
+ BiblioInfo::const_iterator cit = bi.find(key);
+ if (cit == bi.end())
+ continue;
+ if (cit->second.entryType() == entry_type)
+ result.push_back(key);
+ }
+ keyVector = result;
+}
+
+
+CiteEngine GuiCitation::citeEngine() const
+{
+ return buffer().params().citeEngine();
+}
+
+
+// Escape special chars.
+// All characters are literals except: '.|*?+(){}[]^$\'
+// These characters are literals when preceded by a "\", which is done here
+// @todo: This function should be moved to support, and then the test in tests
+// should be moved there as well.
+static docstring escape_special_chars(docstring const & expr)
+{
+ // Search for all chars '.|*?+(){}[^$]\'
+ // Note that '[' and '\' must be escaped.
+ // This is a limitation of boost::regex, but all other chars in BREs
+ // are assumed literal.
+ static const boost::regex reg("[].|*?+(){}^$\\[\\\\]");
+
+ // $& is a perl-like expression that expands to all
+ // of the current match
+ // The '$' must be prefixed with the escape character '\' for
+ // boost to treat it as a literal.
+ // Thus, to prefix a matched expression with '\', we use:
+ // FIXME: UNICODE
+ return from_utf8(boost::regex_replace(to_utf8(expr), reg, "\\\\$&"));
+}
+
+
+vector<docstring> GuiCitation::searchKeys(BiblioInfo const & bi,
+ vector<docstring> const & keys_to_search, bool only_keys,
+ docstring const & search_expression, docstring field,
+ bool case_sensitive, bool regex)
+{
+ vector<docstring> foundKeys;
+
+ docstring expr = trim(search_expression);
+ if (expr.empty())
+ return foundKeys;
+
+ if (!regex)
+ // We must escape special chars in the search_expr so that
+ // it is treated as a simple string by boost::regex.
+ expr = escape_special_chars(expr);
+
+ boost::regex reg_exp;
+ try {
+ reg_exp.assign(to_utf8(expr), case_sensitive ?
+ boost::regex_constants::normal : boost::regex_constants::icase);
+ } catch (boost::regex_error & e) {
+ // boost::regex throws an exception if the regular expression is not
+ // valid.
+ LYXERR(Debug::GUI, e.what());
+ return vector<docstring>();
+ }
+
+ vector<docstring>::const_iterator it = keys_to_search.begin();
+ vector<docstring>::const_iterator end = keys_to_search.end();
+ for (; it != end; ++it ) {
+ BiblioInfo::const_iterator info = bi.find(*it);
+ if (info == bi.end())
+ continue;
+
+ BibTeXInfo const & kvm = info->second;
+ string data;
+ if (only_keys)
+ data = to_utf8(*it);
+ else if (field.empty())
+ data = to_utf8(*it) + ' ' + to_utf8(kvm.allData());
+ else
+ data = to_utf8(kvm[field]);
+
+ if (data.empty())
+ continue;
+
+ try {
+ if (boost::regex_search(data, reg_exp))
+ foundKeys.push_back(*it);
+ }
+ catch (boost::regex_error & e) {
+ LYXERR(Debug::GUI, e.what());
+ return vector<docstring>();
+ }
+ }
+ return foundKeys;