X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.C;h=2f16fd3d6ce1dd27ef31f39009a68675d4d4bdf7;hb=37d42d45f3f4a5d3e916a080af50b37ae4a9d118;hp=a4fe14d017300febb54202fcdcedbb8632629551;hpb=2a5bc90633d0bb63e5cabd43837b0de78cbd8895;p=lyx.git diff --git a/src/lyxfind.C b/src/lyxfind.C index a4fe14d017..2f16fd3d6c 100644 --- a/src/lyxfind.C +++ b/src/lyxfind.C @@ -17,28 +17,30 @@ #include "buffer.h" #include "cursor.h" +#include "CutAndPaste.h" #include "BufferView.h" #include "debug.h" -#include "iterators.h" #include "funcrequest.h" #include "gettext.h" #include "lyxtext.h" #include "paragraph.h" -#include "PosIterator.h" +#include "pariterator.h" #include "undo.h" #include "frontends/Alert.h" #include "frontends/LyXView.h" -#include "support/textutils.h" -#include "support/tostr.h" +#include "support/convert.h" -#include "support/std_sstream.h" +#include using lyx::support::lowercase; using lyx::support::uppercase; using lyx::support::split; +using lyx::pit_type; +using lyx::pos_type; + using std::advance; using std::ostringstream; using std::string; @@ -56,160 +58,6 @@ bool parse_bool(string & howto) } -bool find(BufferView * bv, - string const & searchstr, bool cs, bool mw, bool fw); - - -int replace(BufferView * bv, - string const & searchstr, string const & replacestr, - bool cs, bool mw, bool fw); - - -int replaceAll(BufferView * bv, - string const & searchstr, string const & replacestr, - bool cs, bool mw); - - -bool findChange(PosIterator & cur, PosIterator const & end); - -} // namespace anon - - -namespace lyx { -namespace find { - -string const find2string(string const & search, - bool casesensitive, bool matchword, bool forward) -{ - ostringstream ss; - ss << search << '\n' - << int(casesensitive) << ' ' - << int(matchword) << ' ' - << int(forward); - - return ss.str(); -} - - -string const replace2string(string const & search, string const & replace, - bool casesensitive, bool matchword, - bool all, bool forward) -{ - ostringstream ss; - ss << search << '\n' - << replace << '\n' - << int(casesensitive) << ' ' - << int(matchword) << ' ' - << int(all) << ' ' - << int(forward); - - return ss.str(); -} - - -void find(BufferView * bv, FuncRequest const & ev) -{ - if (!bv || ev.action != LFUN_WORD_FIND) - return; - - // data is of the form - // " - // " - string search; - string howto = split(ev.argument, search, '\n'); - - bool casesensitive = parse_bool(howto); - bool matchword = parse_bool(howto); - bool forward = parse_bool(howto); - - bool const found = ::find(bv, search, - casesensitive, matchword, forward); - - if (!found) - bv->owner()->message(_("String not found!")); -} - - -void replace(BufferView * bv, FuncRequest const & ev) -{ - if (!bv || ev.action != LFUN_WORD_REPLACE) - return; - - // data is of the form - // " - // - // " - string search; - string replace; - string howto = split(ev.argument, search, '\n'); - howto = split(howto, replace, '\n'); - - bool casesensitive = parse_bool(howto); - bool matchword = parse_bool(howto); - bool all = parse_bool(howto); - bool forward = parse_bool(howto); - - LyXView * lv = bv->owner(); - - int const replace_count = all ? - ::replaceAll(bv, search, replace, - casesensitive, matchword) : - ::replace(bv, search, replace, - casesensitive, matchword, forward); - - if (replace_count == 0) { - lv->message(_("String not found!")); - } else { - if (replace_count == 1) { - lv->message(_("String has been replaced.")); - } else { - string str = tostr(replace_count); - str += _(" strings have been replaced."); - lv->message(str); - } - } -} - - -bool findNextChange(BufferView * bv) -{ - if (!bv->available()) - return false; - - PosIterator cur = PosIterator(*bv); - PosIterator const endit = bv->buffer()->pos_iterator_end(); - - if (!findChange(cur, endit)) - return false; - - ParagraphList::iterator pit = cur.pit(); - pos_type pos = cur.pos(); - - Change orig_change = pit->lookupChangeFull(pos); - pos_type parsize = pit->size(); - pos_type end = pos; - - for (; end != parsize; ++end) { - Change change = pit->lookupChangeFull(end); - if (change != orig_change) { - // slight UI optimisation: for replacements, we get - // text like : _old_new. Consider that as one change. - if (!(orig_change.type == Change::DELETED && - change.type == Change::INSERTED)) - break; - } - } - pos_type length = end - pos; - bv->putSelectionAt(cur, length, true); - return true; -} - -} // find namespace -} // lyx namespace - - -namespace { - class MatchString : public std::binary_function { public: @@ -226,7 +74,7 @@ public: for (i = 0; pos + i < parsize; ++i) { if (string::size_type(i) >= size) break; - if (cs && str[i] != par.getChar(pos + i)) + if (cs && str[i] != par.getChar(pos + i)) break; if (!cs && uppercase(str[i]) != uppercase(par.getChar(pos + i))) break; @@ -237,10 +85,10 @@ public: // if necessary, check whether string matches word if (mw) { - if (pos > 0 && IsLetterCharOrDigit(par.getChar(pos - 1))) + if (pos > 0 && par.isLetter(pos - 1)) return false; if (pos + lyx::pos_type(size) < parsize - && IsLetterCharOrDigit(par.getChar(pos + size))); + && par.isLetter(pos + size)) return false; } @@ -257,36 +105,33 @@ private: }; -bool findForward(PosIterator & cur, PosIterator const & end, - MatchString const & match) +bool findForward(DocIterator & cur, MatchString const & match) { - for (; cur != end; ++cur) { - if (match(*cur.pit(), cur.pos())) + for (; cur; cur.forwardChar()) + if (cur.inTexted() && match(cur.paragraph(), cur.pos())) return true; - } return false; } -bool findBackwards(PosIterator & cur, PosIterator const & beg, - MatchString const & match) +bool findBackwards(DocIterator & cur, MatchString const & match) { - while (beg != cur) { - --cur; - if (match(*cur.pit(), cur.pos())) + while (cur) { + cur.backwardChar(); + if (cur.inTexted() && match(cur.paragraph(), cur.pos())) return true; } return false; } -bool findChange(PosIterator & cur, PosIterator const & end) +bool findChange(DocIterator & cur) { - for (; cur != end; ++cur) { - if ((cur.pit()->empty() || !cur.at_end()) - && cur.pit()->lookupChange(cur.pos()) != Change::UNCHANGED) + for (; cur; cur.forwardChar()) + if (cur.inTexted() && cur.pos() != cur.paragraph().size() && + cur.paragraph().lookupChange(cur.pos()) + != Change::UNCHANGED) return true; - } return false; } @@ -306,15 +151,11 @@ bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw) if (!searchAllowed(bv, searchstr)) return false; - PosIterator cur = PosIterator(*bv); + DocIterator cur = bv->cursor(); MatchString const match(searchstr, cs, mw); - PosIterator const end = bv->buffer()->pos_iterator_end(); - PosIterator const beg = bv->buffer()->pos_iterator_begin(); - - bool found = fw ? findForward(cur, end, match) - : findBackwards(cur, beg, match); + bool found = fw ? findForward(cur, match) : findBackwards(cur, match); if (found) bv->putSelectionAt(cur, searchstr.length(), !fw); @@ -332,29 +173,28 @@ int replaceAll(BufferView * bv, if (!searchAllowed(bv, searchstr) || buf.isReadonly()) return 0; - recordUndoFullDocument(bv->cursor()); + recordUndoFullDocument(bv); - PosIterator cur = buf.pos_iterator_begin(); - PosIterator const end = buf.pos_iterator_end(); MatchString const match(searchstr, cs, mw); int num = 0; int const rsize = replacestr.size(); int const ssize = searchstr.size(); - while (findForward(cur, end, match)) { + DocIterator cur = doc_iterator_begin(buf.inset()); + while (findForward(cur, match)) { lyx::pos_type pos = cur.pos(); LyXFont const font - = cur.pit()->getFontSettings(buf.params(), pos); - int striked = ssize - cur.pit()->erase(pos, pos + ssize); - cur.pit()->insert(pos, replacestr, font); - advance(cur, rsize + striked); + = cur.paragraph().getFontSettings(buf.params(), pos); + int striked = ssize - cur.paragraph().erase(pos, pos + ssize); + cur.paragraph().insert(pos, replacestr, font); + for (int i = 0; i < rsize + striked; ++i) + cur.forwardChar(); ++num; } - PosIterator beg = buf.pos_iterator_begin(); bv->text()->init(bv); - bv->putSelectionAt(beg, 0, false); + bv->putSelectionAt(doc_iterator_begin(buf.inset()), 0, false); if (num) buf.markDirty(); return num; @@ -378,7 +218,7 @@ bool stringSelected(BufferView * bv, string const & searchstr, int replace(BufferView * bv, string const & searchstr, - string const & replacestr, bool cs, bool mw, bool fw) + string const & replacestr, bool cs, bool mw, bool fw) { if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) return 0; @@ -386,11 +226,10 @@ int replace(BufferView * bv, string const & searchstr, if (!stringSelected(bv, searchstr, cs, mw, fw)) return 0; - LyXText * text = bv->getLyXText(); - - text->replaceSelectionWithString(replacestr); - text->setSelectionRange(replacestr.length()); - bv->cursor().current() = fw ? bv->cursor().selEnd() : bv->cursor().selBegin(); + LCursor & cur = bv->cursor(); + lyx::cap::replaceSelectionWithString(cur, replacestr); + lyx::cap::setSelectionRange(cur, replacestr.length()); + cur.top() = fw ? cur.selEnd() : cur.selBegin(); bv->buffer()->markDirty(); find(bv, searchstr, cs, mw, fw); bv->update(); @@ -398,4 +237,138 @@ int replace(BufferView * bv, string const & searchstr, return 1; } -} //namespace anon +} // namespace anon + + +namespace lyx { +namespace find { + +string const find2string(string const & search, + bool casesensitive, bool matchword, bool forward) +{ + ostringstream ss; + ss << search << '\n' + << int(casesensitive) << ' ' + << int(matchword) << ' ' + << int(forward); + return ss.str(); +} + + +string const replace2string(string const & search, string const & replace, + bool casesensitive, bool matchword, + bool all, bool forward) +{ + ostringstream ss; + ss << search << '\n' + << replace << '\n' + << int(casesensitive) << ' ' + << int(matchword) << ' ' + << int(all) << ' ' + << int(forward); + return ss.str(); +} + + +void find(BufferView * bv, FuncRequest const & ev) +{ + if (!bv || ev.action != LFUN_WORD_FIND) + return; + + lyxerr << "find called, cmd: " << ev << std::endl; + + // data is of the form + // " + // " + string search; + string howto = split(ev.argument, search, '\n'); + + bool casesensitive = parse_bool(howto); + bool matchword = parse_bool(howto); + bool forward = parse_bool(howto); + + bool const found = ::find(bv, search, + casesensitive, matchword, forward); + + if (!found) + bv->owner()->message(_("String not found!")); +} + + +void replace(BufferView * bv, FuncRequest const & ev) +{ + if (!bv || ev.action != LFUN_WORD_REPLACE) + return; + + // data is of the form + // " + // + // " + string search; + string replace; + string howto = split(ev.argument, search, '\n'); + howto = split(howto, replace, '\n'); + + bool casesensitive = parse_bool(howto); + bool matchword = parse_bool(howto); + bool all = parse_bool(howto); + bool forward = parse_bool(howto); + + LyXView * lv = bv->owner(); + + int const replace_count = all + ? ::replaceAll(bv, search, replace, casesensitive, matchword) + : ::replace(bv, search, replace, casesensitive, matchword, forward); + + if (replace_count == 0) { + lv->message(_("String not found!")); + } else { + if (replace_count == 1) { + lv->message(_("String has been replaced.")); + } else { + string str = convert(replace_count); + str += _(" strings have been replaced."); + lv->message(str); + } + } +} + + +bool findNextChange(BufferView * bv) +{ + if (!bv->available()) + return false; + + DocIterator cur = bv->cursor(); + + if (!findChange(cur)) + return false; + + Paragraph const & par = cur.paragraph(); + const pos_type pos = cur.pos(); + + Change orig_change = par.lookupChangeFull(pos); + const pos_type parsize = par.size(); + pos_type end = pos; + + for (; end != parsize; ++end) { + Change change = par.lookupChangeFull(end); + if (change != orig_change) { + // slight UI optimisation: for replacements, we get + // text like : _old_new. Consider that as one change. + if (!(orig_change.type == Change::DELETED && + change.type == Change::INSERTED)) + break; + } + } + pos_type length = end - pos; + bv->putSelectionAt(cur, length, false); + // if we used a lfun like in find/replace, dispatch would do + // that for us + bv->update(); + + return true; +} + +} // find namespace +} // lyx namespace