+
+namespace {
+
+
+/** Check if 'len' letters following cursor are all non-lowercase */
+static bool allNonLowercase(DocIterator const & cur, int len) {
+ pos_type end_pos = cur.pos() + len;
+ for (pos_type pos = cur.pos(); pos != end_pos; ++pos)
+ if (isLowerCase(cur.paragraph().getChar(pos)))
+ return false;
+ return true;
+}
+
+
+/** Check if first letter is upper case and second one is lower case */
+static bool firstUppercase(DocIterator const & cur) {
+ char_type ch1, ch2;
+ if (cur.pos() >= cur.lastpos() - 1) {
+ LYXERR(Debug::FIND, "No upper-case at cur: " << cur);
+ return false;
+ }
+ ch1 = cur.paragraph().getChar(cur.pos());
+ ch2 = cur.paragraph().getChar(cur.pos()+1);
+ bool result = isUpperCase(ch1) && isLowerCase(ch2);
+ LYXERR(Debug::FIND, "firstUppercase(): "
+ << "ch1=" << ch1 << "(" << char(ch1) << "), ch2="
+ << ch2 << "(" << char(ch2) << ")"
+ << ", result=" << result << ", cur=" << cur);
+ return result;
+}
+
+
+/** Make first letter of supplied buffer upper-case, and the rest lower-case.
+ **
+ ** \fixme What to do with possible further paragraphs in replace buffer ?
+ **/
+static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase others_case) {
+ ParagraphList::iterator pit = buffer.paragraphs().begin();
+ pos_type right = pos_type(1);
+ pit->changeCase(buffer.params(), pos_type(0), right, first_case);
+ right = pit->size() + 1;
+ pit->changeCase(buffer.params(), right, right, others_case);
+}
+} // anon namespace
+
+///
+static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, MatchStringAdv & matchAdv)
+{
+ Cursor & cur = bv->cursor();
+ if (opt.replace == docstring(from_utf8(LYX_FR_NULL_STRING)))
+ return;
+ DocIterator sel_beg = cur.selectionBegin();
+ DocIterator sel_end = cur.selectionEnd();
+ if (&sel_beg.inset() != &sel_end.inset()
+ || sel_beg.pit() != sel_end.pit())
+ return;
+ int sel_len = sel_end.pos() - sel_beg.pos();
+ LYXERR(Debug::FIND, "sel_beg: " << sel_beg << ", sel_end: " << sel_end
+ << ", sel_len: " << sel_len << endl);
+ if (sel_len == 0)
+ return;
+ LASSERT(sel_len > 0, /**/);
+
+ if (!matchAdv(sel_beg, sel_len))
+ return;
+
+ string lyx = to_utf8(opt.replace);
+ // FIXME: Seems so stupid to me to rebuild a buffer here,
+ // when we already have one (replace_work_area_.buffer())
+ Buffer repl_buffer("", false);
+ repl_buffer.setUnnamed(true);
+ LASSERT(repl_buffer.readString(lyx), /**/);
+ repl_buffer.changeLanguage(
+ repl_buffer.language(),
+ cur.getFont().language());
+ if (opt.keep_case && sel_len >= 2) {
+ if (cur.inTexted()) {
+ if (firstUppercase(cur))
+ changeFirstCase(repl_buffer, text_uppercase, text_lowercase);
+ else if (allNonLowercase(cur, sel_len))
+ changeFirstCase(repl_buffer, text_uppercase, text_uppercase);
+ }
+ }
+ cap::cutSelection(cur, false, false);
+ if (!cur.inMathed()) {
+ LYXERR(Debug::FIND, "Replacing by pasteParagraphList()ing repl_buffer");
+ cap::pasteParagraphList(cur, repl_buffer.paragraphs(),
+ repl_buffer.params().documentClassPtr(),
+ bv->buffer().errorList("Paste"));
+ } else {
+ odocstringstream ods;
+ OutputParams runparams(&repl_buffer.params().encoding());
+ runparams.nice = false;
+ runparams.flavor = OutputParams::LATEX;
+ runparams.linelen = 8000; //lyxrc.plaintext_linelen;
+ runparams.dryrun = true;
+ TexRow texrow;
+ TeXOnePar(repl_buffer, repl_buffer.text(),
+ repl_buffer.paragraphs().begin(), ods, texrow, runparams);
+ //repl_buffer.getSourceCode(ods, 0, repl_buffer.paragraphs().size(), false);
+ docstring repl_latex = ods.str();
+ LYXERR(Debug::FIND, "Latexified replace_buffer: '" << repl_latex << "'");
+ string s;
+ regex_replace(to_utf8(repl_latex), s, "\\$(.*)\\$", "$1");
+ regex_replace(s, s, "\\\\\\[(.*)\\\\\\]", "$1");
+ repl_latex = from_utf8(s);
+ LYXERR(Debug::FIND, "Replacing by niceInsert()ing latex: '" << repl_latex << "'");
+ cur.niceInsert(repl_latex);
+ }
+ bv->buffer().markDirty();
+ cur.pos() -= repl_buffer.paragraphs().begin()->size();
+ bv->putSelectionAt(DocIterator(cur), repl_buffer.paragraphs().begin()->size(), !opt.forward);
+ bv->processUpdateFlags(Update::Force);
+}
+
+