The following patch fixes several *GOTO* lfuns:

- use proper inset iterators to be able to move inside/outside insets

- use BufferView::setCursor so that insets are open as needed

- move the handling of these LFUNS from LyXText to BufferView::Pimpl

- move gotoInset to bufferview_funcs.C.

It would be nice to have some testing before committing it.

JMarc

Index: src/BufferView.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v
retrieving revision 1.259
diff -u -p -r1.259 BufferView.C
--- src/BufferView.C	8 Feb 2005 13:17:53 -0000	1.259
+++ src/BufferView.C	14 Feb 2005 11:23:07 -0000
@@ -275,9 +275,7 @@ void BufferView::gotoLabel(string const 
 		vector<string> labels;
 		it->getLabelList(*buffer(), labels);
 		if (find(labels.begin(),labels.end(),label) != labels.end()) {
-			cursor().clearSelection();
-			text()->setCursor(cursor(), it.pit(), it.pos());
-			cursor().resetAnchor();
+			setCursor(it);
 			update();
 			return;
 		}
@@ -324,12 +322,13 @@ LyXText * BufferView::text() const
 }
 
 
-void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos)
+void BufferView::setCursor(DocIterator const & dit)
 {
-	for (int i = 0, n = par.depth(); i < n; ++i)
-		par[i].inset().edit(cursor(), true);
+	size_t const n = dit.depth();
+	for (size_t i = 0; i < n; ++i)
+		dit[i].inset().edit(cursor(), true);
 
-	cursor().setCursor(makeDocIterator(par, pos));
+	cursor().setCursor(dit);
 	cursor().selection() = false;
 }
 
@@ -337,11 +336,9 @@ void BufferView::setCursor(ParIterator c
 void BufferView::putSelectionAt(DocIterator const & cur,
 				int length, bool backwards)
 {
-	ParIterator par(cur);
-
 	cursor().clearSelection();
 
-	setCursor(par, cur.pos());
+	setCursor(cur);
 
 	if (length) {
 		if (backwards) {
Index: src/BufferView.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.h,v
retrieving revision 1.184
diff -u -p -r1.184 BufferView.h
--- src/BufferView.h	31 Jan 2005 16:29:35 -0000	1.184
+++ src/BufferView.h	14 Feb 2005 11:23:07 -0000
@@ -165,7 +165,7 @@ public:
 	///
 	LyXText * text() const;
 	///
-	void setCursor(ParIterator const & par, lyx::pos_type pos);
+	void setCursor(DocIterator const &);
 	/* Sets the selection. When \c backwards == false, set anchor
 	 * to \c cur and cursor to \c cur + \c length. When \c
 	 * backwards == true, set anchor to \c cur and cursor to \c
Index: src/BufferView_pimpl.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v
retrieving revision 1.578
diff -u -p -r1.578 BufferView_pimpl.C
--- src/BufferView_pimpl.C	14 Feb 2005 08:24:16 -0000	1.578
+++ src/BufferView_pimpl.C	14 Feb 2005 11:23:07 -0000
@@ -76,6 +76,7 @@
 #include <boost/bind.hpp>
 
 #include <functional>
+#include <vector>
 
 using lyx::pos_type;
 
@@ -96,6 +97,7 @@ using std::min;
 using std::max;
 using std::string;
 using std::mem_fun_ref;
+using std::vector;
 
 
 extern BufferList bufferlist;
@@ -132,7 +134,6 @@ T * getInsetByCode(LCursor & cur, InsetB
 	return inset;
 }
 
-
 } // anon namespace
 
 
@@ -722,8 +723,7 @@ void BufferView::Pimpl::restorePosition(
 	if (par == buffer_->par_iterator_end())
 		return;
 
-	bv_->text()->setCursor(cursor_, par.pit(),
-		min(par->size(), saved_positions[i].par_pos));
+	bv_->setCursor(makeDocIterator(par, min(par->size(), saved_positions[i].par_pos)));
 
 	if (i > 0)
 		owner_->message(bformat(_("Moved to bookmark %1$d"), i));
@@ -966,6 +966,9 @@ FuncStatus BufferView::Pimpl::getStatus(
 	case LFUN_BOOKMARK_SAVE:
 	case LFUN_REF_GOTO:
 	case LFUN_GOTO_PARAGRAPH:
+	case LFUN_GOTOERROR:
+	case LFUN_GOTONOTE:
+	case LFUN_REFERENCE_GOTO:
 	case LFUN_WORD_FIND:
 	case LFUN_WORD_REPLACE:
 	case LFUN_MARK_OFF:
@@ -1102,10 +1105,26 @@ bool BufferView::Pimpl::dispatch(FuncReq
 		}
 
 		// Set the cursor
-		bv_->setCursor(par, 0);
+		bv_->setCursor(makeDocIterator(par, 0));
 
 		update();
 		switchKeyMap();
+		break;
+	}
+
+	case LFUN_GOTOERROR:
+		bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false);
+		break;
+
+	case LFUN_GOTONOTE:
+		bv_funcs::gotoInset(bv_, InsetBase::NOTE_CODE, false);
+		break;
+
+	case LFUN_REFERENCE_GOTO: {
+		vector<InsetBase_code> tmp;
+		tmp.push_back(InsetBase::LABEL_CODE);
+		tmp.push_back(InsetBase::REF_CODE);
+		bv_funcs::gotoInset(bv_, tmp, true);
 		break;
 	}
 
Index: src/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v
retrieving revision 1.2120
diff -u -p -r1.2120 ChangeLog
--- src/ChangeLog	14 Feb 2005 08:24:16 -0000	1.2120
+++ src/ChangeLog	14 Feb 2005 11:23:08 -0000
@@ -1,3 +1,23 @@
+2005-02-14  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
+	* BufferView.C (setCursor): change to use a DocIterator.
+	(gotoLabel): use BufferView::setCursor (other part of bug 781).
+	(putSelectionAt): adapt to BufferView::setCursor change.
+
+	* bufferview_funcs.C (gotoNextInset, gotoInset): new functions,
+	moved here from LyXText and rewritten to use proper cursor
+	methods. Fixes bug 1787, 616 and 835.
+
+	* BufferView_pimpl.C (restorePosition): set the cursor correctly
+	when inside an inset (part of bug 781).
+	(dispatch): adapt to change of BufferView::setCursor.
+	(getStatus, dispatch): handle LFUN_GOTOERROR,
+	LFUN_GOTONOTE and LFUN_REFERENCE_GOTO.
+
+	* text3.C (getStatus, dispatch): do not handle LFUN_GOTOERROR,
+	LFUN_GOTONOTE and LFUN_REFERENCE_GOTO.
+	* text3.C (gotoNextInset, gotoInset): removed.
+
 2005-02-14  Jürgen Spitzmüller  <[EMAIL PROTECTED]>
 
 	* BufferView_pimpl.C: revert accidental commit.
Index: src/bufferview_funcs.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferview_funcs.C,v
retrieving revision 1.148
diff -u -p -r1.148 bufferview_funcs.C
--- src/bufferview_funcs.C	8 Feb 2005 13:17:57 -0000	1.148
+++ src/bufferview_funcs.C	14 Feb 2005 11:23:08 -0000
@@ -33,6 +33,7 @@
 #include "frontends/Alert.h"
 #include "frontends/LyXView.h"
 
+#include "insets/insetcommand.h"
 #include "insets/insettext.h"
 
 #include "support/convert.h"
@@ -44,6 +45,7 @@ using lyx::support::bformat;
 using std::istringstream;
 using std::ostringstream;
 using std::string;
+using std::vector;
 
 
 namespace bv_funcs {
@@ -204,6 +206,67 @@ CurStatus status(BufferView const * bv, 
 		return CUR_ABOVE;
 	else
 		return CUR_BELOW;
+}
+
+namespace {
+
+bool gotoNextInset(LCursor & cur,
+		   vector<InsetBase_code> const & codes, 
+		   string const & contents)
+{
+	LCursor tmpcur = cur;
+	
+	while (tmpcur) {
+		InsetBase const * inset = tmpcur.nextInset();
+		if (inset 
+		    && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() 
+		    && (contents.empty() ||
+			static_cast<InsetCommand const *>(inset)->getContents() == contents)) {
+			cur = tmpcur;
+			return true;
+		}
+		tmpcur.forwardInset();
+	}
+
+	return false;
+}
+
+}
+
+
+void gotoInset(BufferView * bv, vector<InsetBase_code> const & codes, 
+	       bool same_content)
+{
+	string contents;
+	LCursor tmpcur = bv->cursor();
+	tmpcur.forwardInset();
+
+	if (same_content) {
+		InsetBase const * inset = tmpcur.nextInset();
+		if (inset 
+		    && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end()) {
+			contents = static_cast<InsetCommand const *>(inset)->getContents();
+		}
+	}
+
+	if (!gotoNextInset(tmpcur, codes, contents)) {
+		if (tmpcur != doc_iterator_begin(tmpcur.inset())) {
+			tmpcur.reset(tmpcur.bottom().inset());
+			if (!gotoNextInset(tmpcur, codes, contents)) 
+				bv->cursor().message(_("No more insets"));
+		} else {
+			bv->cursor().message(_("No more insets"));
+		}
+	}
+	
+	tmpcur.clearSelection();
+	bv->setCursor(tmpcur);
+}
+
+
+void gotoInset(BufferView * bv, InsetBase_code code, bool same_content)
+{
+	gotoInset(bv, vector<InsetBase_code>(1, code), same_content);
 }
 
 
Index: src/bufferview_funcs.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferview_funcs.h,v
retrieving revision 1.34
diff -u -p -r1.34 bufferview_funcs.h
--- src/bufferview_funcs.h	30 Nov 2004 01:59:32 -0000	1.34
+++ src/bufferview_funcs.h	14 Feb 2005 11:23:08 -0000
@@ -15,11 +15,13 @@
 #define BUFFERVIEW_FUNCS_H
 
 #include <string>
+#include <vector>
 
 class LyXFont;
 class Point;
 class DocIterator;
 class BufferView;
+class InsetBase_code;
 
 
 namespace bv_funcs {
@@ -48,6 +50,13 @@ CurStatus status(BufferView const * bv, 
 
 
 Point coordOffset(DocIterator const & dit);
+
+// Moves cursor to the next inset with one of the given codes.
+void gotoInset(BufferView * bv, std::vector<InsetBase_code> const & codes, 
+	       bool same_content);
+
+// Moves cursor to the next inset with given code.
+void gotoInset(BufferView * bv, InsetBase_code code, bool same_content);
 
 
 } // namespace bv_funcs
Index: src/lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.318
diff -u -p -r1.318 lyxtext.h
--- src/lyxtext.h	8 Feb 2005 02:06:35 -0000	1.318
+++ src/lyxtext.h	14 Feb 2005 11:23:08 -0000
@@ -255,16 +255,6 @@ public:
 	/// needed to insert the selection
 	void insertStringAsParagraphs(LCursor & cur, std::string const & str);
 
-	/// Find next inset of some specified type.
-	bool gotoNextInset(LCursor & cur,
-		std::vector<InsetBase_code> const & codes,
-		std::string const & contents = std::string());
-	///
-	void gotoInset(LCursor & cur,
-		std::vector<InsetBase_code> const & codes, bool same_content);
-	///
-	void gotoInset(LCursor & cur, InsetBase_code code, bool same_content);
-
 	/// current text width
 	int width() const;
 
Index: src/text3.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v
retrieving revision 1.283
diff -u -p -r1.283 text3.C
--- src/text3.C	8 Feb 2005 13:18:02 -0000	1.283
+++ src/text3.C	14 Feb 2005 11:23:08 -0000
@@ -74,10 +74,8 @@ using lyx::support::isStrUnsignedInt;
 using lyx::support::token;
 
 using std::endl;
-using std::find;
 using std::string;
 using std::istringstream;
-using std::vector;
 
 
 extern string current_layout;
@@ -181,77 +179,6 @@ string const freefont2string()
 
 }
 
-bool LyXText::gotoNextInset(LCursor & cur,
-	vector<InsetBase_code> const & codes, string const & contents)
-{
-	BOOST_ASSERT(this == cur.text());
-	pit_type end = paragraphs().size();
-	pit_type pit = cur.pit();
-	pos_type pos = cur.pos();
-
-	InsetBase * inset;
-	do {
-		if (pos + 1 < pars_[pit].size()) {
-			++pos;
-		} else  {
-			++pit;
-			pos = 0;
-		}
-
-	} while (pit != end &&
-		 !(pars_[pit].isInset(pos) &&
-		   (inset = pars_[pit].getInset(pos)) != 0 &&
-		   find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() &&
-		   (contents.empty() ||
-		    static_cast<InsetCommand *>(pars_[pit].getInset(pos))->getContents()
-		    == contents)));
-
-	if (pit == end)
-		return false;
-
-	setCursor(cur, pit, pos, false);
-	return true;
-}
-
-
-void LyXText::gotoInset(LCursor & cur,
-	vector<InsetBase_code> const & codes, bool same_content)
-{
-	cur.clearSelection();
-
-	string contents;
-	if (same_content
-	    && cur.pos() < cur.lastpos()
-	    && cur.paragraph().isInset(cur.pos())) {
-		InsetBase const * inset = cur.paragraph().getInset(cur.pos());
-		if (find(codes.begin(), codes.end(), inset->lyxCode())
-		    != codes.end())
-			contents = static_cast<InsetCommand const *>(inset)->getContents();
-	}
-
-	if (!gotoNextInset(cur, codes, contents)) {
-		if (cur.pos() || cur.pit() != 0) {
-			CursorSlice tmp = cur.top();
-			cur.pit() = 0;
-			cur.pos() = 0;
-			if (!gotoNextInset(cur, codes, contents)) {
-				cur.top() = tmp;
-				cur.message(_("No more insets"));
-			}
-		} else {
-			cur.message(_("No more insets"));
-		}
-	}
-	cur.resetAnchor();
-}
-
-
-void LyXText::gotoInset(LCursor & cur, InsetBase_code code, bool same_content)
-{
-	gotoInset(cur, vector<InsetBase_code>(1, code), same_content);
-}
-
-
 bool LyXText::cursorPrevious(LCursor & cur)
 {
 	pos_type cpos = cur.pos();
@@ -997,22 +924,6 @@ void LyXText::dispatch(LCursor & cur, Fu
 		break;
 	}
 
-	case LFUN_GOTOERROR:
-		gotoInset(cur, InsetBase::ERROR_CODE, false);
-		break;
-
-	case LFUN_GOTONOTE:
-		gotoInset(cur, InsetBase::NOTE_CODE, false);
-		break;
-
-	case LFUN_REFERENCE_GOTO: {
-		vector<InsetBase_code> tmp;
-		tmp.push_back(InsetBase::LABEL_CODE);
-		tmp.push_back(InsetBase::REF_CODE);
-		gotoInset(cur, tmp, true);
-		break;
-	}
-
 	case LFUN_QUOTE: {
 		lyx::cap::replaceSelection(cur);
 		Paragraph & par = cur.paragraph();
@@ -1887,9 +1798,6 @@ bool LyXText::getStatus(LCursor & cur, F
 	case LFUN_GETLAYOUT:
 	case LFUN_LAYOUT:
 	case LFUN_PASTESELECTION:
-	case LFUN_GOTOERROR:
-	case LFUN_GOTONOTE:
-	case LFUN_REFERENCE_GOTO:
 	case LFUN_DATE_INSERT:
 	case LFUN_SELFINSERT:
 	case LFUN_INSERT_LABEL:

Reply via email to