From 32a716152e3e19d0afe039fe7220e982619348cf Mon Sep 17 00:00:00 2001 From: Alfredo Braunstein Date: Tue, 4 Nov 2003 12:01:15 +0000 Subject: [PATCH] the spellcheck cleanup git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8034 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView_pimpl.C | 2 - src/ChangeLog | 6 + src/frontends/controllers/ChangeLog | 6 + src/frontends/controllers/ControlSearch.C | 17 +- src/frontends/controllers/ControlSearch.h | 3 +- src/frontends/controllers/ControlThesaurus.C | 2 +- src/frontends/qt2/ChangeLog | 6 + src/frontends/qt2/QSearch.C | 5 +- src/frontends/qt2/QSearch.h | 5 +- src/frontends/qt2/QSearchDialog.C | 4 +- src/frontends/xforms/ChangeLog | 4 + src/frontends/xforms/FormSearch.C | 1 + src/insets/ChangeLog | 9 + src/insets/insetcollapsable.C | 36 -- src/insets/insetcollapsable.h | 8 - src/insets/insetert.C | 2 + src/insets/insettabular.C | 82 --- src/insets/insettabular.h | 8 - src/insets/insettext.C | 73 --- src/insets/insettext.h | 8 - src/insets/updatableinset.C | 26 - src/insets/updatableinset.h | 12 - src/lyxfind.C | 499 +++++++------------ src/lyxfind.h | 64 +-- src/lyxfunc.C | 3 +- src/paragraph.C | 9 + src/paragraph.h | 3 + 27 files changed, 289 insertions(+), 614 deletions(-) diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index dafede2235..93b49159fe 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -418,8 +418,6 @@ void BufferView::Pimpl::resizeCurrentBuffer() bv_->text->fullRebreak(); update(); } else { - lyxerr << "text not available!" << endl; - lyxerr << "no text in cache!" << endl; bv_->text = new LyXText(bv_, 0, false, bv_->buffer()->paragraphs()); bv_->text->init(bv_); } diff --git a/src/ChangeLog b/src/ChangeLog index e879aa8c1e..086b6668aa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2003-11-04 Alfredo Braunstein + + * lyxfind.[Ch]: complete overhaul + * BufferView_pimpl.C: + * lyxfunc.C: adjust + * paragraph.[Ch] (insert): add 2003-11-04 Alfredo Braunstein diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index 67e532930d..785887848e 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,9 @@ + +2003-11-04 Alfredo Braunstein + + * ControlSearch.[Ch]: + * ControlThesaurus.C: adjust to spellcheck code changes + 2003-11-04 Alfredo Braunstein * ControlSpellchecker.C (nextWord): do not send ligature breaks diff --git a/src/frontends/controllers/ControlSearch.C b/src/frontends/controllers/ControlSearch.C index 7b3fdbff6a..e1482ec28f 100644 --- a/src/frontends/controllers/ControlSearch.C +++ b/src/frontends/controllers/ControlSearch.C @@ -32,8 +32,8 @@ void ControlSearch::find(string const & search, bool casesensitive, bool matchword, bool forward) { bool const found = lyx::find::find(bufferview(), search, - forward, casesensitive, - matchword); + casesensitive, matchword, + forward); if (!found) lv_.message(_("String not found!")); @@ -41,16 +41,17 @@ void ControlSearch::find(string const & search, void ControlSearch::replace(string const & search, string const & replace, - bool casesensitive, bool matchword, bool all) + bool casesensitive, bool matchword, + bool forward, bool all) { // If not replacing all instances of the word, then do not // move on to the next instance once the present instance has been // changed - bool const once = !all; - int const replace_count = - lyx::find::replace(bufferview(), - search, replace, true, casesensitive, - matchword, all, once); + int const replace_count = all ? + lyx::find::replaceAll(bufferview(), search, replace, + casesensitive, matchword) + : lyx::find::replace(bufferview(), search, replace, + casesensitive, matchword, forward); if (replace_count == 0) { lv_.message(_("String not found!")); diff --git a/src/frontends/controllers/ControlSearch.h b/src/frontends/controllers/ControlSearch.h index 16855db05f..5c34643c4c 100644 --- a/src/frontends/controllers/ControlSearch.h +++ b/src/frontends/controllers/ControlSearch.h @@ -28,7 +28,8 @@ public: /// Replaces occurence of string void replace(std::string const & search, std::string const & replace, - bool casesensitive, bool matchword, bool all); + bool casesensitive, bool matchword, + bool forward, bool all); private: /// not needed. virtual void apply() {} diff --git a/src/frontends/controllers/ControlThesaurus.C b/src/frontends/controllers/ControlThesaurus.C index da3883f0fe..d6692583f4 100644 --- a/src/frontends/controllers/ControlThesaurus.C +++ b/src/frontends/controllers/ControlThesaurus.C @@ -48,7 +48,7 @@ void ControlThesaurus::replace(string const & newstr) */ int const replace_count = lyx::find::replace(kernel().bufferview(), oldstr_, newstr, - true, true, true, false, true); + true /*cs*/, true /*mw*/, true /*fw*/); oldstr_ = newstr; diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index 4c4686d177..94a01dc9b6 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,9 @@ + +2003-11-04 Alfredo Braunstein + + * QSearch.[Ch]: + * QSearchDialog.C: adjust to spellcheck code changes + 2003-11-01 Juergen Spitzmueller * ui/QParagraphDialogBase.ui: finally remove [line|pagebreak]_[above|below] diff --git a/src/frontends/qt2/QSearch.C b/src/frontends/qt2/QSearch.C index 6a705f4c7c..a74f29b0e2 100644 --- a/src/frontends/qt2/QSearch.C +++ b/src/frontends/qt2/QSearch.C @@ -54,7 +54,8 @@ void QSearch::find(string const & str, bool casesens, void QSearch::replace(string const & findstr, string const & replacestr, - bool casesens, bool words, bool all) + bool casesens, bool words, bool backwards, bool all) { - controller().replace(findstr, replacestr, casesens, words, all); + controller().replace(findstr, replacestr, casesens, words, + !backwards, all); } diff --git a/src/frontends/qt2/QSearch.h b/src/frontends/qt2/QSearch.h index 3da9d557ff..3c179dac9f 100644 --- a/src/frontends/qt2/QSearch.h +++ b/src/frontends/qt2/QSearch.h @@ -39,8 +39,9 @@ private: void find(std::string const & str, bool casesens, bool words, bool backwards); - void replace(std::string const & findstr, std::string const & replacestr, - bool casesens, bool words, bool all); + void replace(std::string const & findstr, + std::string const & replacestr, + bool casesens, bool words, bool backwards, bool all); }; #endif // QSEARCH_H diff --git a/src/frontends/qt2/QSearchDialog.C b/src/frontends/qt2/QSearchDialog.C index 7131e42bd4..113202d11a 100644 --- a/src/frontends/qt2/QSearchDialog.C +++ b/src/frontends/qt2/QSearchDialog.C @@ -94,7 +94,7 @@ void QSearchDialog::replaceClicked() form_->replace(find, replace, caseCB->isChecked(), wordsCB->isChecked(), - false); + backwardsCB->isChecked(), false); uniqueInsert(findCO, findCO->currentText()); uniqueInsert(replaceCO, replaceCO->currentText()); } @@ -106,7 +106,7 @@ void QSearchDialog::replaceallClicked() fromqstr(replaceCO->currentText()), caseCB->isChecked(), wordsCB->isChecked(), - true); + false, true); uniqueInsert(findCO, findCO->currentText()); uniqueInsert(replaceCO, replaceCO->currentText()); } diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index 007b4a9619..93dd6dc69d 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,4 +1,8 @@ +2003-11-04 Alfredo Braunstein + + * FormSearch.C: adjust to spellcheck changes + 2003-10-27 André Pönitz * FormParagraph.C: diff --git a/src/frontends/xforms/FormSearch.C b/src/frontends/xforms/FormSearch.C index 66037d7bc1..261d895cf6 100644 --- a/src/frontends/xforms/FormSearch.C +++ b/src/frontends/xforms/FormSearch.C @@ -85,6 +85,7 @@ ButtonPolicy::SMInput FormSearch::input(FL_OBJECT * ob, long) getString(dialog_->input_replace), fl_get_button(dialog_->check_casesensitive), fl_get_button(dialog_->check_matchword), + !fl_get_button(dialog_->check_searchbackwards), all); } diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index 907802f427..2a304e608c 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,4 +1,13 @@ +2003-11-04 Alfredo Braunstein + + * inset.h: + * insetcollapsable.[Ch]: + * insetert.[Ch]: + * insettabular.[Ch]: + * insettext.[Ch]: + * updatableinset.[Ch]: remove dead search code + 2003-11-04 Alfredo Braunstein * inset.h: diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index e3a889d80f..fa467dfeb4 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -527,42 +527,6 @@ void InsetCollapsable::markErased() } -bool InsetCollapsable::nextChange(BufferView * bv, lyx::pos_type & length) -{ - bool found = inset.nextChange(bv, length); - - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; -} - - -bool InsetCollapsable::searchForward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - bool found = inset.searchForward(bv, str, cs, mw); - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; -} - - -bool InsetCollapsable::searchBackward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - bool found = inset.searchBackward(bv, str, cs, mw); - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; -} - - void InsetCollapsable::addPreview(PreviewLoader & loader) const { inset.addPreview(loader); diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index 9a85975d83..de9f2229b1 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -133,14 +133,6 @@ public: void markErased(); - bool nextChange(BufferView * bv, lyx::pos_type & length); - - /// - bool searchForward(BufferView * bv, std::string const & str, - bool = true, bool = false); - bool searchBackward(BufferView * bv, std::string const & str, - bool = true, bool = false); - /// void addPreview(lyx::graphics::PreviewLoader &) const; diff --git a/src/insets/insetert.C b/src/insets/insetert.C index 0dfa14f46d..1621b2016c 100644 --- a/src/insets/insetert.C +++ b/src/insets/insetert.C @@ -445,6 +445,8 @@ InsetERT::priv_dispatch(FuncRequest const & cmd, break; result = inset.dispatch(cmd); } else { + // Is the following line correct? Ab + open(bv); result = InsetCollapsable::priv_dispatch(cmd, idx, pos); } set_latex_font(bv); diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 38f0eb8296..eb170b68bb 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -2425,88 +2425,6 @@ void InsetTabular::markErased() } -bool InsetTabular::nextChange(BufferView * bv, lyx::pos_type & length) -{ - if (the_locking_inset) { - if (the_locking_inset->nextChange(bv, length)) { - updateLocal(bv); - return true; - } - if (tabular.isLastCell(actcell)) - return false; - ++actcell; - } - InsetText & inset = tabular.getCellInset(actcell); - if (inset.nextChange(bv, length)) { - updateLocal(bv); - return true; - } - while (!tabular.isLastCell(actcell)) { - ++actcell; - InsetText & inset = tabular.getCellInset(actcell); - if (inset.nextChange(bv, length)) { - updateLocal(bv); - return true; - } - } - return false; -} - - -bool InsetTabular::searchForward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - int cell = 0; - if (the_locking_inset) { - if (the_locking_inset->searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - if (tabular.isLastCell(actcell)) - return false; - cell = actcell + 1; - } - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - while (!tabular.isLastCell(cell)) { - ++cell; - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - } - return false; -} - - -bool InsetTabular::searchBackward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - int cell = tabular.getNumberOfCells(); - if (the_locking_inset) { - if (the_locking_inset->searchBackward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - cell = actcell; - } - - while (cell) { - --cell; - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchBackward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - } - return false; -} - - bool InsetTabular::insetAllowed(InsetOld::Code code) const { if (the_locking_inset) diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index 145bd1ee64..0e012ba93c 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -169,14 +169,6 @@ public: /// void markErased(); - /// find next change - bool nextChange(BufferView *, lyx::pos_type & length); - /// - bool searchForward(BufferView *, std::string const &, - bool = true, bool = false); - bool searchBackward(BufferView *, std::string const &, - bool = true, bool = false); - // this should return true if we have a "normal" cell, otherwise true. // "normal" means without width set! bool forceDefaultParagraphs(InsetOld const * in) const; diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 150193edc1..e029e2cd49 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -1455,79 +1455,6 @@ LyXCursor const & InsetText::cursor(BufferView * bv) const } -bool InsetText::nextChange(BufferView * bv, lyx::pos_type & length) -{ - if (the_locking_inset) { - if (the_locking_inset->nextChange(bv, length)) - return true; - text_.cursorRight(true); - } - lyx::find::SearchResult result = - lyx::find::findNextChange(bv, &text_, length); - - if (result == lyx::find::SR_FOUND) { - LyXCursor cur = text_.cursor; - bv->unlockInset(bv->theLockingInset()); - if (bv->lockInset(this)) - locked = true; - text_.cursor = cur; - text_.setSelectionRange(length); - updateLocal(bv, false); - } - return result != lyx::find::SR_NOT_FOUND; -} - - -bool InsetText::searchForward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - if (the_locking_inset) { - if (the_locking_inset->searchForward(bv, str, cs, mw)) - return true; - text_.cursorRight(true); - } - lyx::find::SearchResult result = - lyx::find::find(bv, &text_, str, true, cs, mw); - - if (result == lyx::find::SR_FOUND) { - LyXCursor cur = text_.cursor; - bv->unlockInset(bv->theLockingInset()); - if (bv->lockInset(this)) - locked = true; - text_.cursor = cur; - text_.setSelectionRange(str.length()); - updateLocal(bv, false); - } - return result != lyx::find::SR_NOT_FOUND; -} - - -bool InsetText::searchBackward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - if (the_locking_inset) { - if (the_locking_inset->searchBackward(bv, str, cs, mw)) - return true; - } - if (!locked) { - text_.setCursor(paragraphs.size() - 1, paragraphs.back().size()); - } - lyx::find::SearchResult result = - lyx::find::find(bv, &text_, str, false, cs, mw); - - if (result == lyx::find::SR_FOUND) { - LyXCursor cur = text_.cursor; - bv->unlockInset(bv->theLockingInset()); - if (bv->lockInset(this)) - locked = true; - text_.cursor = cur; - text_.setSelectionRange(str.length()); - updateLocal(bv, false); - } - return result != lyx::find::SR_NOT_FOUND; -} - - bool InsetText::checkInsertChar(LyXFont & font) { return owner() ? owner()->checkInsertChar(font) : true; diff --git a/src/insets/insettext.h b/src/insets/insettext.h index b9de092828..57ce3daa25 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -168,15 +168,7 @@ public: * for the (empty) paragraph contained. */ void markNew(bool track_changes = false); - /// find next change - bool nextChange(BufferView *, lyx::pos_type & length); - /// - bool searchForward(BufferView *, std::string const &, - bool = true, bool = false); - /// - bool searchBackward(BufferView *, std::string const &, - bool = true, bool = false); /// bool checkInsertChar(LyXFont &); /// diff --git a/src/insets/updatableinset.C b/src/insets/updatableinset.C index a62fbc0be7..4a5cb9a2e9 100644 --- a/src/insets/updatableinset.C +++ b/src/insets/updatableinset.C @@ -136,29 +136,3 @@ LyXCursor const & InsetOld::cursor(BufferView * bv) const return owner()->getLyXText(bv, false)->cursor; return bv->text->cursor; } - - -bool UpdatableInset::nextChange(BufferView * bv, lyx::pos_type &) -{ - // we have to unlock ourself in this function by default! - bv->unlockInset(const_cast(this)); - return false; -} - - -bool UpdatableInset::searchForward(BufferView * bv, string const &, - bool, bool) -{ - // we have to unlock ourself in this function by default! - bv->unlockInset(const_cast(this)); - return false; -} - - -bool UpdatableInset::searchBackward(BufferView * bv, string const &, - bool, bool) -{ - // we have to unlock ourself in this function by default! - bv->unlockInset(const_cast(this)); - return false; -} diff --git a/src/insets/updatableinset.h b/src/insets/updatableinset.h index bdb503bced..058db608dd 100644 --- a/src/insets/updatableinset.h +++ b/src/insets/updatableinset.h @@ -89,18 +89,6 @@ public: /// virtual void toggleSelection(BufferView *, bool /*kill_selection*/) {} - /// find the next change in the inset - virtual bool nextChange(BufferView * bv, lyx::pos_type & length); - - /// - // needed for search/replace functionality - /// - virtual bool searchForward(BufferView *, std::string const &, - bool = true, bool = false); - /// - virtual bool searchBackward(BufferView *, std::string const &, - bool = true, bool = false); - protected: /// An updatable inset could handle lyx editing commands virtual diff --git a/src/lyxfind.C b/src/lyxfind.C index dfa961eb18..fe64e943a8 100644 --- a/src/lyxfind.C +++ b/src/lyxfind.C @@ -6,6 +6,7 @@ * \author Lars Gullik Bjønnes * \author John Levon * \author Jürgen Vigna + * \author Alfredo Braunstein * * Full author contact details are available in file CREDITS. */ @@ -16,9 +17,13 @@ #include "buffer.h" #include "BufferView.h" +#include "debug.h" +#include "iterators.h" #include "gettext.h" #include "lyxtext.h" #include "paragraph.h" +#include "PosIterator.h" +#include "undo.h" #include "frontends/Alert.h" @@ -28,6 +33,7 @@ using lyx::support::lowercase; using lyx::support::uppercase; +using bv_funcs::put_selection_at; using std::string; @@ -37,304 +43,234 @@ namespace find { namespace { -// returns true if the specified string is at the specified position -bool isStringInText(Paragraph const & par, pos_type pos, - string const & str, bool const & cs, - bool const & mw) +class MatchString { - string::size_type size = str.length(); - pos_type i = 0; - pos_type parsize = par.size(); - while ((pos + i < parsize) - && (string::size_type(i) < size) - && (cs ? (str[i] == par.getChar(pos + i)) - : (uppercase(str[i]) == uppercase(par.getChar(pos + i))))) { - ++i; - } - - if (size == string::size_type(i)) { - // if necessary, check whether string matches word - if (!mw) - return true; - if ((pos <= 0 || !IsLetterCharOrDigit(par.getChar(pos - 1))) - && (pos + pos_type(size) >= parsize - || !IsLetterCharOrDigit(par.getChar(pos + size)))) { - return true; +public: + MatchString(string const & str, bool cs, bool mw) + : str(str), cs(cs), mw(mw) {}; +// returns true if the specified string is at the specified position + bool operator()(Paragraph const & par, pos_type pos) const + { + string::size_type size = str.length(); + pos_type i = 0; + pos_type parsize = par.size(); + while ((pos + i < parsize) + && (string::size_type(i) < size) + && (cs ? (str[i] == par.getChar(pos + i)) + : (uppercase(str[i]) == uppercase(par.getChar(pos + i))))) { + ++i; } - } - return false; -} - -// forward search: -// if the string can be found: return true and set the cursor to -// the new position, cs = casesensitive, mw = matchword -SearchResult searchForward(BufferView * bv, LyXText * text, string const & str, - bool const & cs, bool const & mw) -{ - ParagraphList::iterator pit = text->cursorPar(); - ParagraphList::iterator pend = text->ownerParagraphs().end(); - pos_type pos = text->cursor.pos(); - UpdatableInset * inset; - - while (pit != pend && !isStringInText(*pit, pos, str, cs, mw)) { - if (pos < pit->size() - && pit->isInset(pos) - && (inset = (UpdatableInset *)pit->getInset(pos)) - && inset->isTextInset() - && inset->searchForward(bv, str, cs, mw)) - return SR_FOUND_NOUPDATE; - - if (++pos >= pit->size()) { - ++pit; - pos = 0; + if (size == string::size_type(i)) { + // if necessary, check whether string matches word + if (!mw) + return true; + if ((pos <= 0 || !IsLetterCharOrDigit(par.getChar(pos - 1))) + && (pos + pos_type(size) >= parsize + || !IsLetterCharOrDigit(par.getChar(pos + size)))) { + return true; + } } + return false; } + +private: + string str; + bool cs; + bool mw; +}; - if (pit != pend) { - text->setCursor(pit, pos); - return SR_FOUND; - } - return SR_NOT_FOUND; -} -// backward search: -// if the string can be found: return true and set the cursor to -// the new position, cs = casesensitive, mw = matchword -SearchResult searchBackward(BufferView * bv, LyXText * text, - string const & str, - bool const & cs, bool const & mw) -{ - ParagraphList::iterator pit = text->cursorPar(); - ParagraphList::iterator pbegin = text->ownerParagraphs().begin(); - pos_type pos = text->cursor.pos(); - - // skip past a match at the current cursor pos - if (pos > 0) { - --pos; - } else if (pit != pbegin) { - --pit; - pos = pit->size(); - } else { - return SR_NOT_FOUND; - } +} //namespace anon - while (true) { - if (pos < pit->size()) { - if (pit->isInset(pos) && pit->getInset(pos)->isTextInset()) { - UpdatableInset * inset = (UpdatableInset *)pit->getInset(pos); - if (inset->searchBackward(bv, str, cs, mw)) - return SR_FOUND_NOUPDATE; - } - if (isStringInText(*pit, pos, str, cs, mw)) { - text->setCursor(pit, pos); - return SR_FOUND; - } - } - if (pos == 0 && pit == pbegin) - break; - if (pos > 0) { - --pos; - } else if (pit != pbegin) { - --pit; - pos = pit->size(); - } - } - return SR_NOT_FOUND; -} +namespace { -} // anon namespace -int replace(BufferView * bv, - string const & searchstr, string const & replacestr, - bool forward, bool casesens, bool matchwrd, bool replaceall, - bool once) +bool findForward(PosIterator & cur, PosIterator const & end, + MatchString & match) { - if (!bv->available() || bv->buffer()->isReadonly()) - return 0; + for (; cur != end && !match(*cur.pit(), cur.pos()); ++cur) + ; - // CutSelection cannot cut a single space, so we have to stop - // in order to avoid endless loop :-( - if (searchstr.length() == 0 - || (searchstr.length() == 1 && searchstr[0] == ' ')) { -#ifdef WITH_WARNINGS -#warning BLECH. If we have an LFUN for replace, we can sort of fix this bogosity -#endif - Alert::error(_("Cannot replace"), - _("You cannot replace a single space or " - "an empty character.")); - return 0; - } - - // now we can start searching for the first - // start at top if replaceall - LyXText * text = bv->getLyXText(); - bool fw = forward; - if (replaceall) { - text->clearSelection(); - bv->unlockInset(bv->theLockingInset()); - text = bv->text; - text->cursorTop(); - // override search direction because we search top to bottom - fw = true; - } + return cur != end; +} - // if nothing selected or selection does not equal search string - // search and select next occurance and return if no replaceall - string str1; - string str2; - if (casesens) { - str1 = searchstr; - str2 = text->selectionAsString(*bv->buffer(), false); - } else { - str1 = lowercase(searchstr); - str2 = lowercase(text->selectionAsString(*bv->buffer(), false)); - } - if (str1 != str2) { - if (!find(bv, searchstr, fw, casesens, matchwrd) || - !replaceall) { - return 0; - } - } - bool found = false; - int replace_count = 0; +bool findBackwards(PosIterator & cur, PosIterator const & beg, + MatchString & match) +{ + if (beg == cur) + return false; do { - text = bv->getLyXText(); - // We have to do this check only because mathed insets don't - // return their own LyXText but the LyXText of it's parent! - if (!bv->theLockingInset() || - ((text != bv->text) && - (text->inset_owner == text->inset_owner->getLockingInset()))) { - text->replaceSelectionWithString(replacestr); - text->setSelectionRange(replacestr.length()); - ++replace_count; - } - if (!once) - found = find(bv, searchstr, fw, casesens, matchwrd); - } while (!once && replaceall && found); + --cur; + if (match(*cur.pit(), cur.pos())) + break; + } while (cur != beg); - // FIXME: should be called via an LFUN - bv->buffer()->markDirty(); - bv->update(); + return match(*cur.pit(), cur.pos()); +} - return replace_count; + +bool findChange(PosIterator & cur, PosIterator const & end) +{ + for (; cur != end; ++cur) { + if ((!cur.pit()->size() || !cur.at_end()) + && cur.pit()->lookupChange(cur.pos()) != Change::UNCHANGED) + break; + } + + return cur != end; } -bool find(BufferView * bv, - string const & searchstr, bool forward, - bool casesens, bool matchwrd) +bool searchAllowed(BufferView * bv, string const & str) { - if (!bv->available() || searchstr.empty()) + if (str.empty()) { + Alert::error(_("Search error"), _("Search string is empty")); return false; - - if (bv->theLockingInset()) { - bool found = forward ? - bv->theLockingInset()->searchForward(bv, searchstr, casesens, matchwrd) : - bv->theLockingInset()->searchBackward(bv, searchstr, casesens, matchwrd); - // We found the stuff inside the inset so we don't have to - // do anything as the inset did all the update for us! - if (found) - return true; - // We now are in the main text but if we did a forward - // search we have to put the cursor behind the inset. - if (forward) { - bv->text->cursorRight(true); - } } - // If we arrive here we are in the main text again so we - // just start searching from the root LyXText at the position - // we are! - LyXText * text = bv->text; - - - if (text->selection.set()) - text->cursor = forward ? - text->selection.end : text->selection.start; - - text->clearSelection(); - - SearchResult result = forward ? - searchForward(bv, text, searchstr, casesens, matchwrd) : - searchBackward(bv, text, searchstr, casesens, matchwrd); - - bool found = true; - // If we found the cursor inside an inset we will get back - // SR_FOUND_NOUPDATE and we don't have to do anything as the - // inset did it already. - if (result == SR_FOUND) { - bv->unlockInset(bv->theLockingInset()); - text->setSelectionRange(searchstr.length()); - } else if (result == SR_NOT_FOUND) { - bv->unlockInset(bv->theLockingInset()); - found = false; - } - bv->update(); - - return found; + if (!bv->available()) + return false; + return true; + } +} // namespace anon -SearchResult find(BufferView * bv, LyXText * text, - string const & searchstr, bool forward, - bool casesens, bool matchwrd) + +bool find(BufferView * bv, string const & searchstr, + bool cs, bool mw, bool fw) { - if (text->selection.set()) - text->cursor = forward ? - text->selection.end : text->selection.start; + if (!searchAllowed(bv, searchstr)) + return false; + + PosIterator cur = PosIterator(*bv); - text->clearSelection(); + MatchString match(searchstr, cs, mw); + + bool found; - SearchResult result = forward ? - searchForward(bv, text, searchstr, casesens, matchwrd) : - searchBackward(bv, text, searchstr, casesens, matchwrd); + if (fw) { + PosIterator const end = bv->buffer()->pos_iterator_end(); + found = findForward(cur, end, match); + } else { + PosIterator const beg = bv->buffer()->pos_iterator_begin(); + found = findBackwards(cur, beg, match); + } + + if (found) + put_selection_at(bv, cur, searchstr.length(), !fw); - return result; + return found; } +namespace { + + + +} //namespace anon -SearchResult nextChange(BufferView * bv, LyXText * text, pos_type & length) +int replaceAll(BufferView * bv, + string const & searchstr, string const & replacestr, + bool cs, bool mw) { - ParagraphList::iterator pit = text->cursorPar(); - ParagraphList::iterator pend = text->ownerParagraphs().end(); - pos_type pos = text->cursor.pos(); + Buffer & buf = *bv->buffer(); - while (pit != pend) { - pos_type parsize = pit->size(); + if (!searchAllowed(bv, searchstr) || buf.isReadonly()) + return 0; + + recordUndo(Undo::ATOMIC, bv->text, 0, + buf.paragraphs().size() - 1); + + PosIterator cur = buf.pos_iterator_begin(); + PosIterator const end = buf.pos_iterator_end(); + MatchString match(searchstr, cs, mw); + int num = 0; + + int const rsize = replacestr.size(); + int const ssize = searchstr.size(); + while (findForward(cur, end, match)) { + 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); + ++num; + } + PosIterator beg = buf.pos_iterator_begin(); + bv->text->init(bv); + put_selection_at(bv, beg, 0, false); + return num; +} - if (pos < parsize) { - if ((!parsize || pos != parsize) - && pit->lookupChange(pos) != Change::UNCHANGED) - break; - if (pit->isInset(pos) && pit->getInset(pos)->isTextInset()) { - UpdatableInset * inset = (UpdatableInset *)pit->getInset(pos); - if (inset->nextChange(bv, length)) - return SR_FOUND_NOUPDATE; - } +int replace(BufferView * bv, + string const & searchstr, string const & replacestr, + bool cs, bool mw, bool fw) +{ + if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) + return 0; + + { + LyXText * text = bv->getLyXText(); + // if nothing selected or selection does not equal search + // string search and select next occurance and return + string const str1 = searchstr; + string const str2 = text->selectionAsString(*bv->buffer(), + false); + if ((cs && str1 != str2) + || lowercase(str1) != lowercase(str2)) { + find(bv, searchstr, cs, mw, fw); + return 0; } + } - ++pos; - - if (pos >= parsize) { - ++pit; - pos = 0; - } + LyXText * text = bv->getLyXText(); + // We have to do this check only because mathed insets don't + // return their own LyXText but the LyXText of it's parent! + if (!bv->theLockingInset() || + ((text != bv->text) && + (text->inset_owner == text->inset_owner->getLockingInset()))) { + text->replaceSelectionWithString(replacestr); + text->setSelectionRange(replacestr.length()); + text->cursor = fw ? text->selection.end + : text->selection.start; } - if (pit == pend) - return SR_NOT_FOUND; + // FIXME: should be called via an LFUN + bv->buffer()->markDirty(); + + find(bv, searchstr, cs, mw, fw); + bv->update(); + + return 1; +} + + +bool findNextChange(BufferView * bv) +{ + if (!bv->available()) + return false; + + PosIterator cur = PosIterator(*bv); + PosIterator const endit = bv->buffer()->pos_iterator_end(); - text->setCursor(pit, pos); + 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; @@ -349,69 +285,10 @@ SearchResult nextChange(BufferView * bv, LyXText * text, pos_type & length) break; } } - length = end - pos; - return SR_FOUND; -} - - -SearchResult findNextChange(BufferView * bv, LyXText * text, pos_type & length) -{ - if (text->selection.set()) - text->cursor = text->selection.end; - - text->clearSelection(); - - return nextChange(bv, text, length); -} - - -bool findNextChange(BufferView * bv) -{ - if (!bv->available()) - return false; - - pos_type length; - - if (bv->theLockingInset()) { - bool found = bv->theLockingInset()->nextChange(bv, length); - - // We found the stuff inside the inset so we don't have to - // do anything as the inset did all the update for us! - if (found) - return true; - - // We now are in the main text but if we did a forward - // search we have to put the cursor behind the inset. - bv->text->cursorRight(true); - } - // If we arrive here we are in the main text again so we - // just start searching from the root LyXText at the position - // we are! - LyXText * text = bv->text; - - if (text->selection.set()) - text->cursor = text->selection.end; - - text->clearSelection(); - - SearchResult result = nextChange(bv, text, length); - - bool found = true; - - // If we found the cursor inside an inset we will get back - // SR_FOUND_NOUPDATE and we don't have to do anything as the - // inset did it already. - if (result == SR_FOUND) { - bv->unlockInset(bv->theLockingInset()); - text->setSelectionRange(length); - } else if (result == SR_NOT_FOUND) { - bv->unlockInset(bv->theLockingInset()); - found = false; - } - - bv->update(); - - return found; + pos_type length = end - pos; + bv->text->init(bv); + put_selection_at(bv, cur, length, true); + return true; } } // find namespace diff --git a/src/lyxfind.h b/src/lyxfind.h index 4888047638..61e3977053 100644 --- a/src/lyxfind.h +++ b/src/lyxfind.h @@ -7,6 +7,7 @@ * \author Lars Gullik Bjønnes * \author John Levon * \author Jürgen Vigna + * \author Alfredo Braunstein * * Full author contact details are available in file CREDITS. */ @@ -24,49 +25,50 @@ class LyXText; namespace lyx { namespace find { -enum SearchResult { - // - SR_NOT_FOUND = 0, - // - SR_FOUND, - // - SR_FOUND_NOUPDATE -}; - +/** + * This function replaces an ocurrence of \param search with the + * string \param replace + * + * \param bv the BufferView in which the search is to be performed, + * starting at the current cursor position. + * \param search the string we're looking for. + * \param replace if \c search is found, replace it with this. + * \param cs perform a case-sensitive search for \c search. + * \param mw match whole words only. + * \param fw search forward from the current cursor position. + */ int replace(BufferView * bv, - std::string const &, std::string const &, - bool, bool = true, bool = false, - bool = false, bool = false); - + std::string const & search, std::string const & replace, + bool cs, bool mw, bool fw); /** - * This function is called as a general interface to find some - * text from the actual cursor position in whatever direction - * we want to go. This does also update the screen. + * This function replaces all ocurrences of \param search with + * the string \param replace + * + * \param bv the BufferView in which the search is to be performed, + * starting at the current cursor position. + * \param search the string we're looking for. + * \param replace if \c search is found, replace it with this. + * \param cs perform a case-sensitive search for \c search. + * \param mw match whole words only. */ -bool find(BufferView *, - std::string const & searchstr, bool forward, - bool casesens = true, bool matchwrd = false); + +int replaceAll(BufferView * bv, + std::string const & search, std::string const & replace, + bool cs, bool mw); /** - * This function does search from the cursor position inside the - * passed LyXText parameter and regards this LyXText as the root - * LyXText. It will NOT update any screen stuff. It will however - * set the cursor to the new position inside LyXText, before - * returning to the calling function. + * This function is called as a general interface to find some text + * from the actual cursor position in whatever direction we want to + * go. This does also update the screen. */ +bool find(BufferView *, std::string const & search, + bool cs, bool mw, bool fw); -SearchResult find(BufferView *, LyXText * text, - std::string const & searchstr, bool forward, - bool casesens = true, bool matchwrd = false); /// find the next change in the buffer bool findNextChange(BufferView * bv); -SearchResult findNextChange(BufferView * bv, LyXText * text, lyx::pos_type & length); - -SearchResult nextChange(BufferView * bv, LyXText * text, lyx::pos_type & length); - } // namespace find } // namespace lyx diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 99c68b272f..a4bac22fb7 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -1087,7 +1087,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) } bool fw = (action == LFUN_WORDFINDFORWARD); if (!searched_string.empty()) - lyx::find::find(view(), searched_string, fw); + lyx::find::find(view(), searched_string, + true, false, fw); break; } diff --git a/src/paragraph.C b/src/paragraph.C index e95ab46dd5..aedb757338 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -257,6 +257,15 @@ int Paragraph::erase(pos_type start, pos_type end) } +void Paragraph::insert(pos_type start, string const & str, + LyXFont const & font) +{ + int size = str.size(); + for (int i = 0 ; i < size ; ++i) + insertChar(start + i, str[i], font); +} + + bool Paragraph::checkInsertChar(LyXFont & font) { if (pimpl_->inset_owner) diff --git a/src/paragraph.h b/src/paragraph.h index 977520372d..d0338cd4c4 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -271,6 +271,9 @@ public: lyx::pos_type endpos, LyXFont_size def_size) const; /// + void insert(lyx::pos_type pos, std::string const & str, + LyXFont const & font); + /// void insertChar(lyx::pos_type pos, value_type c); /// void insertChar(lyx::pos_type pos, value_type c, LyXFont const &, Change change = Change(Change::INSERTED)); -- 2.39.2