The following short patch is a links the source view window with the work
area: now when navigating with the cursor the line of the latex source
which should contain the corresponding position of the cursor position is
selected.

The patch includes an orthogonal simplification to rowlist (for the same
price).

This is probably 1.5.x stuff at minimum, but I'd appreciate comments very
much nevertheless...

I have in mind several ways of enhancing this stuff: 

- the reverse lookup source-> text (easy)
- more fine-grained control than latex lines (harder but a cool project IMO,
I think I have good ideas about it)
- search in the source window (easy)

A/

Index: frontends/controllers/ControlViewSource.h
===================================================================
--- frontends/controllers/ControlViewSource.h	(revision 18837)
+++ frontends/controllers/ControlViewSource.h	(working copy)
@@ -45,6 +45,9 @@
 		\param fullSource get full source code
 	 */
 	docstring const updateContent(bool fullSource);
+	/** get the cursor position in the source code
+	 */
+	int getRow() const;
 };
 
 } // namespace frontend
Index: frontends/controllers/ControlViewSource.cpp
===================================================================
--- frontends/controllers/ControlViewSource.cpp	(revision 18837)
+++ frontends/controllers/ControlViewSource.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "BufferView.h"
 #include "Buffer.h"
 #include "Cursor.h"
+#include "TexRow.h"
 #include <sstream>
 
 using std::string;
@@ -58,6 +59,15 @@
 }
 
 
+int ControlViewSource::getRow() const
+{
+	BufferView const * view = kernel().bufferview();
+	return view->buffer()->texrow().
+		getRowFromIdPos(view->cursor().bottom().paragraph().id(),
+				view->cursor().bottom().pos());
+}
+
+
 void ControlViewSource::clearParams()
 {
 }
Index: frontends/qt4/QViewSource.cpp
===================================================================
--- frontends/qt4/QViewSource.cpp	(revision 18837)
+++ frontends/qt4/QViewSource.cpp	(working copy)
@@ -61,6 +61,11 @@
 	if (autoUpdateCB->isChecked())
 		form_->update(viewFullSourceCB->isChecked());
 
+	int row = form_->getRow();
+	QTextCursor c = QTextCursor(viewSourceTV->document());
+	c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, row);
+	c.select(QTextCursor::BlockUnderCursor);
+	viewSourceTV->setTextCursor(c);
 	QWidget::update();
 }
 
Index: TexRow.h
===================================================================
--- TexRow.h	(revision 18837)
+++ TexRow.h	(working copy)
@@ -24,10 +24,8 @@
 class TexRow {
 public:
 	///
-	TexRow() : count(0), lastid(-1), lastpos(-1) {}
+	TexRow() : lastid(-1), lastpos(-1) {}
 
-	TexRow & operator+= (TexRow const &);
-
 	/// Clears structure
 	void reset();
 
@@ -49,14 +47,22 @@
 	 */
 	bool getIdFromRow(int row, int & id, int & pos) const;
 
+	/**
+	 * getIdFromRow - find row containing a given id and pos
+	 * @param id of the paragraph
+	 * @param pos a given position in that paragraph
+	 * @return the row number within the rowlist
+	 */
+	int getRowFromIdPos(int id, int pos) const;
+	
 	/// Returns the number of rows contained
-	int rows() const { return count; }
+	int rows() const { return rowlist.size(); }
 
 	/// an individual id/pos <=> row mapping
 	class RowItem {
 	public:
-		RowItem(int id, int pos, int row)
-			: id_(id), pos_(pos), rownumber_(row)
+		RowItem(int id, int pos)
+			: id_(id), pos_(pos)
 		{}
 
 		/// paragraph id
@@ -74,21 +80,14 @@
 			return pos_;
 		}
 
-		/// row number
-		int rownumber() const {
-			return rownumber_;
-		}
 	private:
 		RowItem();
 		int id_;
 		int pos_;
-		int rownumber_;
 	};
 	///
-	typedef std::list<RowItem> RowList;
+	typedef std::vector<RowItem> RowList;
 private:
-	/// number of lines
-	unsigned int count;
 	/// container of id/pos <=> row mapping
 	RowList rowlist;
 	/// Last paragraph
Index: TexRow.cpp
===================================================================
--- TexRow.cpp	(revision 18837)
+++ TexRow.cpp	(working copy)
@@ -20,30 +20,10 @@
 
 namespace lyx {
 
-using std::find_if;
 
-
-namespace {
-
-/// function object returning true when row number is found
-class same_rownumber {
-public:
-	same_rownumber(int row) : row_(row) {}
-	bool operator()(TexRow::RowList::value_type const & vt) const {
-		return vt.rownumber() == row_;
-	}
-
-private:
-	int row_;
-};
-
-} // namespace anon
-
-
 void TexRow::reset()
 {
 	rowlist.clear();
-	count = 0;
 	lastid = -1;
 	lastpos = -1;
 }
@@ -59,32 +39,41 @@
 void TexRow::newline()
 {
 	int const id = lastid;
-	RowList::value_type tmp(id, lastpos, ++count);
+	RowList::value_type tmp(id, lastpos);
 	rowlist.push_back(tmp);
 }
 
 
 bool TexRow::getIdFromRow(int row, int & id, int & pos) const
 {
-	RowList::const_iterator cit =
-		find_if(rowlist.begin(), rowlist.end(),
-			same_rownumber(row));
-
-	if (cit != rowlist.end()) {
-		id = cit->id();
-		pos = cit->pos();
-		return true;
+	if (row > rowlist.size()) {
+		id = -1;
+		pos = 0;
+		return false;
 	}
-	id = -1;
-	pos = 0;
-	return false;
+
+	id = rowlist[row].id();
+	pos = rowlist[row].pos();
+	return true;
 }
 
 
-TexRow & TexRow::operator+=(TexRow const & tr)
+int TexRow::getRowFromIdPos(int id, int pos) const
 {
-	rowlist.insert(rowlist.end(), tr.rowlist.begin(), tr.rowlist.end());
-	return *this;
+	int bestrow = 0;
+	bool foundid = false;
+
+	// this loop finds the last *nonempty* row whith the same id
+	// and position <= pos
+	for (int r = 0, n = rowlist.size(); r != n; ++r) {
+		if (rowlist[r].id() == id && rowlist[r].pos() <= pos) {
+			foundid = true;
+			if (rowlist[bestrow].id() != id || rowlist[r].pos() > rowlist[bestrow].pos())
+				bestrow = r;
+		} else if (foundid)
+			break;
+	}
+	return bestrow;
 }
 
 
Index: Buffer.cpp
===================================================================
--- Buffer.cpp	(revision 18837)
+++ Buffer.cpp	(working copy)
@@ -942,8 +942,6 @@
 	validate(features);
 	LYXERR(Debug::LATEX) << "  Buffer validation done." << endl;
 
-	texrow().reset();
-
 	// The starting paragraph of the coming rows is the
 	// first paragraph of the document. (Asger)
 	texrow().start(paragraphs().begin()->id(), 0);
@@ -1746,8 +1744,11 @@
 	// No side effect of file copying and image conversion
 	runparams.dryrun = true;
 
+	texrow().reset();
 	if (full_source) {
 		os << "% " << _("Preview source code") << "\n\n";
+		texrow().newline();
+		texrow().newline();
 		if (isLatex())
 			writeLaTeXSource(os, filePath(), runparams, true, true);
 		else {
@@ -1766,9 +1767,10 @@
 					convert<docstring>(par_begin),
 					convert<docstring>(par_end - 1))
 			   << "\n\n";
+		texrow().newline();
+		texrow().newline();
 		// output paragraphs
 		if (isLatex()) {
-			texrow().reset();
 			latexParagraphs(*this, paragraphs(), os, texrow(), runparams);
 		} else {
 			// DocBook

Reply via email to