X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=bb53c35854739da4d9138dd7785bcdb38430b352;hb=9337d73f1f9a6d4dae2e239e9f679a7452660c40;hp=f8001349279ebc76bd28c6f6803a1af4dfb31a00;hpb=f630be890494c849981e4fb52ea4740506e92bed;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index f800134927..bb53c35854 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -16,31 +16,29 @@ #include "lyxfind.h" #include "Buffer.h" -#include "LCursor.h" +#include "BufferParams.h" +#include "Cursor.h" #include "CutAndPaste.h" #include "buffer_funcs.h" #include "BufferView.h" -#include "debug.h" +#include "Changes.h" #include "FuncRequest.h" -#include "gettext.h" -#include "LyXText.h" +#include "Text.h" #include "Paragraph.h" #include "ParIterator.h" -#include "Undo.h" -#include "frontends/Alert.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" -namespace lyx { - -using support::compare_no_case; -using support::uppercase; -using support::split; - -using std::advance; +using namespace std; +using namespace lyx::support; +namespace lyx { namespace { @@ -54,7 +52,7 @@ bool parse_bool(docstring & howto) } -class MatchString : public std::binary_function +class MatchString : public binary_function { public: MatchString(docstring const & str, bool cs, bool mw) @@ -62,33 +60,10 @@ public: {} // returns true if the specified string is at the specified position - bool operator()(Paragraph const & par, pos_type pos) const + // del specifies whether deleted strings in ct mode will be considered + bool operator()(Paragraph const & par, pos_type pos, bool del = true) const { - docstring::size_type const size = str.length(); - pos_type i = 0; - pos_type const parsize = par.size(); - for (i = 0; pos + i < parsize; ++i) { - if (docstring::size_type(i) >= size) - break; - if (cs && str[i] != par.getChar(pos + i)) - break; - if (!cs && uppercase(str[i]) != uppercase(par.getChar(pos + i))) - break; - } - - if (size != docstring::size_type(i)) - return false; - - // if necessary, check whether string matches word - if (mw) { - if (pos > 0 && par.isLetter(pos - 1)) - return false; - if (pos + pos_type(size) < parsize - && par.isLetter(pos + size)) - return false; - } - - return true; + return par.find(str, cs, mw, pos, del); } private: @@ -101,20 +76,24 @@ private: }; -bool findForward(DocIterator & cur, MatchString const & match) +bool findForward(DocIterator & cur, MatchString const & match, + bool find_del = true) { for (; cur; cur.forwardChar()) - if (cur.inTexted() && match(cur.paragraph(), cur.pos())) + if (cur.inTexted() && + match(cur.paragraph(), cur.pos(), find_del)) return true; return false; } -bool findBackwards(DocIterator & cur, MatchString const & match) +bool findBackwards(DocIterator & cur, MatchString const & match, + bool find_del = true) { while (cur) { cur.backwardChar(); - if (cur.inTexted() && match(cur.paragraph(), cur.pos())) + if (cur.inTexted() && + match(cur.paragraph(), cur.pos(), find_del)) return true; } return false; @@ -130,18 +109,18 @@ bool findChange(DocIterator & cur) } -bool searchAllowed(BufferView * bv, docstring const & str) +bool searchAllowed(BufferView * /*bv*/, docstring const & str) { if (str.empty()) { - frontend::Alert::error(_("Search error"), - _("Search string is empty")); + frontend::Alert::error(_("Search error"), _("Search string is empty")); return false; } - return bv->buffer(); + return true; } -bool find(BufferView * bv, docstring const & searchstr, bool cs, bool mw, bool fw) +bool find(BufferView * bv, docstring const & searchstr, + bool cs, bool mw, bool fw, bool find_del = true) { if (!searchAllowed(bv, searchstr)) return false; @@ -150,7 +129,8 @@ bool find(BufferView * bv, docstring const & searchstr, bool cs, bool mw, bool f MatchString const match(searchstr, cs, mw); - bool found = fw ? findForward(cur, match) : findBackwards(cur, match); + bool found = fw ? findForward(cur, match, find_del) : + findBackwards(cur, match, find_del); if (found) bv->putSelectionAt(cur, searchstr.length(), !fw); @@ -163,12 +143,12 @@ int replaceAll(BufferView * bv, docstring const & searchstr, docstring const & replacestr, bool cs, bool mw) { - Buffer & buf = *bv->buffer(); + Buffer & buf = bv->buffer(); if (!searchAllowed(bv, searchstr) || buf.isReadonly()) return 0; - recordUndoFullDocument(bv); + bv->cursor().recordUndoFullDocument(); MatchString const match(searchstr, cs, mw); int num = 0; @@ -177,15 +157,15 @@ int replaceAll(BufferView * bv, int const ssize = searchstr.size(); DocIterator cur = doc_iterator_begin(buf.inset()); - while (findForward(cur, match)) { + while (findForward(cur, match, false)) { pos_type pos = cur.pos(); - LyXFont const font + Font const font = cur.paragraph().getFontSettings(buf.params(), pos); int striked = ssize - cur.paragraph().eraseChars(pos, pos + ssize, buf.params().trackChanges); cur.paragraph().insert(pos, replacestr, font, - Change(buf.params().trackChanges ? - Change::INSERTED : Change::UNCHANGED)); + Change(buf.params().trackChanges ? + Change::INSERTED : Change::UNCHANGED)); for (int i = 0; i < rsize + striked; ++i) cur.forwardChar(); ++num; @@ -218,17 +198,18 @@ bool stringSelected(BufferView * bv, docstring const & searchstr, int replace(BufferView * bv, docstring const & searchstr, docstring const & replacestr, bool cs, bool mw, bool fw) { - if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) + if (!searchAllowed(bv, searchstr) || bv->buffer().isReadonly()) return 0; if (!stringSelected(bv, searchstr, cs, mw, fw)) return 0; - LCursor & cur = bv->cursor(); + Cursor & cur = bv->cursor(); cap::replaceSelectionWithString(cur, replacestr, fw); - bv->buffer()->markDirty(); - find(bv, searchstr, cs, mw, fw); - bv->update(); + bv->buffer().markDirty(); + find(bv, searchstr, cs, mw, fw, false); + bv->buffer().updateMacros(); + bv->processUpdateFlags(Update::Force | Update::FitCursor); return 1; } @@ -263,12 +244,12 @@ docstring const replace2string(docstring const & search, docstring const & repla } -void find(BufferView * bv, FuncRequest const & ev) +bool find(BufferView * bv, FuncRequest const & ev) { if (!bv || ev.action != LFUN_WORD_FIND) - return; + return false; - //lyxerr << "find called, cmd: " << ev << std::endl; + //lyxerr << "find called, cmd: " << ev << endl; // data is of the form // " @@ -280,16 +261,11 @@ void find(BufferView * bv, FuncRequest const & ev) bool matchword = parse_bool(howto); bool forward = parse_bool(howto); - bool const found = find(bv, search, - casesensitive, matchword, forward); - - if (!found) - // emit message signal. - bv->message(_("String not found!")); + return find(bv, search, casesensitive, matchword, forward); } -void replace(BufferView * bv, FuncRequest const & ev) +void replace(BufferView * bv, FuncRequest const & ev, bool has_deleted) { if (!bv || ev.action != LFUN_WORD_REPLACE) return; @@ -308,34 +284,39 @@ void replace(BufferView * bv, FuncRequest const & ev) bool all = parse_bool(howto); bool forward = parse_bool(howto); - Buffer * buf = bv->buffer(); - - int const replace_count = all - ? replaceAll(bv, search, rplc, casesensitive, matchword) - : replace(bv, search, rplc, casesensitive, matchword, forward); - - if (replace_count == 0) { - // emit message signal. - buf->message(_("String not found!")); - } else { - if (replace_count == 1) { + if (!has_deleted) { + int const replace_count = all + ? replaceAll(bv, search, rplc, casesensitive, matchword) + : replace(bv, search, rplc, casesensitive, matchword, forward); + + Buffer & buf = bv->buffer(); + if (replace_count == 0) { // emit message signal. - buf->message(_("String has been replaced.")); + buf.message(_("String not found!")); } else { - docstring str = convert(replace_count); - str += _(" strings have been replaced."); - // emit message signal. - buf->message(str); + if (replace_count == 1) { + // emit message signal. + buf.message(_("String has been replaced.")); + } else { + docstring str = convert(replace_count); + str += _(" strings have been replaced."); + // emit message signal. + buf.message(str); + } } + } else { + // if we have deleted characters, we do not replace at all, but + // rather search for the next occurence + if (find(bv, search, casesensitive, matchword, forward)) + bv->showCursor(); + else + bv->message(_("String not found!")); } } bool findNextChange(BufferView * bv) { - if (!bv->buffer()) - return false; - DocIterator cur = bv->cursor(); if (!findChange(cur)) @@ -346,21 +327,16 @@ bool findNextChange(BufferView * bv) Change orig_change = cur.paragraph().lookupChange(cur.pos()); - DocIterator et = doc_iterator_end(cur.inset()); - DocIterator ok = cur; // see below - for (; cur != et; cur.forwardPosNoDescend()) { - ok = cur; - Change change = cur.paragraph().lookupChange(cur.pos()); - if (change != orig_change) { + CursorSlice & tip = cur.top(); + for (; !tip.at_end(); tip.forwardPos()) { + Change change = tip.paragraph().lookupChange(tip.pos()); + if (change != orig_change) break; - } } - // avoid crash (assertion violation) if the imaginary end-of-par - // character of the last paragraph of the document is marked as changed - if (cur == et) { - cur = ok; - } + // character of the last paragraph of the document is marked as changed + if (tip.at_end()) + tip.backwardPos(); // Now put cursor to end of selection: bv->cursor().setCursor(cur);