X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=fd44187104fdb9a6d80ed04f18cb54c0875f562b;hb=5b75a45bc1c590cca5ac2a3e539a741a4aede26a;hp=bb4518031a43dc37d69a0297d0c708308c6d1d62;hpb=24e2c495fe9836603ccf59f402f9499476975898;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index bb4518031a..fd44187104 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -17,39 +17,35 @@ #include "lyxfind.h" #include "Buffer.h" -#include "BufferList.h" #include "buffer_funcs.h" +#include "BufferList.h" #include "BufferParams.h" #include "BufferView.h" #include "Changes.h" #include "Cursor.h" #include "CutAndPaste.h" #include "FuncRequest.h" -#include "OutputParams.h" +#include "LyX.h" #include "output_latex.h" +#include "OutputParams.h" #include "Paragraph.h" #include "ParIterator.h" #include "TexRow.h" #include "Text.h" -#include "FuncRequest.h" -#include "LyXFunc.h" + +#include "frontends/alert.h" #include "mathed/InsetMath.h" #include "mathed/InsetMathGrid.h" #include "mathed/InsetMathHull.h" #include "mathed/MathStream.h" -#include "frontends/alert.h" - #include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" #include "support/gettext.h" -#include "support/lstrings.h" #include "support/lassert.h" - -#include "frontends/Application.h" -#include "frontends/LyXView.h" +#include "support/lstrings.h" #include #include @@ -175,6 +171,8 @@ int replaceAll(BufferView * bv, if (!searchAllowed(bv, searchstr) || buf.isReadonly()) return 0; + DocIterator cur_orig(bv->cursor()); + MatchString const match(searchstr, cs, mw); int num = 0; @@ -198,10 +196,14 @@ int replaceAll(BufferView * bv, ++num; } - buf.updateLabels(); + buf.updateBuffer(); bv->putSelectionAt(doc_iterator_begin(&buf), 0, false); if (num) buf.markDirty(); + + cur_orig.fixIfBroken(); + bv->setCursor(cur_orig); + return num; } @@ -210,8 +212,10 @@ bool stringSelected(BufferView * bv, docstring & searchstr, bool cs, bool mw, bool fw) { // if nothing selected and searched string is empty, this - // means that we want to search current word at cursor position. - if (!bv->cursor().selection() && searchstr.empty()) { + // means that we want to search current word at cursor position, + // but only if we are in texted() mode. + if (!bv->cursor().selection() && searchstr.empty() + && bv->cursor().inTexted()) { bv->cursor().innerText()->selectWord(bv->cursor(), WHOLE_WORD); searchstr = bv->cursor().selectionAsString(false); return true; @@ -281,7 +285,7 @@ docstring const replace2string(docstring const & replace, bool find(BufferView * bv, FuncRequest const & ev) { - if (!bv || ev.action != LFUN_WORD_FIND) + if (!bv || ev.action() != LFUN_WORD_FIND) return false; //lyxerr << "find called, cmd: " << ev << endl; @@ -302,7 +306,7 @@ bool find(BufferView * bv, FuncRequest const & ev) void replace(BufferView * bv, FuncRequest const & ev, bool has_deleted) { - if (!bv || ev.action != LFUN_WORD_REPLACE) + if (!bv || ev.action() != LFUN_WORD_REPLACE) return; // data is of the form @@ -367,7 +371,7 @@ bool findChange(BufferView * bv, bool next) if (bv->cursor().selection()) { // set the cursor at the beginning or at the end of the selection // before searching. Otherwise, the current change will be found. - if (next != (bv->cursor().top() > bv->cursor().anchor())) + if (next != (bv->cursor().top() > bv->cursor().normalAnchor())) bv->cursor().setCursorToAnchor(); } @@ -377,11 +381,18 @@ bool findChange(BufferView * bv, bool next) // clear the selection and search the other way around (see the end // of this function). This will avoid changes to be selected half. bool search_both_sides = false; - if (cur.pos() > 1) { - Change change_next_pos - = cur.paragraph().lookupChange(cur.pos()); + DocIterator tmpcur = cur; + // Leave math first + while (tmpcur.inMathed()) + tmpcur.pop_back(); + Change change_next_pos + = tmpcur.paragraph().lookupChange(tmpcur.pos()); + if (change_next_pos.changed() && cur.inMathed()) { + cur = tmpcur; + search_both_sides = true; + } else if (tmpcur.pos() > 0 && tmpcur.inTexted()) { Change change_prev_pos - = cur.paragraph().lookupChange(cur.pos() - 1); + = tmpcur.paragraph().lookupChange(tmpcur.pos() - 1); if (change_next_pos.isSimilarTo(change_prev_pos)) search_both_sides = true; } @@ -402,14 +413,14 @@ bool findChange(BufferView * bv, bool next) if (next) { for (; !tip.at_end(); tip.forwardPos()) { Change change = tip.paragraph().lookupChange(tip.pos()); - if (change != orig_change) + if (!change.isSimilarTo(orig_change)) break; } } else { for (; !tip.at_begin();) { tip.backwardPos(); Change change = tip.paragraph().lookupChange(tip.pos()); - if (change != orig_change) { + if (!change.isSimilarTo(orig_change)) { // take a step forward to correctly set the selection tip.forwardPos(); break; @@ -516,33 +527,34 @@ string escape_for_regex(string s) { size_t pos = 0; while (pos < s.size()) { - size_t new_pos = s.find("\\regexp{", pos); - if (new_pos == string::npos) - new_pos = s.size(); - LYXERR(Debug::FIND, "new_pos: " << new_pos); - string t = apply_escapes(s.substr(pos, new_pos - pos), get_lyx_unescapes()); - LYXERR(Debug::FIND, "t : " << t); - t = apply_escapes(t, get_regexp_escapes()); - s.replace(pos, new_pos - pos, t); - new_pos = pos + t.size(); - LYXERR(Debug::FIND, "Regexp after escaping: " << s); - LYXERR(Debug::FIND, "new_pos: " << new_pos); - if (new_pos == s.size()) - break; - size_t end_pos = find_matching_brace(s, new_pos + 7); - LYXERR(Debug::FIND, "end_pos: " << end_pos); - t = apply_escapes(s.substr(new_pos + 8, end_pos - (new_pos + 8)), get_lyx_unescapes()); - LYXERR(Debug::FIND, "t : " << t); - if (end_pos == s.size()) { - s.replace(new_pos, end_pos - new_pos, t); - pos = s.size(); - LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); - break; - } - s.replace(new_pos, end_pos + 1 - new_pos, t); + size_t new_pos = s.find("\\regexp{{{", pos); + if (new_pos == string::npos) + new_pos = s.size(); + LYXERR(Debug::FIND, "new_pos: " << new_pos); + string t = apply_escapes(s.substr(pos, new_pos - pos), get_lyx_unescapes()); + LYXERR(Debug::FIND, "t : " << t); + t = apply_escapes(t, get_regexp_escapes()); + LYXERR(Debug::FIND, "t : " << t); + s.replace(pos, new_pos - pos, t); + new_pos = pos + t.size(); + LYXERR(Debug::FIND, "Regexp after escaping: " << s); + LYXERR(Debug::FIND, "new_pos: " << new_pos); + if (new_pos == s.size()) + break; + size_t end_pos = s.find("}}}", new_pos + 10); // find_matching_brace(s, new_pos + 7); + LYXERR(Debug::FIND, "end_pos: " << end_pos); + t = apply_escapes(s.substr(new_pos + 10, end_pos - (new_pos + 10)), get_lyx_unescapes()); + LYXERR(Debug::FIND, "t : " << t); + if (end_pos == s.size()) { + s.replace(new_pos, end_pos - new_pos, t); + pos = s.size(); LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); - pos = new_pos + t.size(); - LYXERR(Debug::FIND, "pos: " << pos); + break; + } + s.replace(new_pos, end_pos + 3 - new_pos, t); + LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); + pos = new_pos + t.size(); + LYXERR(Debug::FIND, "pos: " << pos); } return s; } @@ -570,7 +582,8 @@ bool regex_replace(string const & s, string & t, string const & searchstr, ** Number of open braces that must remain open at the end for the verification to succeed. **/ bool braces_match(string::const_iterator const & beg, - string::const_iterator const & end, int unmatched = 0) + string::const_iterator const & end, + int unmatched = 0) { int open_pars = 0; string::const_iterator it = beg; @@ -628,6 +641,9 @@ public: FindAndReplaceOptions const & opt; private: + /// Auxiliary find method (does not account for opt.matchword) + int findAux(DocIterator const & cur, int len = -1, bool at_begin = true) const; + /** Normalize a stringified or latexified LyX paragraph. ** ** Normalize means: @@ -683,7 +699,6 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & break; } while (true); LYXERR(Debug::FIND, "Open braces: " << open_braces); - LASSERT(braces_match(par_as_string.begin(), par_as_string.end(), open_braces), /* */); LYXERR(Debug::FIND, "Built MatchStringAdv object: par_as_string = '" << par_as_string << "'"); } else { par_as_string = escape_for_regex(par_as_string); @@ -705,7 +720,6 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & LYXERR(Debug::FIND, "par_as_string now is '" << par_as_string << "'"); LYXERR(Debug::FIND, "Open braces: " << open_braces); LYXERR(Debug::FIND, "Close .*? : " << close_wildcards); - LASSERT(braces_match(par_as_string.begin(), par_as_string.end(), open_braces), /* */); LYXERR(Debug::FIND, "Replaced text (to be used as regex): " << par_as_string); // If entered regexp must match at begin of searched string buffer regexp = boost::regex(string("\\`") + par_as_string); @@ -715,7 +729,7 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & } -int MatchStringAdv::operator()(DocIterator const & cur, int len, bool at_begin) const +int MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_begin) const { docstring docstr = stringifyFromForSearch(opt, cur, len); LYXERR(Debug::FIND, "Matching against '" << lyx::to_utf8(docstr) << "'"); @@ -758,6 +772,26 @@ int MatchStringAdv::operator()(DocIterator const & cur, int len, bool at_begin) } +int MatchStringAdv::operator()(DocIterator const & cur, int len, bool at_begin) const +{ + int res = findAux(cur, len, at_begin); + if (res == 0 || !at_begin || !opt.matchword || !cur.inTexted()) + return res; + Paragraph const & par = cur.paragraph(); + bool ws_left = cur.pos() > 0 ? + par.isWordSeparator(cur.pos() - 1) : true; + bool ws_right = cur.pos() + res < par.size() ? + par.isWordSeparator(cur.pos() + res) : true; + LYXERR(Debug::FIND, + "cur.pos()=" << cur.pos() << ", res=" << res + << ", separ: " << ws_left << ", " << ws_right + << endl); + if (ws_left && ws_right) + return res; + return 0; +} + + string MatchStringAdv::normalize(docstring const & s) const { string t; @@ -844,9 +878,6 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) ParagraphList::const_iterator pit = cur.innerText()->paragraphs().begin(); for (int i = 0; i < cur.pit(); ++i) ++pit; -// ParagraphList::const_iterator pit_end = pit; -// ++pit_end; -// lyx::latexParagraphs(buf, cur.innerText()->paragraphs(), ods, texrow, runparams, string(), pit, pit_end); pos_type const endpos = (len == -1 || cur.pos() + len > int(pit->size())) ? pit->size() : cur.pos() + len; TeXOnePar(buf, *cur.innerText(), pit, ods, texrow, runparams, string(), @@ -870,13 +901,6 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) for (MathData::const_iterator it = md.begin() + cs.pos(); it != it_end; ++it) ods << *it; - // MathData md = cur.cell(); - // MathData::const_iterator it_end = ( ( len == -1 || cur.pos() + len > int(md.size()) ) ? md.end() : md.begin() + cur.pos() + len ); - // for (MathData::const_iterator it = md.begin() + cur.pos(); it != it_end; ++it) { - // MathAtom const & ma = *it; - // ma.nucleus()->latex(buf, ods, runparams); - // } - // Retrieve the math environment type, and add '$' or '$]' // or others (\end{equation}) accordingly for (int s = cur.depth() - 1; s >= 0; --s) { @@ -918,6 +942,8 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match) // Compute the match length int len = 1; + if (cur.pos() + len > cur.lastpos()) + return 0; LYXERR(Debug::FIND, "verifying unmatch with len = " << len); while (cur.pos() + len <= cur.lastpos() && match(cur, len) == 0) { ++len; @@ -936,271 +962,96 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match) } -/** Switch p_buf to point to next document buffer. - ** - ** Return true if restarted from master-document buffer. - ** - ** @note - ** Not using p_buf->allRelatives() here, because I'm not sure - ** whether or not the returned order is independent of p_buf. - **/ -bool next_document_buffer(Buffer * & p_buf) { - Buffer *p_master = p_buf; - Buffer *p_old; - do { - p_old = p_master; - p_master = const_cast(p_master->masterBuffer()); - LYXERR(Debug::FIND, "p_old=" << p_old << ", p_master=" << p_master); - } while (p_master != p_old); - LASSERT(p_master != NULL, /**/); - vector v_children; - /* Root master added as first buffer in the vector */ - v_children.push_back(p_master); - p_master->getChildren(v_children, true); - LYXERR(Debug::FIND, "v_children.size()=" << v_children.size()); - vector::const_iterator it = find(v_children.begin(), v_children.end(), p_buf); - LASSERT(it != v_children.end(), /**/) - ++it; - if (it == v_children.end()) { - p_buf = *v_children.begin(); - return true; - } - p_buf = *it; - return false; -} - - -/** Switch p_buf to point to previous document buffer. - ** - ** Return true if restarted from last child buffer. - ** - ** @note - ** Not using p_buf->allRelatives() here, because I'm not sure - ** whether or not the returned order is independent of p_buf. - **/ -bool prev_document_buffer(Buffer * & p_buf) { - Buffer *p_master = p_buf; - Buffer *p_old; - do { - p_old = p_master; - p_master = const_cast(p_master->masterBuffer()); - LYXERR(Debug::FIND, "p_old=" << p_old << ", p_master=" << p_master); - } while (p_master != p_old); - LASSERT(p_master != NULL, /**/); - vector v_children; - /* Root master added as first buffer in the vector */ - v_children.push_back(p_master); - p_master->getChildren(v_children, true); - LYXERR(Debug::FIND, "v_children.size()=" << v_children.size()); - vector::const_iterator it = find(v_children.begin(), v_children.end(), p_buf); - LASSERT(it != v_children.end(), /**/) - if (it == v_children.begin()) { - it = v_children.end(); - --it; - p_buf = *it; - return true; - } - --it; - p_buf = *it; - return false; -} - - -/** Switch p_buf to point to next open buffer. - ** - ** Return true if restarted from first open buffer. - **/ -bool next_open_buffer(Buffer * & p_buf) { - BufferList::const_iterator it = find(theBufferList().begin(), theBufferList().end(), p_buf); - LASSERT(it != theBufferList().end(), /**/) - ++it; - if (it == theBufferList().end()) { - p_buf = *theBufferList().begin(); - return true; - } - p_buf = *it; - return false; -} - - -/** Switch p_buf to point to previous open buffer. - ** - ** Return true if restarted from last open buffer. - **/ -bool prev_open_buffer(Buffer * & p_buf) { - BufferList::const_iterator it = find(theBufferList().begin(), theBufferList().end(), p_buf); - LASSERT(it != theBufferList().end(), /**/) - if (it == theBufferList().begin()) { - it = theBufferList().end(); - --it; - p_buf = *it; - return true; - } - --it; - p_buf = *it; - return false; -} - - /// Finds forward int findForwardAdv(DocIterator & cur, MatchStringAdv & match) { if (!cur) return 0; - int wrap_answer = -1; - do { - while (cur && !match(cur, -1, false)) { - if (cur.pit() < cur.lastpit()) - cur.forwardPar(); - else { - cur.forwardPos(); - } - } - for (; cur; cur.forwardPos()) { - if (match(cur)) - return findAdvFinalize(cur, match); - } - // No match has been found in current buffer - bool prompt = false; - if (match.opt.scope == FindAndReplaceOptions::S_BUFFER) { - prompt = true; - } else if (match.opt.scope == FindAndReplaceOptions::S_DOCUMENT) { - prompt = next_document_buffer(match.p_buf); - } else if (match.opt.scope == FindAndReplaceOptions::S_OPEN_BUFFERS) { - prompt = next_open_buffer(match.p_buf); - } else { - /* Unimplemented scope */ - LASSERT(false, /**/); - } - if (prompt) { - if (wrap_answer != -1) - break; - wrap_answer = frontend::Alert::prompt( - _("Wrap search?"), - _("End of document/scope reached while searching forward.\n" - "\n" - "Continue searching from beginning?"), - 0, 1, _("&Yes"), _("&No")); + while (cur && !match(cur, -1, false)) { + if (cur.pit() < cur.lastpit()) + cur.forwardPar(); + else { + cur.forwardPos(); } - cur.clear(); - cur.push_back(CursorSlice(match.p_buf->inset())); - } while (wrap_answer != 1); + } + for (; cur; cur.forwardPos()) { + if (match(cur)) + return findAdvFinalize(cur, match); + } return 0; } /// Find the most backward consecutive match within same paragraph while searching backwards. -void findMostBackwards(DocIterator & cur, MatchStringAdv const & match, int & len) { +void findMostBackwards(DocIterator & cur, MatchStringAdv const & match, int & len) +{ DocIterator cur_begin = doc_iterator_begin(cur.buffer()); - len = findAdvFinalize(cur, match); - if (cur != cur_begin) { - Inset & inset = cur.inset(); - int old_len; - DocIterator old_cur; - DocIterator dit2; - do { - old_cur = cur; - old_len = len; - cur.backwardPos(); - LYXERR(Debug::FIND, "findMostBackwards(): old_cur=" - << old_cur << ", old_len=" << len << ", cur=" << cur); - dit2 = cur; - } while (cur != cur_begin && &cur.inset() == &inset && match(cur) - && (len = findAdvFinalize(dit2, match)) > old_len); - cur = old_cur; - len = old_len; + DocIterator tmp_cur = cur; + len = findAdvFinalize(tmp_cur, match); + Inset & inset = cur.inset(); + for (; cur != cur_begin; cur.backwardPos()) { + LYXERR(Debug::FIND, "findMostBackwards(): cur=" << cur); + DocIterator new_cur = cur; + new_cur.backwardPos(); + if (new_cur == cur || &new_cur.inset() != &inset || !match(new_cur)) + break; + int new_len = findAdvFinalize(new_cur, match); + if (new_len == len) + break; + len = new_len; } - LYXERR(Debug::FIND, "findMostBackwards(): cur=" << cur); + LYXERR(Debug::FIND, "findMostBackwards(): exiting with cur=" << cur); } + /// Finds backwards int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { if (! cur) return 0; - // Backup of original position (for restoring it in case match not found) - DocIterator cur_orig(cur); - // Position beyond which match is not considered - // (set to end of document after wrap-around question) - DocIterator cur_orig2(cur); + // Backup of original position DocIterator cur_begin = doc_iterator_begin(cur.buffer()); -/* if (match(cur_orig)) */ -/* findAdvFinalize(cur_orig, match); */ - int wrap_answer = 0; + if (cur == cur_begin) + return 0; + cur.backwardPos(); + DocIterator cur_orig(cur); bool found_match; + bool pit_changed = false; + found_match = false; do { - bool pit_changed = false; - found_match = false; - // Search in current par occurs from start to end, - // but in next loop match is discarded if pos > original pos cur.pos() = 0; found_match = match(cur, -1, false); - LYXERR(Debug::FIND, "findBackAdv0: found_match=" << found_match << ", cur: " << cur); - while (cur != cur_begin) { - if (found_match) - break; - if (cur.pit() > 0) - --cur.pit(); - else - cur.backwardPos(); - pit_changed = true; - // Search in previous pars occurs from start to end - cur.pos() = 0; - found_match = match(cur, -1, false); - LYXERR(Debug::FIND, "findBackAdv1: found_match=" - << found_match << ", cur: " << cur); - } - if (pit_changed) - cur.pos() = cur.lastpos(); - else - cur.pos() = cur_orig2.pos(); - LYXERR(Debug::FIND, "findBackAdv2: cur: " << cur); - DocIterator cur_prev_iter; + if (found_match) { - while (true) { - found_match=match(cur); + if (pit_changed) + cur.pos() = cur.lastpos(); + else + cur.pos() = cur_orig.pos(); + LYXERR(Debug::FIND, "findBackAdv2: cur: " << cur); + DocIterator cur_prev_iter; + do { + found_match = match(cur); LYXERR(Debug::FIND, "findBackAdv3: found_match=" - << found_match << ", cur: " << cur); + << found_match << ", cur: " << cur); if (found_match) { int len; findMostBackwards(cur, match, len); - if (&cur.inset() != &cur_orig2.inset() - || !(cur.pit() == cur_orig2.pit()) - || cur.pos() < cur_orig2.pos()) - return len; + return len; } - // Prevent infinite loop at begin of document - if (cur == cur_begin || cur == cur_prev_iter) + // Stop if begin of document reached + if (cur == cur_begin) break; cur_prev_iter = cur; cur.backwardPos(); - }; - } - // No match has been found in current buffer - bool prompt = false; - if (match.opt.scope == FindAndReplaceOptions::S_BUFFER) { - prompt = true; - } else if (match.opt.scope == FindAndReplaceOptions::S_DOCUMENT) { - prompt = prev_document_buffer(match.p_buf); - } else if (match.opt.scope == FindAndReplaceOptions::S_OPEN_BUFFERS) { - prompt = prev_open_buffer(match.p_buf); - } else { - /* Unimplemented scope */ - LASSERT(false, /**/); + } while (true); } - if (prompt) { - wrap_answer = frontend::Alert::prompt( - _("Wrap search?"), - _("Beginning of document/scope reached while searching backwards\n" - "\n" - "Continue searching from end?"), - 0, 1, _("&Yes"), _("&No")); - } - cur = doc_iterator_end(match.p_buf); - cur.backwardPos(); - LYXERR(Debug::FIND, "findBackAdv5: cur: " << cur); - cur_orig2 = cur; - } while (wrap_answer == 0); - cur = cur_orig; + if (cur == cur_begin) + break; + if (cur.pit() > 0) + --cur.pit(); + else + cur.backwardPos(); + pit_changed = true; + } while (true); return 0; } @@ -1282,23 +1133,91 @@ static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase other } +/// +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); +} + + /// Perform a FindAdv operation. bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) { - DocIterator cur = bv->cursor(); - int match_len = 0; + DocIterator cur; + int match_len; if (opt.search.empty()) { - bv->message(_("Search text is empty!")); - return false; + bv->message(_("Search text is empty!")); + return false; } -// if (! bv->buffer()) { -// bv->message(_("No open document !")); -// return false; -// } - MatchStringAdv matchAdv(bv->buffer(), opt); try { + MatchStringAdv matchAdv(bv->buffer(), opt); + findAdvReplace(bv, opt, matchAdv); + cur = bv->cursor(); if (opt.forward) match_len = findForwardAdv(cur, matchAdv); else @@ -1314,80 +1233,16 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) return false; } - LYXERR(Debug::FIND, "Putting selection at buf=" << matchAdv.p_buf - << "cur=" << cur << " with len: " << match_len); - - theApp()->currentWindow()->selectDocumentBuffer(matchAdv.p_buf); - bv = theApp()->currentWindow()->documentBufferView(); + bv->message(_("Match found!")); - bv->putSelectionAt(cur, match_len, ! opt.forward); - if (opt.replace == docstring(from_utf8(LYX_FR_NULL_STRING))) { - bv->message(_("Match found !")); - } else { - 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); - if (repl_buffer.readString(lyx)) { - if (opt.keep_case && match_len >= 2) { - if (cur.inTexted()) { - if (firstUppercase(cur)) - changeFirstCase(repl_buffer, text_uppercase, text_lowercase); - else if (allNonLowercase(cur, match_len)) - changeFirstCase(repl_buffer, text_uppercase, text_uppercase); - } - } - cap::cutSelection(bv->cursor(), false, false); - if (! cur.inMathed()) { - LYXERR(Debug::FIND, "Replacing by pasteParagraphList()ing repl_buffer"); - cap::pasteParagraphList(bv->cursor(), 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 << "'"); - bv->cursor().niceInsert(repl_latex); - } - bv->putSelectionAt(cur, repl_buffer.paragraphs().begin()->size(), ! opt.forward); - bv->message(_("Match found and replaced !")); - } else - LASSERT(false, /**/); - // dispatch(FuncRequest(LFUN_SELF_INSERT, opt.replace)); - } + LYXERR(Debug::FIND, "Putting selection at cur=" << cur << " with len: " << match_len); + bv->putSelectionAt(cur, match_len, !opt.forward); return true; } -void findAdv(BufferView * bv, FuncRequest const & ev) -{ - if (!bv || ev.action != LFUN_WORD_FINDADV) - return; - - FindAndReplaceOptions opt; - istringstream iss(to_utf8(ev.argument())); - iss >> opt; - findAdv(bv, opt); -} - - -ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const & opt) +ostringstream & operator<<(ostringstream & os, FindAndReplaceOptions const & opt) { os << to_utf8(opt.search) << "\nEOSS\n" << opt.casesensitive << ' ' @@ -1405,7 +1260,7 @@ ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const return os; } -istringstream & operator>>(istringstream & is, lyx::FindAndReplaceOptions & opt) +istringstream & operator>>(istringstream & is, FindAndReplaceOptions & opt) { LYXERR(Debug::FIND, "parsing"); string s;