This is what's left in my tree. lyxfind.C attached separately as is has been
completely overhauled.

Should solve all existing s&r and spellchecking problems and has a much
nicer (and shorter) code.

(the removal of all recursive spellchecking code is still missing and it has
already a pretty negative linecount)

I'll break up and send in little pieces.

Alfredo
Index: BufferView_pimpl.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v
retrieving revision 1.451
diff -u -p -u -r1.451 BufferView_pimpl.C
--- BufferView_pimpl.C	1 Nov 2003 15:45:12 -0000	1.451
+++ BufferView_pimpl.C	3 Nov 2003 12:18:21 -0000
@@ -418,8 +418,6 @@ void BufferView::Pimpl::resizeCurrentBuf
 		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_);
 	}
Index: bufferview_funcs.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferview_funcs.h,v
retrieving revision 1.25
diff -u -p -u -r1.25 bufferview_funcs.h
--- bufferview_funcs.h	3 Nov 2003 09:23:23 -0000	1.25
+++ bufferview_funcs.h	3 Nov 2003 12:18:21 -0000
@@ -45,8 +45,7 @@ void update_and_apply_freefont(BufferVie
  */
 void apply_freefont(BufferView * bv);
 
-
-void put_selection_at(BufferView * bv, PosIterator & cur,
+void put_selection_at(BufferView * bv, PosIterator const & cur,
 		      int length, bool backwards);
 
 
Index: lyxfind.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxfind.h,v
retrieving revision 1.16
diff -u -p -u -r1.16 lyxfind.h
--- lyxfind.h	7 Oct 2003 06:45:24 -0000	1.16
+++ lyxfind.h	3 Nov 2003 12:18:22 -0000
@@ -24,29 +24,21 @@ class LyXText;
 namespace lyx {
 namespace find {
 
-enum SearchResult {
-	//
-	SR_NOT_FOUND = 0,
-	//
-	SR_FOUND,
-	//
-	SR_FOUND_NOUPDATE
-};
-
-
 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 & /*repl*/,
+	    bool /*cs*/, bool /*mw*/, bool /*fw*/);
+
+int replaceAll(BufferView * bv,
+	       std::string const & /*search*/, std::string const & /*repl*/,
+	       bool /*cs*/, bool /*mw*/);
 
 /**
  * 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 & searchstr, bool forward,
-	     bool casesens = true, bool matchwrd = false);
+bool find(BufferView *, std::string const & /*search*/, 
+	  bool /*cs*/, bool /*mw*/, bool /*fw*/);
 
 /**
  * This function does search from the cursor position inside the
@@ -56,16 +48,8 @@ bool find(BufferView *,
  * returning to the calling function.
  */
 
-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
Index: lyxfunc.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxfunc.C,v
retrieving revision 1.530
diff -u -p -u -r1.530 lyxfunc.C
--- lyxfunc.C	1 Nov 2003 15:45:14 -0000	1.530
+++ lyxfunc.C	3 Nov 2003 12:18:26 -0000
@@ -1078,7 +1078,8 @@ void LyXFunc::dispatch(FuncRequest const
 		}
 		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;
 	}
 
Index: paragraph.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v
retrieving revision 1.340
diff -u -p -u -r1.340 paragraph.C
--- paragraph.C	31 Oct 2003 18:45:34 -0000	1.340
+++ paragraph.C	3 Nov 2003 12:18:28 -0000
@@ -257,6 +257,15 @@ int Paragraph::erase(pos_type start, pos
 }
 
 
+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)
Index: paragraph.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.h,v
retrieving revision 1.117
diff -u -p -u -r1.117 paragraph.h
--- paragraph.h	31 Oct 2003 18:45:35 -0000	1.117
+++ paragraph.h	3 Nov 2003 12:18:29 -0000
@@ -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));
Index: text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v
retrieving revision 1.491
diff -u -p -u -r1.491 text.C
--- text.C	29 Oct 2003 12:18:07 -0000	1.491
+++ text.C	3 Nov 2003 12:18:31 -0000
@@ -1209,17 +1209,18 @@ void LyXText::acceptChange()
 	if (!selection.set() && cursorPar()->size())
 		return;
 
-	if (selection.start.par() == selection.end.par()) {
-		LyXCursor & startc = selection.start;
-		LyXCursor & endc = selection.end;
-		recordUndo(Undo::INSERT, this, startc.par());
-		getPar(startc)->acceptChange(startc.pos(), endc.pos());
-		finishUndo();
-		clearSelection();
-		redoParagraph(getPar(startc));
-		setCursorIntern(startc.par(), 0);
-	}
 #warning handle multi par selection
+	if (selection.start.par() != selection.end.par())
+		return;
+
+	LyXCursor & startc = selection.start;
+	LyXCursor & endc = selection.end;
+	recordUndo(Undo::INSERT, this, startc.par());
+	getPar(startc)->acceptChange(startc.pos(), endc.pos());
+	finishUndo();
+	clearSelection();
+	redoParagraph(getPar(startc));
+	setCursorIntern(startc.par(), 0);
 }
 
 
@@ -1228,17 +1229,18 @@ void LyXText::rejectChange()
 	if (!selection.set() && cursorPar()->size())
 		return;
 
-	if (selection.start.par() == selection.end.par()) {
-		LyXCursor & startc = selection.start;
-		LyXCursor & endc = selection.end;
-		recordUndo(Undo::INSERT, this, startc.par());
-		getPar(startc)->rejectChange(startc.pos(), endc.pos());
-		finishUndo();
-		clearSelection();
-		redoParagraph(getPar(startc));
-		setCursorIntern(startc.par(), 0);
-	}
 #warning handle multi par selection
+	if (selection.start.par() != selection.end.par())
+		return;
+
+	LyXCursor & startc = selection.start;
+	LyXCursor & endc = selection.end;
+	recordUndo(Undo::INSERT, this, startc.par());
+	getPar(startc)->rejectChange(startc.pos(), endc.pos());
+	finishUndo();
+	clearSelection();
+	redoParagraph(getPar(startc));
+	setCursorIntern(startc.par(), 0);
 }
 
 
@@ -1592,7 +1594,7 @@ void LyXText::backspace()
 
 ParagraphList::iterator LyXText::cursorPar() const
 {
-	if (cursor.par() != cache_pos_) {
+	if (cursor.par() != cache_pos_ || cache_pos_ == -1) {
 		cache_pos_ = cursor.par();
 		cache_par_ = getPar(cache_pos_);
 	}
Index: undo.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo.C,v
retrieving revision 1.25
diff -u -p -u -r1.25 undo.C
--- undo.C	29 Oct 2003 12:18:08 -0000	1.25
+++ undo.C	3 Nov 2003 12:18:32 -0000
@@ -200,12 +200,8 @@ bool performUndoOrRedo(BufferView * bv, 
 	// rebreak the entire lyxtext
 	bv->text->fullRebreak();
 
-	InsetOld * inset = pit.inset();
-	if (inset) {
-		// magic needed to cope with inset locking
-		bv->lockInset(dynamic_cast<UpdatableInset *>(inset));
-	}
-
+	pit.lockPath(bv);
+	
 	finishUndo();
 	return true;
 }
Index: frontends/controllers/ControlSearch.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSearch.C,v
retrieving revision 1.27
diff -u -p -u -r1.27 ControlSearch.C
--- frontends/controllers/ControlSearch.C	6 Oct 2003 15:42:46 -0000	1.27
+++ frontends/controllers/ControlSearch.C	3 Nov 2003 12:18:32 -0000
@@ -32,8 +32,8 @@ void ControlSearch::find(string const & 
 			 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 & 
 
 
 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!"));
Index: frontends/controllers/ControlSearch.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSearch.h,v
retrieving revision 1.15
diff -u -p -u -r1.15 ControlSearch.h
--- frontends/controllers/ControlSearch.h	6 Oct 2003 15:42:46 -0000	1.15
+++ frontends/controllers/ControlSearch.h	3 Nov 2003 12:18:32 -0000
@@ -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() {}
Index: frontends/controllers/ControlSpellchecker.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.C,v
retrieving revision 1.56
diff -u -p -u -r1.56 ControlSpellchecker.C
--- frontends/controllers/ControlSpellchecker.C	6 Oct 2003 15:42:46 -0000	1.56
+++ frontends/controllers/ControlSpellchecker.C	3 Nov 2003 12:18:33 -0000
@@ -16,11 +16,15 @@
 #include "buffer.h"
 #include "bufferparams.h"
 #include "BufferView.h"
+#include "bufferview_funcs.h"
 #include "debug.h"
 #include "gettext.h"
 #include "language.h"
 #include "lyxrc.h"
 
+#include "PosIterator.h"
+#include "paragraph.h"
+
 #include "ispell.h"
 #ifdef USE_PSPELL
 # include "pspell.h"
@@ -43,7 +47,7 @@ using std::string;
 
 ControlSpellchecker::ControlSpellchecker(LyXView & lv, Dialogs & d)
 	: ControlDialogBD(lv, d),
-	  newval_(0.0), oldval_(0), newvalue_(0), count_(0)
+	  oldval_(0), newvalue_(0), count_(0)
 {}
 
 
@@ -67,6 +71,7 @@ void ControlSpellchecker::clearParams()
 
 namespace {
 
+
 SpellBase * getSpeller(BufferParams const & bp)
 {
 	string lang = (lyxrc.isp_use_alt_lang)
@@ -104,7 +109,6 @@ void ControlSpellchecker::startSession()
 	speller_.reset(getSpeller(buffer()->params()));
 
 	// reset values to initial
-	newval_ = 0.0;
 	oldval_ = 0;
 	newvalue_ = 0;
 	count_ = 0;
@@ -131,7 +135,7 @@ void ControlSpellchecker::endSession()
 {
 	lyxerr[Debug::GUI] << "spell endSession" << endl;
 
-	bufferview()->endOfSpellCheck();
+//	bufferview()->endOfSpellCheck();
 
 	emergency_exit_ = true;
 
@@ -144,17 +148,61 @@ void ControlSpellchecker::endSession()
 }
 
 
+namespace {
+
+
+bool isLetter(PosIterator & cur)
+{
+	return !cur.at_end()
+		&& cur.pit()->isLetter(cur.pos())
+		&& !isDeletedText(*cur.pit(), cur.pos());
+}
+
+
+WordLangTuple nextWord(PosIterator & cur, PosIterator const & end,
+		       int & progress, BufferParams & bp)
+{
+	// skip until we have real text (will jump paragraphs)
+	for (; cur != end && !isLetter(cur); ++cur, ++progress);
+	
+	if (cur == end)
+		return WordLangTuple(string(), string());
+
+	string lang_code = cur.pit()->getFontSettings(bp, cur.pos()).language()->code();
+	string str;
+	// and find the end of the word (insets like optional hyphens
+	// and ligature break are part of a word)
+	for (; cur != end && isLetter(cur); ++cur, ++progress)
+		str += cur.pit()->getChar(cur.pos());
+
+	return WordLangTuple(str, lang_code);
+}
+
+
+} //namespace anon
+
+
+
+
 void ControlSpellchecker::check()
 {
 	lyxerr[Debug::GUI] << "spell check a word" << endl;
 
 	SpellBase::Result res = SpellBase::OK;
 
-	// clear any old selection
-	bufferview()->update();
+	PosIterator cur(*bufferview());
+	PosIterator const end = buffer()->pos_iterator_end();
+	PosIterator const beg = buffer()->pos_iterator_end();
+
+	int start = distance(beg, cur);
+	int const total = start + distance(cur, end);
+
+	if (cur != buffer()->pos_iterator_begin())
+		for (; cur != end && isLetter(cur); ++cur, ++start);
 
+	
 	while (res == SpellBase::OK || res == SpellBase::IGNORE) {
-		word_ = bufferview()->nextWord(newval_);
+		word_ = nextWord(cur, end, start, buffer()->params());
 
 		// end of document
 		if (word_.word().empty())
@@ -163,7 +211,8 @@ void ControlSpellchecker::check()
 		++count_;
 
 		// Update slider if and only if value has changed
-		newvalue_ = int(100.0 * newval_);
+		float progress = total ? float(start)/total : 1;
+		newvalue_ = int(100.0 * progress);
 		if (newvalue_!= oldval_) {
 			lyxerr[Debug::GUI] << "Updating spell progress." << endl;
 			oldval_ = newvalue_;
@@ -183,11 +232,12 @@ void ControlSpellchecker::check()
 	}
 
 	lyxerr[Debug::GUI] << "Found word \"" << word_.word() << "\"" << endl;
-	lyxerr << "Found word \"" << word_.word() << "\"" << endl;
 
 	if (!word_.word().empty()) {
-		bufferview()->selectLastWord();
-		bufferview()->fitCursor();
+		int const size = word_.word().size();
+		advance(cur, -size);
+		bv_funcs::put_selection_at(bufferview(), cur, size, false);
+		advance(cur, size);
 	} else {
 		showSummary();
 		endSession();
Index: frontends/controllers/ControlSpellchecker.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlSpellchecker.h,v
retrieving revision 1.19
diff -u -p -u -r1.19 ControlSpellchecker.h
--- frontends/controllers/ControlSpellchecker.h	6 Oct 2003 15:42:46 -0000	1.19
+++ frontends/controllers/ControlSpellchecker.h	3 Nov 2003 12:18:33 -0000
@@ -85,7 +85,6 @@ private:
 	WordLangTuple word_;
 
 	/// values for progress
-	float newval_;
 	int oldval_;
 	int newvalue_;
 
Index: frontends/controllers/ControlThesaurus.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlThesaurus.C,v
retrieving revision 1.18
diff -u -p -u -r1.18 ControlThesaurus.C
--- frontends/controllers/ControlThesaurus.C	6 Oct 2003 15:42:47 -0000	1.18
+++ frontends/controllers/ControlThesaurus.C	3 Nov 2003 12:18:33 -0000
@@ -48,7 +48,7 @@ void ControlThesaurus::replace(string co
 	 */
 	int const replace_count =
 		lyx::find::replace(kernel().bufferview(), oldstr_, newstr,
-				    true, true, true, false, true);
+				   true /*cs*/, true /*mw*/, true /*fw*/);
 
 	oldstr_ = newstr;
 
Index: frontends/qt2/QSearch.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSearch.C,v
retrieving revision 1.19
diff -u -p -u -r1.19 QSearch.C
--- frontends/qt2/QSearch.C	6 Oct 2003 15:42:51 -0000	1.19
+++ frontends/qt2/QSearch.C	3 Nov 2003 12:18:34 -0000
@@ -54,7 +54,8 @@ void QSearch::find(string const & str, b
 
 
 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);
 }
Index: frontends/qt2/QSearch.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSearch.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 QSearch.h
--- frontends/qt2/QSearch.h	6 Oct 2003 15:42:51 -0000	1.10
+++ frontends/qt2/QSearch.h	3 Nov 2003 12:18:34 -0000
@@ -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
Index: frontends/qt2/QSearchDialog.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/QSearchDialog.C,v
retrieving revision 1.14
diff -u -p -u -r1.14 QSearchDialog.C
--- frontends/qt2/QSearchDialog.C	6 Oct 2003 15:42:51 -0000	1.14
+++ frontends/qt2/QSearchDialog.C	3 Nov 2003 12:18:34 -0000
@@ -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());
 }
Index: frontends/xforms/FormSearch.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormSearch.C,v
retrieving revision 1.27
diff -u -p -u -r1.27 FormSearch.C
--- frontends/xforms/FormSearch.C	6 Oct 2003 15:42:57 -0000	1.27
+++ frontends/xforms/FormSearch.C	3 Nov 2003 12:18:35 -0000
@@ -85,6 +85,7 @@ ButtonPolicy::SMInput FormSearch::input(
 				     getString(dialog_->input_replace),
 				     fl_get_button(dialog_->check_casesensitive),
 				     fl_get_button(dialog_->check_matchword),
+				     !fl_get_button(dialog_->check_searchbackwards),				     
 				     all);
 	}
 
Index: insets/insetcollapsable.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v
retrieving revision 1.190
diff -u -p -u -r1.190 insetcollapsable.C
--- insets/insetcollapsable.C	1 Nov 2003 15:45:15 -0000	1.190
+++ insets/insetcollapsable.C	3 Nov 2003 12:18:36 -0000
@@ -536,42 +536,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;
-}
-
-
 WordLangTuple const
 InsetCollapsable::selectNextWordToSpellcheck(BufferView * bv, float & value) const
 {
Index: insets/insetcollapsable.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.h,v
retrieving revision 1.137
diff -u -p -u -r1.137 insetcollapsable.h
--- insets/insetcollapsable.h	1 Nov 2003 09:56:18 -0000	1.137
+++ insets/insetcollapsable.h	3 Nov 2003 12:18:36 -0000
@@ -142,14 +142,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;
 
Index: insets/insetert.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetert.C,v
retrieving revision 1.166
diff -u -p -u -r1.166 insetert.C
--- insets/insetert.C	1 Nov 2003 15:45:15 -0000	1.166
+++ insets/insetert.C	3 Nov 2003 12:18:37 -0000
@@ -446,6 +446,8 @@ InsetERT::priv_dispatch(FuncRequest cons
 				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);
Index: insets/insettabular.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettabular.C,v
retrieving revision 1.361
diff -u -p -u -r1.361 insettabular.C
--- insets/insettabular.C	1 Nov 2003 15:45:16 -0000	1.361
+++ insets/insettabular.C	3 Nov 2003 12:18:40 -0000
@@ -432,6 +432,9 @@ bool InsetTabular::lockInsetInInset(Buff
 
 	oldcell = -1;
 
+	lyxerr[Debug::INSETTEXT] << "HERE1" << std::endl;
+	
+	
 	if (inset == &tabular.getCellInset(actcell)) {
 		lyxerr[Debug::INSETTEXT] << "OK" << endl;
 		the_locking_inset = &tabular.getCellInset(actcell);
@@ -439,27 +442,37 @@ bool InsetTabular::lockInsetInInset(Buff
 		return true;
 	}
 
+	lyxerr[Debug::INSETTEXT] << "HERE2" << std::endl;
+	
 	if (!the_locking_inset) {
 		int const n = tabular.getNumberOfCells();
 		int const id = inset->id();
 		for (int i = 0; i < n; ++i) {
 			InsetText * in = &tabular.getCellInset(i);
 			if (inset == in) {
+				lyxerr[Debug::INSETTEXT] <<
+					"found!" << std::endl;
 				actcell = i;
 				the_locking_inset = in;
 				locked = true;
 				resetPos(bv);
 				return true;
 			}
+			/*
 			if (in->getInsetFromID(id)) {
 				actcell = i;
 				in->dispatch(FuncRequest(bv, LFUN_INSET_EDIT));
 				return the_locking_inset->lockInsetInInset(bv, inset);
 			}
+			*/
 		}
 		return false;
 	}
 
+	lyxerr[Debug::INSETTEXT] << "HERE3" << std::endl;
+	
+
+	
 	if (the_locking_inset && (the_locking_inset == inset)) {
 		lyxerr[Debug::INSETTEXT] << "OK" << endl;
 		resetPos(bv);
@@ -2490,88 +2503,6 @@ void InsetTabular::markErased()
 {
 	for (int cell = 0; cell < tabular.getNumberOfCells(); ++cell)
 		tabular.getCellInset(cell).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;
 }
 
 
Index: insets/insettabular.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettabular.h,v
retrieving revision 1.157
diff -u -p -u -r1.157 insettabular.h
--- insets/insettabular.h	1 Nov 2003 09:56:18 -0000	1.157
+++ insets/insettabular.h	3 Nov 2003 12:18:41 -0000
@@ -177,14 +177,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;
Index: insets/insettext.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v
retrieving revision 1.521
diff -u -p -u -r1.521 insettext.C
--- insets/insettext.C	1 Nov 2003 15:45:17 -0000	1.521
+++ insets/insettext.C	3 Nov 2003 12:18:43 -0000
@@ -369,6 +369,7 @@ void InsetText::lockInset(BufferView * b
 		font.setLanguage(bv->getParentLanguage(this));
 		setFont(bv, font, false);
 	}
+	lyxerr << "HERE" << std::endl;
 }
 
 
@@ -1493,81 +1494,6 @@ void InsetText::selectSelectedWord(Buffe
 	getLyXText(bv)->selectSelectedWord();
 	updateLocal(bv, false);
 }
-
-
-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;
Index: insets/insettext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.h,v
retrieving revision 1.219
diff -u -p -u -r1.219 insettext.h
--- insets/insettext.h	1 Nov 2003 09:56:18 -0000	1.219
+++ insets/insettext.h	3 Nov 2003 12:18:43 -0000
@@ -177,15 +177,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 &);
 	///
Index: insets/updatableinset.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/updatableinset.C,v
retrieving revision 1.31
diff -u -p -u -r1.31 updatableinset.C
--- insets/updatableinset.C	1 Nov 2003 15:45:17 -0000	1.31
+++ insets/updatableinset.C	3 Nov 2003 12:18:43 -0000
@@ -149,27 +149,3 @@ UpdatableInset::selectNextWordToSpellche
 }
 
 
-bool UpdatableInset::nextChange(BufferView * bv, lyx::pos_type &)
-{
-	// we have to unlock ourself in this function by default!
-	bv->unlockInset(const_cast<UpdatableInset *>(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<UpdatableInset *>(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<UpdatableInset *>(this));
-	return false;
-}
Index: insets/updatableinset.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/updatableinset.h,v
retrieving revision 1.20
diff -u -p -u -r1.20 updatableinset.h
--- insets/updatableinset.h	29 Oct 2003 10:47:19 -0000	1.20
+++ insets/updatableinset.h	3 Nov 2003 12:18:44 -0000
@@ -98,18 +98,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
/**
 * \file lyxfind.C
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Lars Gullik Bjønnes
 * \author John Levon
 * \author Jürgen Vigna
 * \author Alfredo Braunstein
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "lyxfind.h"

#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"

#include "insets/insettext.h"

#include "support/textutils.h"

using lyx::support::lowercase;
using lyx::support::uppercase;
using bv_funcs::put_selection_at;

using std::string;

namespace lyx {
namespace find {


namespace {

class MatchString
{
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;
		}
		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;
};



} //namespace anon





namespace {




bool findForward(PosIterator & cur, PosIterator const & end,
		 MatchString & match)
{
	for (; cur != end && !match(*cur.pit(), cur.pos()); ++cur)
		;

	return cur != end;
}


bool findBackwards(PosIterator & cur, PosIterator const & beg,
		   MatchString & match)
{
	if (beg == cur)
		return false;
	do {
		--cur;
		if (match(*cur.pit(), cur.pos()))
			break;
	} while (cur != beg);

	return match(*cur.pit(), cur.pos());
}


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 searchAllowed(BufferView * bv, string const & str)
{
	if (str.empty()) {
		Alert::error(_("Search error"), _("Search string is empty"));
		return false;
	}
	if (!bv->available())
		return false;
	return true;
	    
}

} // namespace anon


bool find(BufferView * bv, string const & searchstr,
	  bool cs, bool mw, bool fw)
{
	if (!searchAllowed(bv, searchstr))
		return false;

	PosIterator cur = PosIterator(*bv);

	MatchString match(searchstr, cs, mw);
	
	bool found;

	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 found;
}

namespace {
	


 
} //namespace anon


int replaceAll(BufferView * bv,
	       string const & searchstr, string const & replacestr,
	       bool cs, bool mw)
{
	Buffer & buf = *bv->buffer();

	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;
}


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;
		}
	}

	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;
	}

	// 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();

	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->text->init(bv);
	put_selection_at(bv, cur, length, true);
	return true;
}

} // find namespace
} // lyx namespace

Reply via email to