X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=bf99caf33f536244fb1315d73eeea7b95a7c8eeb;hb=2098f1d8c20d51e63e670bcdc9da8996068975bf;hp=2ddd6da2c523e6a64a50c927012c95c79fc05633;hpb=378d32bc06bbbc7d982f1183fe4f378912644d7e;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index 2ddd6da2c5..bf99caf33f 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -17,6 +17,7 @@ #include "lyxfind.h" #include "Buffer.h" +#include "BufferList.h" #include "buffer_funcs.h" #include "BufferParams.h" #include "BufferView.h" @@ -47,6 +48,9 @@ #include "support/lstrings.h" #include "support/lassert.h" +#include "frontends/Application.h" +#include "frontends/LyXView.h" + #include #include @@ -373,11 +377,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; } @@ -601,7 +612,7 @@ bool braces_match(string::const_iterator const & beg, **/ class MatchStringAdv { public: - MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt); + MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & opt); /** Tests if text starting at the supplied position matches with the one provided to the MatchStringAdv ** constructor as opt.search, under the opt.* options settings. @@ -617,7 +628,9 @@ public: public: /// buffer - lyx::Buffer const & buf; + lyx::Buffer * p_buf; + /// first buffer on which search was started + lyx::Buffer * const p_first_buf; /// options FindAndReplaceOptions const & opt; @@ -650,8 +663,8 @@ private: }; -MatchStringAdv::MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt) - : buf(buf), opt(opt) +MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & opt) + : p_buf(&buf), p_first_buf(&buf), opt(opt) { par_as_string = normalize(opt.search); open_braces = 0; @@ -889,6 +902,7 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) return ods.str(); } + /** Finalize an advanced find operation, advancing the cursor to the innermost ** position that matches, plus computing the length of the matching text to ** be selected @@ -930,39 +944,28 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match) /// Finds forward -int findForwardAdv(DocIterator & cur, MatchStringAdv const & match) +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(); - } + 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); - } - if (wrap_answer != -1) - break; - wrap_answer = frontend::Alert::prompt( - _("Wrap search?"), - _("End of document reached while searching forward.\n" - "\n" - "Continue searching from beginning?"), - 0, 1, _("&Yes"), _("&No")); - cur.clear(); - cur.push_back(CursorSlice(match.buf.inset())); - } while (wrap_answer == 0); + } + 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) { @@ -985,74 +988,59 @@ void findMostBackwards(DocIterator & cur, MatchStringAdv const & match, int & le LYXERR(Debug::FIND, "findMostBackwards(): cur=" << cur); } + /// Finds backwards -int findBackwardsAdv(DocIterator & cur, MatchStringAdv const & match) { +int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { if (! cur) return 0; + // Backup of original position DocIterator cur_orig(cur); 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; 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_orig.pos(); - LYXERR(Debug::FIND, "findBackAdv2: cur: " << cur); + if (found_match) { + if (pit_changed) + cur.pos() = cur.lastpos(); + else + cur.pos() = cur_orig.pos(); + LYXERR(Debug::FIND, "findBackAdv2: cur: " << cur); + DocIterator cur_prev_iter; while (true) { - found_match=match(cur); + 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_orig.inset() - || !(cur.pit()==cur_orig.pit()) - || cur.pos() < cur_orig.pos()) + if (cur < cur_orig) return len; } - if (cur == cur_begin) + // Prevent infinite loop at begin of document + if (cur == cur_begin || cur == cur_prev_iter) break; + cur_prev_iter = cur; cur.backwardPos(); - }; + } } - wrap_answer = frontend::Alert::prompt( - _("Wrap search?"), - _("Beginning of document reached while searching backwards\n" - "\n" - "Continue searching from end?"), - 0, 1, _("&Yes"), _("&No")); - cur = doc_iterator_end(&match.buf); - cur.backwardPos(); - } 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; } + } // anonym namespace @@ -1068,10 +1056,11 @@ docstring stringifyFromForSearch(FindAndReplaceOptions const & opt, FindAndReplaceOptions::FindAndReplaceOptions(docstring const & search, bool casesensitive, bool matchword, bool forward, bool expandmacros, bool ignoreformat, - bool regexp, docstring const & replace, bool keep_case) + bool regexp, docstring const & replace, bool keep_case, + SearchScope scope) : search(search), casesensitive(casesensitive), matchword(matchword), forward(forward), expandmacros(expandmacros), ignoreformat(ignoreformat), - regexp(regexp), replace(replace), keep_case(keep_case) + regexp(regexp), replace(replace), keep_case(keep_case), scope(scope) { } @@ -1139,13 +1128,9 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) 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 const matchAdv(bv->buffer(), opt); if (opt.forward) match_len = findForwardAdv(cur, matchAdv); else @@ -1161,10 +1146,12 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) return false; } - LYXERR(Debug::FIND, "Putting selection at " << cur << " with len: " << match_len); + LYXERR(Debug::FIND, "Putting selection at buf=" << matchAdv.p_buf + << "cur=" << cur << " with len: " << match_len); + bv->putSelectionAt(cur, match_len, ! opt.forward); if (opt.replace == docstring(from_utf8(LYX_FR_NULL_STRING))) { - bv->message(_("Match found !")); + bv->message(_("Match found!")); } else { string lyx = to_utf8(opt.replace); // FIXME: Seems so stupid to me to rebuild a buffer here, @@ -1210,25 +1197,12 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) bv->message(_("Match found and replaced !")); } else LASSERT(false, /**/); - // dispatch(FuncRequest(LFUN_SELF_INSERT, opt.replace)); } 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) { os << to_utf8(opt.search) << "\nEOSS\n" @@ -1239,7 +1213,8 @@ ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const << opt.ignoreformat << ' ' << opt.regexp << ' ' << to_utf8(opt.replace) << "\nEOSS\n" - << opt.keep_case; + << opt.keep_case << ' ' + << int(opt.scope); LYXERR(Debug::FIND, "built: " << os.str()); @@ -1275,6 +1250,9 @@ istringstream & operator>>(istringstream & is, lyx::FindAndReplaceOptions & opt) getline(is, line); } is >> opt.keep_case; + int i; + is >> i; + opt.scope = FindAndReplaceOptions::SearchScope(i); LYXERR(Debug::FIND, "parsed: " << opt.casesensitive << ' ' << opt.matchword << ' ' << opt.forward << ' ' << opt.expandmacros << ' ' << opt.ignoreformat << ' ' << opt.regexp << ' ' << opt.keep_case); LYXERR(Debug::FIND, "replacing with: '" << s << "'");