Dear all,

This is a complete patch for the view-source feature I proposed.

What does it do?
1. add menu item 'view->view source'
2. when view->view source is selected, a dialog is open with source
code of current or selected paragraphs
3. If this dialog is open, source code of mouse selected text will be
displayed automatically.

Why do I implement it?
1. Make lyx a great tool to learn latex. (I do not know any other
program does this.)
2. Easy debugging of latex errors (we can not really avoid them)
3. Help writing ERT intensive lyx files such as beamer presentations
4. Help developers produce nicer-looking source output

Implementation:
1. change output_latex.C, output_docbook.C and output_latex.C to get
partial output
2. class outputparam is added three members: par_begin, par_end and
dryrun. The last one is set to avoid lyx from copying files and
converting images during view-source
3. LFUN_MOUSE_RELEASE and LFUN_DIALOG_SHOW handlers are modified
4. getSourceCode(ostream, start, end) is added to Buffer class.

Note:
1. source code for the *whole* paragraphs will be displayed, not only
selected text.
2. source code for the rest of the environment will also be displayed,
and give a complete begin/end environment, if only, for example, one
list item is chosen.
3. this patch uses a less intrusive way to get output than my last
patch, which stops output right at the ending paragraph. I chose the
current approach for its simplicity.

Todo:
1. I only have access to qt2, so I implement only the qt2 dialog. qt4
dialog can be added later, may be with the new syntax highlightinh
feature.
2. Trigger update with more selection event?

Testing:
tested under both linux and windows, works well so far.

Please test it and tell me what you think.

Cheers,
Bo
Index: src/insets/insetgraphics.C
===================================================================
--- src/insets/insetgraphics.C	(revision 13548)
+++ src/insets/insetgraphics.C	(working copy)
@@ -559,6 +559,10 @@
 	string const orig_file = params().filename.absFilename();
 	string const rel_file = params().filename.relFilename(buf.filePath());
 
+	// previewing source code, no file copying or file format conversion 
+	if (runparams.dryrun)
+		return stripExtensionIfPossible(rel_file);
+
 	// If the file is compressed and we have specified that it
 	// should not be uncompressed, then just return its name and
 	// let LaTeX do the rest!
Index: src/buffer.C
===================================================================
--- src/buffer.C	(revision 13548)
+++ src/buffer.C	(working copy)
@@ -64,6 +64,7 @@
 
 #include "graphics/Previews.h"
 
+#include "support/types.h"
 #include "support/lyxalgo.h"
 #include "support/filetools.h"
 #include "support/fs_extras.h"
@@ -1576,3 +1577,38 @@
 	}
 }
 
+void Buffer::getSourceCode(ostream& os, lyx::pit_type par_begin, lyx::pit_type par_end)
+{
+	OutputParams runparams;
+	runparams.nice = true;
+	runparams.flavor = OutputParams::LATEX;
+	runparams.linelen = lyxrc.ascii_linelen;
+	runparams.par_begin = par_begin;
+	runparams.par_end = par_end;
+	// No side effect of file copying and image conversion
+	runparams.dryrun = true;
+
+	// set source type for the view-source dialog
+	if (isLatex())
+		os << "%LaTeX\n";
+	else if (isLinuxDoc())
+		os << "%LinuxDoc\n";
+	else if (isDocBook())
+		os << "%DocBook\n";
+	else
+		BOOST_ASSERT(false);
+	// start text
+	if (par_begin + 1 == par_end)
+		os << "% Preview source code for paragraph " << par_begin << "\n\n";
+	else
+		os << "% Preview source code from paragraph " << par_begin << " to " << par_end - 1 << "\n\n";
+	// output paragraphs
+	if (isLatex()) {
+		texrow().reset();
+		latexParagraphs(*this, paragraphs(), os, texrow(), runparams);
+	} else if (isLinuxDoc())
+		linuxdocParagraphs(*this, paragraphs(), os, runparams);
+	else // DocBook
+		docbookParagraphs(paragraphs(), *this, os, runparams);
+}
+
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C	(revision 13548)
+++ src/lyxfunc.C	(working copy)
@@ -129,6 +129,7 @@
 using std::pair;
 using std::string;
 using std::istringstream;
+using std::ostringstream;
 
 namespace biblio = lyx::biblio;
 namespace fs = boost::filesystem;
@@ -520,6 +521,8 @@
 #endif
 		else if (name == "vclog")
 			enable = buf->lyxvc().inUse();
+		else if (name == "view-source")
+			enable = buf;
 		break;
 	}
 
@@ -1172,6 +1175,25 @@
 					owner->buffer()->lyxvc().getLogFile();
 				owner->getDialogs().show("log", data);
 			}
+			else if (name == "view-source") {
+				// get the *top* level paragraphs that contain the cursor, 
+				// or the selected text
+				lyx::pit_type par_begin;
+				lyx::pit_type par_end;
+				if (!view()->cursor().selection()) {
+					par_begin = view()->cursor().bottom().pit();
+					par_end = par_begin;
+				} else {
+					par_begin = view()->cursor().selectionBegin().bottom().pit();
+					par_end = view()->cursor().selectionEnd().bottom().pit();
+				}
+				if (par_begin > par_end)
+					std::swap(par_begin, par_end);
+				ostringstream ostr;
+				view()->buffer()->getSourceCode(ostr, par_begin, par_end + 1);
+				// display the dialog and show source code
+				owner->getDialogs().show("view-source", ostr.str());
+			}
 			else
 				owner->getDialogs().show(name, data);
 			break;
Index: src/buffer.h
===================================================================
--- src/buffer.h	(revision 13548)
+++ src/buffer.h	(working copy)
@@ -333,6 +333,8 @@
 	StableDocIterator getAnchor() const { return anchor_; }
 	///
 	void changeRefsIfUnique(std::string const & from, std::string const & to);
+	/// get source code (latex/docbook/linuxdoc) for some paragraphs
+	void getSourceCode(std::ostream & os, lyx::pit_type par_begin, lyx::pit_type par_end);
 
 private:
 	/** Inserts a file into a document
Index: src/frontends/qt2/QViewSourceDialog.h
===================================================================
--- src/frontends/qt2/QViewSourceDialog.h	(revision 0)
+++ src/frontends/qt2/QViewSourceDialog.h	(revision 0)
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+/**
+ * \file QViewSourceDialog.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef QVIEWSOURCEDIALOG_H
+#define QVIEWSOURCEDIALOG_H
+
+#include "ui/QViewSourceDialogBase.h"
+
+namespace lyx {
+namespace frontend {
+
+class QViewSource;
+
+class QViewSourceDialog : public QViewSourceDialogBase {
+	Q_OBJECT
+public:
+	QViewSourceDialog(QViewSource * form);
+protected:
+	virtual void closeEvent(QCloseEvent * e);
+private:
+	QViewSource * form_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // QVIEWSOURCEDIALOG_H
Index: src/frontends/qt2/Makefile.dialogs
===================================================================
--- src/frontends/qt2/Makefile.dialogs	(revision 13548)
+++ src/frontends/qt2/Makefile.dialogs	(working copy)
@@ -33,6 +33,7 @@
 	QIncludeDialogBase.ui \
 	QIndexDialogBase.ui \
 	QLogDialogBase.ui \
+	QViewSourceDialogBase.ui \
 	QMathDialogBase.ui \
 	QMathMatrixDialogBase.ui \
 	QNoteDialogBase.ui \
@@ -100,6 +101,7 @@
 	QIncludeDialog.C QIncludeDialog.h \
 	QIndexDialog.C QIndexDialog.h \
 	QLogDialog.C QLogDialog.h \
+	QViewSourceDialog.C QViewSourceDialog.h \
 	QLPopupMenu.C QLPopupMenu.h \
 	QLPrintDialog.C QLPrintDialog.h \
 	QMathDialog.C QMathDialog.h \
Index: src/frontends/qt2/Makefile.am
===================================================================
--- src/frontends/qt2/Makefile.am	(revision 13548)
+++ src/frontends/qt2/Makefile.am	(working copy)
@@ -49,6 +49,7 @@
 	QIndex.C QIndex.h \
 	QLImage.C QLImage.h \
 	QLog.C QLog.h \
+	QViewSource.C QViewSource.h \
 	QLPainter.C QLPainter.h \
 	QLyXKeySym.C QLyXKeySym.h \
 	QMath.C QMath.h \
Index: src/frontends/qt2/ui/QViewSourceDialogBase.ui
===================================================================
--- src/frontends/qt2/ui/QViewSourceDialogBase.ui	(revision 0)
+++ src/frontends/qt2/ui/QViewSourceDialogBase.ui	(revision 0)
@@ -0,0 +1,99 @@
+<!DOCTYPE UI><UI>
+<class>QViewSourceDialogBase</class>
+<include location="global">config.h</include>
+<include location="local">qt_helpers.h</include>
+<widget>
+    <class>QDialog</class>
+    <property stdset="1">
+        <name>name</name>
+        <cstring>QViewSourceDialogBase</cstring>
+    </property>
+    <property stdset="1">
+        <name>geometry</name>
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>420</width>
+            <height>328</height>
+        </rect>
+    </property>
+    <property stdset="1">
+        <name>caption</name>
+        <string></string>
+    </property>
+    <property stdset="1">
+        <name>sizeGripEnabled</name>
+        <bool>true</bool>
+    </property>
+    <vbox>
+        <property stdset="1">
+            <name>margin</name>
+            <number>11</number>
+        </property>
+        <property stdset="1">
+            <name>spacing</name>
+            <number>6</number>
+        </property>
+        <widget>
+            <class>QTextEdit</class>
+            <property stdset="1">
+                <name>name</name>
+                <cstring>viewSourceTV</cstring>
+            </property>
+        </widget>
+        <widget>
+            <class>QLayoutWidget</class>
+            <property stdset="1">
+                <name>name</name>
+                <cstring>Layout27</cstring>
+            </property>
+            <hbox>
+                <property stdset="1">
+                    <name>margin</name>
+                    <number>0</number>
+                </property>
+                <property stdset="1">
+                    <name>spacing</name>
+                    <number>6</number>
+                </property>
+                <spacer>
+                    <property>
+                        <name>name</name>
+                        <cstring>Spacer3</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>orientation</name>
+                        <enum>Horizontal</enum>
+                    </property>
+                    <property stdset="1">
+                        <name>sizeType</name>
+                        <enum>Expanding</enum>
+                    </property>
+                    <property>
+                        <name>sizeHint</name>
+                        <size>
+                            <width>20</width>
+                            <height>20</height>
+                        </size>
+                    </property>
+                </spacer>
+                <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>closePB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Close</string>
+                    </property>
+                </widget>
+            </hbox>
+        </widget>
+    </vbox>
+</widget>
+<tabstops>
+    <tabstop>viewSourceTV</tabstop>
+    <tabstop>closePB</tabstop>
+</tabstops>
+</UI>
Index: src/frontends/qt2/QViewSource.C
===================================================================
--- src/frontends/qt2/QViewSource.C	(revision 0)
+++ src/frontends/qt2/QViewSource.C	(revision 0)
@@ -0,0 +1,58 @@
+/**
+ * \file QViewSource.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "QViewSource.h"
+#include "QViewSourceDialog.h"
+#include "qt_helpers.h"
+
+#include "controllers/ControlViewSource.h"
+
+#include <sstream>
+
+#include <qtextview.h>
+#include <qpushbutton.h>
+
+namespace lyx {
+namespace frontend {
+
+typedef QController<ControlViewSource, QView<QViewSourceDialog> > base_class;
+
+QViewSource::QViewSource(Dialog & parent)
+	: base_class(parent, "")
+{}
+
+
+void QViewSource::build_dialog()
+{
+	dialog_.reset(new QViewSourceDialog(this));
+	dialog_->viewSourceTV->setReadOnly(true);
+	dialog_->viewSourceTV->setTextFormat(Qt::PlainText);
+	// this is personal. I think source code should be in fixed-size font
+	QFont font("Courier New");
+	font.setFixedPitch(true);
+	font.setStyleHint(QFont::TypeWriter);
+	dialog_->viewSourceTV->setFont(font);
+	// again, personal taste
+	dialog_->viewSourceTV->setWordWrap(QTextEdit::NoWrap);
+}
+
+
+void QViewSource::update_contents()
+{
+	setTitle(controller().title());
+
+	dialog_->viewSourceTV->setText(toqstr(controller().str()));
+}
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/qt2/QViewSource.h
===================================================================
--- src/frontends/qt2/QViewSource.h	(revision 0)
+++ src/frontends/qt2/QViewSource.h	(revision 0)
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+/**
+ * \file QViewSource.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef QVIEWSOURCE_H
+#define QVIEWSOURCE_H
+
+#include "QDialogView.h"
+
+namespace lyx {
+namespace frontend {
+
+class ControlViewSource;
+class QViewSourceDialog;
+
+///
+class QViewSource
+	: public QController<ControlViewSource, QView<QViewSourceDialog> >
+{
+public:
+	///
+	friend class QViewSourceDialog;
+	///
+	QViewSource(Dialog &);
+private:
+	/// Apply changes
+	virtual void apply() {}
+	/// update
+	virtual void update_contents();
+	/// build the dialog
+	virtual void build_dialog();
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // QVIEWSOURCE_H
Index: src/frontends/qt2/QViewSourceDialog.C
===================================================================
--- src/frontends/qt2/QViewSourceDialog.C	(revision 0)
+++ src/frontends/qt2/QViewSourceDialog.C	(revision 0)
@@ -0,0 +1,40 @@
+/**
+ * \file QViewSourceDialog.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "QViewSourceDialog.h"
+#include "QViewSource.h"
+
+#include <qpushbutton.h>
+
+
+namespace lyx {
+namespace frontend {
+
+QViewSourceDialog::QViewSourceDialog(QViewSource * form)
+	: QViewSourceDialogBase(0, 0, false, 0),
+	form_(form)
+{
+	connect(closePB, SIGNAL(clicked()),
+		form, SLOT(slotClose()));
+}
+
+
+void QViewSourceDialog::closeEvent(QCloseEvent * e)
+{
+	form_->slotWMHide();
+	e->accept();
+}
+
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/qt2/Dialogs.C
===================================================================
--- src/frontends/qt2/Dialogs.C	(revision 13548)
+++ src/frontends/qt2/Dialogs.C	(working copy)
@@ -27,6 +27,7 @@
 #include "ControlGraphics.h"
 #include "ControlInclude.h"
 #include "ControlLog.h"
+#include "ControlViewSource.h"
 #include "ControlMath.h"
 #include "ControlNote.h"
 #include "ControlParagraph.h"
@@ -66,6 +67,7 @@
 #include "QInclude.h"
 #include "QIndex.h"
 #include "QLog.h"
+#include "QViewSource.h"
 #include "QMath.h"
 #include "QNote.h"
 #include "QParagraph.h"
@@ -102,7 +104,7 @@
 char const * const dialognames[] = {
 "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
 "citation", "document", "errorlist", "ert", "external", "file",
-"findreplace", "float", "graphics", "include", "index", "label", "log",
+"findreplace", "float", "graphics", "include", "index", "label", "log", "view-source",
 "mathpanel", "mathdelimiter", "mathmatrix", "note", "paragraph", "preamble",
 "prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate",
 
@@ -242,6 +244,10 @@
 		dialog->setController(new ControlLog(*dialog));
 		dialog->setView(new QLog(*dialog));
 		dialog->bc().bp(new OkCancelPolicy);
+	} else if (name == "view-source") {
+		dialog->setController(new ControlViewSource(*dialog));
+		dialog->setView(new QViewSource(*dialog));
+		dialog->bc().bp(new OkCancelPolicy);
 	} else if (name == "mathpanel") {
 		dialog->setController(new ControlMath(*dialog));
 		dialog->setView(new QMath(*dialog));
Index: src/frontends/controllers/ControlViewSource.C
===================================================================
--- src/frontends/controllers/ControlViewSource.C	(revision 0)
+++ src/frontends/controllers/ControlViewSource.C	(revision 0)
@@ -0,0 +1,66 @@
+/**
+ * \file ControlViewSource.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Angus Leeming
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "ControlViewSource.h"
+#include "gettext.h"
+
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+ControlViewSource::ControlViewSource(Dialog & parent)
+	: Dialog::Controller(parent)
+{}
+
+
+bool ControlViewSource::initialiseParams(string const & source)
+{
+	string sourcetype = source.substr(1, 5);
+	if (sourcetype == "LaTeX") {
+		type_ = LatexSource;
+		source_ = source.substr(7);
+	} else if (sourcetype == "Linux") {
+		type_ = LinuxDocSource;
+		source_ = source.substr(10);
+	} else if (sourcetype == "DocBo") {
+		type_ = DocBookSource;
+		source_ = source.substr(9);
+	} else
+		return false;
+	
+	return true;
+}
+
+
+void ControlViewSource::clearParams()
+{
+	source_.erase();
+}
+
+
+string const ControlViewSource::title() const
+{
+	switch (type_) {
+	case LatexSource:
+		return _("LaTeX Source");
+	case LinuxDocSource:
+		return _("LinuxDoc Source");
+	case DocBookSource:
+		return _("DocBook Source");
+	}
+}
+
+} // namespace frontend
+} // namespace lyx
Index: src/frontends/controllers/ControlViewSource.h
===================================================================
--- src/frontends/controllers/ControlViewSource.h	(revision 0)
+++ src/frontends/controllers/ControlViewSource.h	(revision 0)
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+/**
+ * \file ControlViewSource.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author John Levon
+ * \author Angus Leeming
+ * \Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef CONTROLVIEWSOURCE_H
+#define CONTROLVIEWSOURCE_H
+
+#include "Dialog.h"
+
+namespace lyx {
+namespace frontend {
+
+/**
+ * A controller for a read-only text browser.
+ */
+class ControlViewSource : public Dialog::Controller {
+public:
+	///
+	ControlViewSource(Dialog &);
+	/** \param source source code to be displayed
+	 */
+	virtual bool initialiseParams(std::string const & source);
+	///
+	virtual void clearParams();
+	///
+	virtual void dispatchParams() {}
+	///
+	virtual bool isBufferDependent() const { return true; }
+
+	/// The title displayed by the dialog reflects the \c VIEWSOURCETYPE
+	std::string const title() const;
+
+	/// get the source code
+	std::string const str() const { return source_; }
+	
+private:
+	/// Recognized source code type
+	enum SOURCETYPE {
+		LatexSource,
+		LinuxDocSource,
+		DocBookSource
+	};
+
+	SOURCETYPE type_;
+	std::string source_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // CONTROLVIEWSOURCE_H
Index: src/frontends/controllers/Makefile.am
===================================================================
--- src/frontends/controllers/Makefile.am	(revision 13548)
+++ src/frontends/controllers/Makefile.am	(working copy)
@@ -63,6 +63,8 @@
 	ControlInclude.h \
 	ControlLog.C \
 	ControlLog.h \
+	ControlViewSource.C \
+	ControlViewSource.h \
 	ControlMath.C \
 	ControlMath.h \
 	ControlNote.C \
Index: src/outputparams.C
===================================================================
--- src/outputparams.C	(revision 13548)
+++ src/outputparams.C	(working copy)
@@ -19,7 +19,9 @@
 	  local_font(0), free_spacing(false), use_babel(false),
 	  linelen(0), depth(0),
 	  exportdata(new ExportData),
-	  inComment(false)
+	  inComment(false),
+	  par_begin(0), par_end(0),
+	  dryrun(false)
 {}
 
 
Index: src/text3.C
===================================================================
--- src/text3.C	(revision 13548)
+++ src/text3.C	(working copy)
@@ -81,6 +81,7 @@
 using std::endl;
 using std::string;
 using std::istringstream;
+using std::ostringstream;
 
 
 extern string current_layout;
@@ -1107,6 +1108,21 @@
 		bv->switchKeyMap();
 		bv->owner()->updateMenubar();
 		bv->owner()->updateToolbars();
+
+		// if view-source dialog is visible, send source code of selected
+		// text to the dialog
+		if (cmd.button() == mouse_button::button1 && cur.selection() 
+			&& bv->owner()->getDialogs().visible("view-source")) {
+			// get *top* level paragraphs that contain the selection
+			lyx::pit_type par_begin = bv->cursor().selectionBegin().bottom().pit();
+			lyx::pit_type par_end = bv->cursor().selectionEnd().bottom().pit();
+			if (par_begin > par_end)
+				std::swap(par_begin, par_end);
+			ostringstream ostr;
+			bv->buffer()->getSourceCode(ostr, par_begin, par_end + 1);
+			// display the dialog and show source code
+			bv->owner()->getDialogs().update("view-source", ostr.str());
+		}
 		break;
 	}
 
Index: src/output_linuxdoc.C
===================================================================
--- src/output_linuxdoc.C	(revision 13548)
+++ src/output_linuxdoc.C	(working copy)
@@ -15,6 +15,7 @@
 
 #include "buffer.h"
 #include "bufferparams.h"
+#include "outputparams.h"
 #include "paragraph.h"
 #include "paragraph_funcs.h"
 #include "ParagraphList.h"
@@ -40,6 +41,18 @@
 
 	ParagraphList::const_iterator pit = paragraphs.begin();
 	ParagraphList::const_iterator pend = paragraphs.end();
+	
+	BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
+	// if only part of the paragraphs will be outputed
+	if (runparams.par_begin !=  runparams.par_end) {
+		pit = boost::next(paragraphs.begin(), runparams.par_begin);
+		pend = boost::next(paragraphs.begin(), runparams.par_end);
+		// runparams will be passed to nested paragraphs, so
+		// we have to reset the range parameters.
+		const_cast<OutputParams&>(runparams).par_begin = 0;
+		const_cast<OutputParams&>(runparams).par_end = 0;
+	}
+
 	for (; pit != pend; ++pit) {
 		LyXLayout_ptr const & style = pit->layout();
 		// treat <toc> as a special case for compatibility with old code
Index: src/outputparams.h
===================================================================
--- src/outputparams.h	(revision 13548)
+++ src/outputparams.h	(working copy)
@@ -24,7 +24,6 @@
 
 class OutputParams {
 public:
-	//
 	enum FLAVOR {
 		LATEX,
 		PDFLATEX,
@@ -97,6 +96,22 @@
 	 *  if this flag is true, since they may not exist.
 	 */
 	bool inComment;
+
+	/** allow output of only part of the top-level paragraphs 
+	 *  par_begin: beginning paragraph
+	 */
+	lyx::pit_type par_begin;
+
+	/** allow output of only part of the top-level paragraphs 
+	 *  par_end: par_end-1 is the ending paragraph
+	 *  if par_begin=par_end, output all paragraphs
+	 */
+	lyx::pit_type par_end;
+
+	/** whether or not do actual file copying and image conversion 
+	 *  This mode will be used to preview the source code
+	 */
+	bool dryrun;
 };
 
 #endif // NOT OUTPUTPARAMS_H
Index: src/output_docbook.C
===================================================================
--- src/output_docbook.C	(revision 13548)
+++ src/output_docbook.C	(working copy)
@@ -16,6 +16,7 @@
 #include "buffer.h"
 #include "buffer_funcs.h"
 #include "bufferparams.h"
+#include "outputparams.h"
 #include "counters.h"
 #include "debug.h"
 #include "paragraph.h"
@@ -285,8 +286,20 @@
 	ParagraphList::const_iterator par = paragraphs.begin();
 	ParagraphList::const_iterator pend = paragraphs.end();
 
+	BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
+	// if only part of the paragraphs will be outputed
+	if (runparams.par_begin !=  runparams.par_end) {
+		par = boost::next(paragraphs.begin(), runparams.par_begin);
+		pend = boost::next(paragraphs.begin(), runparams.par_end);
+		// runparams will be passed to nested paragraphs, so
+		// we have to reset the range parameters.
+		const_cast<OutputParams&>(runparams).par_begin = 0;
+		const_cast<OutputParams&>(runparams).par_end = 0;
+	}
+	
 	while (par != pend) {
 		LyXLayout_ptr const & style = par->layout();
+		ParagraphList::const_iterator lastpar = par;
 		ParagraphList::const_iterator send;
 
 		switch (style->latextype) {
@@ -308,5 +321,8 @@
 		default:
 			break;
 		}
+		// makeEnvironment may process more than one paragraphs and bypass pend
+		if (std::distance(lastpar, par) >= std::distance(lastpar, pend))
+			break;
 	}
 }
Index: src/output_latex.C
===================================================================
--- src/output_latex.C	(revision 13548)
+++ src/output_latex.C	(working copy)
@@ -463,8 +463,20 @@
 	ParagraphList::const_iterator par = paragraphs.begin();
 	ParagraphList::const_iterator endpar = paragraphs.end();
 
+	BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
+	// if only part of the paragraphs will be outputed
+	if (runparams.par_begin !=  runparams.par_end) {
+		par = boost::next(paragraphs.begin(), runparams.par_begin);
+		endpar = boost::next(paragraphs.begin(), runparams.par_end);
+		// runparams will be passed to nested paragraphs, so
+		// we have to reset the range parameters.
+		const_cast<OutputParams&>(runparams).par_begin = 0;
+		const_cast<OutputParams&>(runparams).par_end = 0;
+	}
+
 	// if only_body
 	while (par != endpar) {
+		ParagraphList::const_iterator lastpar = par;
 		// well we have to check if we are in an inset with unlimited
 		// length (all in one row) if that is true then we don't allow
 		// any special options in the paragraph and also we don't allow
@@ -516,6 +528,8 @@
 			par = TeXOnePar(buf, paragraphs, par, os, texrow,
 			                runparams, everypar);
 		}
+		if (std::distance(lastpar, par) >= std::distance(lastpar, endpar))
+			break;
 	}
 	// It might be that we only have a title in this document
 	if (was_title && !already_title) {
Index: lib/ui/stdmenus.ui
===================================================================
--- lib/ui/stdmenus.ui	(revision 13548)
+++ lib/ui/stdmenus.ui	(working copy)
@@ -217,6 +217,7 @@
 #	Item "Close All Footnotes|C" "close-footnotes"
 		Item "Display Tooltips|i" "toggle-tooltips"
 		Separator
+		Item "View source|s" "dialog-show view-source"
 		Submenu "Update|U" "document_update"
 		ViewFormats
 		Separator
Index: po/POTFILES.in
===================================================================
--- po/POTFILES.in	(revision 13548)
+++ po/POTFILES.in	(working copy)
@@ -30,6 +30,7 @@
 src/frontends/controllers/ControlPrint.C
 src/frontends/controllers/ControlSpellchecker.C
 src/frontends/controllers/ControlToc.C
+src/frontends/controllers/ControlViewSource.C
 src/frontends/controllers/biblio.C
 src/frontends/controllers/character.C
 src/frontends/controllers/frnt_lang.C

Reply via email to