Am Freitag, 10. November 2006 21:14 schrieb Abdelrazak Younes:
> Georg Baum wrote:
> > Why was it not possible to extend the classes in toc.h with the new
> > functionality?
> 
> Because there was no class in toc.h, only global functions that were 
> called each time the navigate menu or an item of Toc dialog was clicked.

Wrong, the TocItem class was in toc.h.

>   The Toc list was recreated on each update of the menu or the Toc 
> dialog and that was slow on windows. Thanks to the TocBackend you now 
> have synchronised Toc dialog and document contents. Try it.

That is nice, and I did not question that.

> toc.h is just there to keep the interface with MenuBackend. I didn't 
> feel like cleaning this at the time. I may have cleaned up ControlToc at 
> the time, I don't remember.
> 
> Now, it you tell me that you prefer 1.4 toc.h over 1.5 TocBackend I 
> don't understand anything.

No, you misunderstood me. I do not question at all your new code, but I do 
question how it is organized. I do not understand why you needed to move 
TocItem inside the class TocBackend, that makes it impossible to forward 
declare it.
I do neither understand why TocBackend is not in namespace toc.
I do neither understand why you define several types in TocBackend that 
then get typedefed again in toc. If I use that code, when should I use 
toc::TocItem, and when TocBackend::Item?

Basically the relationship between src/toc.[Ch] and src/TocBackend.[Ch] is 
unclear to me. In order to demonstrate what I mean I changed my patch so 
that everything is now in one file. The code did not change at all, I only 
moved stuff around so that I could break up the circular include loop. I 
prefer one file, because all this code belongs together IMO, but one could 
as well do it in two files and only do the namespace/class reorganizations 
and move TocItem back to toc.[Ch].

> The TocBackend as well as the different updateLabels() functions should 
> disappear once we tracks labels correctly on paragraph 
> creation/deletion. I have planned to do that when I get some time.

That will probably have to wait :-(


Georg
Index: src/buffer_funcs.h
===================================================================
--- src/buffer_funcs.h	(Revision 15835)
+++ src/buffer_funcs.h	(Arbeitskopie)
@@ -58,17 +58,17 @@ lyx::docstring expandLabel(Buffer const 
 /**
 A full updateLabels(Buffer const &) will be called if not possible.
 */
-void updateLabels(Buffer const & buf, ParIterator & it);
+void updateLabels(Buffer const & buf, ParIterator & it, bool childonly = false);
 
 /// update labels between "from" and "to" if possible.
 /**
 A full updateLabels(Buffer const &) will be called if not possible.
 */
 void updateLabels(Buffer const & buf,
-	ParIterator & from, ParIterator & to);
+	ParIterator & from, ParIterator & to, bool childonly = false);
 
 /// updates all counters
-void updateLabels(Buffer const &);
+void updateLabels(Buffer const &, bool childonly = false);
 
 
 } // namespace lyx
Index: src/insets/insetfloat.C
===================================================================
--- src/insets/insetfloat.C	(Revision 15835)
+++ src/insets/insetfloat.C	(Arbeitskopie)
@@ -29,7 +29,7 @@
 #include "lyxlex.h"
 #include "outputparams.h"
 #include "paragraph.h"
-#include "pariterator.h"
+#include "toc.h"
 
 #include "support/lstrings.h"
 #include "support/convert.h"
Index: src/insets/insetbase.h
===================================================================
--- src/insets/insetbase.h	(Revision 15835)
+++ src/insets/insetbase.h	(Arbeitskopie)
@@ -39,6 +39,7 @@ class OutputParams;
 
 
 namespace graphics { class PreviewLoader; }
+namespace toc { class TocList; }
 
 
 /// Common base class to all insets
@@ -381,6 +382,8 @@ public:
 	 *  defaults to empty.
 	 */
 	virtual void addPreview(graphics::PreviewLoader &) const {}
+	/// Add an antry to the TocList
+	virtual void addToToc(toc::TocList &, Buffer const &) const {}
 
 public:
 	/// returns LyX code associated with the inset. Used for TOC, ...)
Index: src/insets/insetinclude.h
===================================================================
--- src/insets/insetinclude.h	(Revision 15835)
+++ src/insets/insetinclude.h	(Arbeitskopie)
@@ -92,6 +92,10 @@ public:
 	///
 	void addPreview(graphics::PreviewLoader &) const;
 	///
+	void addToToc(toc::TocList &, Buffer const &) const;
+	///
+	void updateLabels(Buffer const & buffer) const;
+	///
 	bool getStatus(LCursor &, FuncRequest const &, FuncStatus &) const;
 protected:
 	InsetInclude(InsetInclude const &);
Index: src/insets/insetwrap.C
===================================================================
--- src/insets/insetwrap.C	(Revision 15835)
+++ src/insets/insetwrap.C	(Arbeitskopie)
@@ -28,7 +28,7 @@
 #include "lyxlex.h"
 #include "outputparams.h"
 #include "paragraph.h"
-#include "pariterator.h"
+#include "toc.h"
 
 #include "support/convert.h"
 
Index: src/insets/insetfloat.h
===================================================================
--- src/insets/insetfloat.h	(Revision 15835)
+++ src/insets/insetfloat.h	(Arbeitskopie)
@@ -14,7 +14,6 @@
 #define INSETFLOAT_H
 
 #include "insetcollapsable.h"
-#include "toc.h"
 #include "mailinset.h"
 
 
Index: src/insets/insetwrap.h
===================================================================
--- src/insets/insetwrap.h	(Revision 15835)
+++ src/insets/insetwrap.h	(Arbeitskopie)
@@ -13,7 +13,6 @@
 #define INSETWRAP_H
 
 #include "insetcollapsable.h"
-#include "toc.h"
 #include "lyxlength.h"
 #include "mailinset.h"
 
Index: src/insets/insetinclude.C
===================================================================
--- src/insets/insetinclude.C	(Revision 15835)
+++ src/insets/insetinclude.C	(Arbeitskopie)
@@ -30,6 +30,7 @@
 #include "lyxlex.h"
 #include "metricsinfo.h"
 #include "outputparams.h"
+#include "toc.h"
 
 #include "frontends/Alert.h"
 #include "frontends/Painter.h"
@@ -772,6 +773,33 @@ void InsetInclude::addPreview(graphics::
 }
 
 
+void InsetInclude::addToToc(toc::TocList & toclist, Buffer const & buffer) const
+{
+	if (!loadIfNeeded(buffer, params_))
+		return;
+
+	string const included_file = includedFilename(buffer, params_);
+	Buffer const * const childbuffer = theBufferList().getBuffer(included_file);
+	toc::TocList const childtoclist = toc::getTocList(*childbuffer);
+	toc::TocList::const_iterator it = childtoclist.begin();
+	toc::TocList::const_iterator const end = childtoclist.end();
+	for(; it != end; ++it)
+		toclist[it->first].insert(toclist[it->first].end(),
+				it->second.begin(), it->second.end());
+}
+
+
+void InsetInclude::updateLabels(Buffer const & buffer) const
+{
+	if (!loadIfNeeded(buffer, params_))
+		return;
+
+	string const included_file = includedFilename(buffer, params_);
+	Buffer const * const childbuffer = theBufferList().getBuffer(included_file);
+	lyx::updateLabels(*childbuffer, true);
+}
+
+
 string const InsetIncludeMailer::name_("include");
 
 InsetIncludeMailer::InsetIncludeMailer(InsetInclude & inset)
Index: src/insets/insettoc.C
===================================================================
--- src/insets/insettoc.C	(Revision 15835)
+++ src/insets/insettoc.C	(Arbeitskopie)
@@ -18,8 +18,6 @@
 #include "metricsinfo.h"
 #include "toc.h"
 
-#include "support/std_ostream.h"
-
 
 namespace lyx {
 
Index: src/TocBackend.C
===================================================================
--- src/TocBackend.C	(Revision 15835)
+++ src/TocBackend.C	(Arbeitskopie)
@@ -1,257 +0,0 @@
-/**
- * \file TocBackend.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Jean-Marc Lasgouttes
- * \author Angus Leeming
- * \author Abdelrazak Younes
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "toc.h"
-
-#include "buffer.h"
-#include "bufferparams.h"
-#include "FloatList.h"
-#include "funcrequest.h"
-#include "LyXAction.h"
-#include "paragraph.h"
-#include "cursor.h"
-#include "debug.h"
-
-#include "frontends/LyXView.h"
-
-#include "insets/insetfloat.h"
-#include "insets/insetoptarg.h"
-#include "insets/insetwrap.h"
-
-#include "support/convert.h"
-
-#include <iostream>
-
-namespace lyx {
-
-using std::vector;
-using std::max;
-using std::ostream;
-using std::string;
-using std::endl;
-
-
-///////////////////////////////////////////////////////////////////////////
-// TocBackend::Item implementation
-
-TocBackend::Item::Item(ParConstIterator const & par_it, int d,
-		docstring const & s)
-		: par_it_(par_it), depth_(d), str_(s)
-{
-/*
-	if (!uid_.empty())
-		return;
-
-	size_t pos = s.find(" ");
-	if (pos == string::npos) {
-		// Non labelled item
-		uid_ = s;
-		return;
-	}
-
-	string s2 = s.substr(0, pos);
-
-	if (s2 == "Chapter" || s2 == "Part") {
-		size_t pos2 = s.find(" ", pos + 1);
-		if (pos2 == string::npos) {
-			// Unnumbered Chapter?? This should not happen.
-			uid_ = s.substr(pos + 1);
-			return;
-		}
-		// Chapter or Part
-		uid_ = s.substr(pos2 + 1);
-		return;
-	}
-	// Numbered Item.
-	uid_ = s.substr(pos + 1);
-	*/
-}
-
-bool const TocBackend::Item::isValid() const
-{
-	return depth_ != -1;
-}
-
-
-int const TocBackend::Item::id() const
-{
-	return par_it_->id();
-}
-
-
-int const TocBackend::Item::depth() const
-{
-	return depth_;
-}
-
-
-docstring const & TocBackend::Item::str() const
-{
-	return str_;
-}
-
-
-docstring const TocBackend::Item::asString() const
-{
-	return docstring(4 * depth_, ' ') + str_;
-}
-
-
-void TocBackend::Item::goTo(LyXView & lv_) const
-{
-	string const tmp = convert<string>(id());
-	lv_.dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, tmp));
-}
-
-FuncRequest TocBackend::Item::action() const
-{
-	return FuncRequest(LFUN_PARAGRAPH_GOTO, convert<string>(id()));
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// TocBackend implementation
-
-TocBackend::Toc const & TocBackend::toc(std::string const & type)
-{
-	// Is the type already supported?
-	TocList::const_iterator it = tocs_.find(type);
-	BOOST_ASSERT(it != tocs_.end());
-
-	return it->second;
-}
-
-
-bool TocBackend::addType(std::string const & type)
-{
-	// Is the type already supported?
-	TocList::iterator toclist_it = tocs_.find(type);
-	if (toclist_it != tocs_.end())
-		return false;
-
-	tocs_.insert(make_pair(type, Toc()));
-	types_.push_back(type);
-
-	return true;
-}
-
-
-void TocBackend::update()
-{
-	tocs_.clear();
-	types_.clear();
-
-	BufferParams const & bufparams = buffer_->params();
-	const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
-
-	ParConstIterator pit = buffer_->par_iterator_begin();
-	ParConstIterator end = buffer_->par_iterator_end();
-	for (; pit != end; ++pit) {
-
-		// the string that goes to the toc (could be the optarg)
-		docstring tocstring;
-
-		// For each paragraph, traverse its insets and look for
-		// FLOAT_CODE or WRAP_CODE
-		InsetList::const_iterator it = pit->insetlist.begin();
-		InsetList::const_iterator end = pit->insetlist.end();
-		for (; it != end; ++it) {
-			switch (it->inset->lyxCode()) {
-			case InsetBase::FLOAT_CODE:
-				static_cast<InsetFloat*>(it->inset)
-					->addToToc(tocs_, *buffer_);
-				break;
-			case InsetBase::WRAP_CODE:
-				static_cast<InsetWrap*>(it->inset)
-					->addToToc(tocs_, *buffer_);
-				break;
-			case InsetBase::OPTARG_CODE: {
-				if (!tocstring.empty())
-					break;
-				Paragraph const & par = *static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();
-				if (!pit->getLabelstring().empty())
-					tocstring = pit->getLabelstring() + ' ';
-				tocstring += par.asString(*buffer_, false);
-				break;
-			}
-			default:
-				break;
-			}
-		}
-
-		/// now the toc entry for the paragraph
-		int const toclevel = pit->layout()->toclevel;
-		if (toclevel != LyXLayout::NOT_IN_TOC
-		    && toclevel >= min_toclevel
-		    && toclevel <= bufparams.tocdepth) {
-			// insert this into the table of contents
-			if (tocstring.empty())
-				tocstring = pit->asString(*buffer_, true);
-			Item const item(pit, toclevel - min_toclevel, tocstring);
-			tocs_["TOC"].push_back(item);
-		}
-	}
-
-	TocList::iterator it = tocs_.begin();
-	for (; it != tocs_.end(); ++it)
-		types_.push_back(it->first);
-}
-
-
-TocBackend::TocIterator const TocBackend::item(std::string const & type, ParConstIterator const & par_it)
-{
-	TocList::iterator toclist_it = tocs_.find(type);
-	// Is the type supported?
-	BOOST_ASSERT(toclist_it != tocs_.end());
-
-	Toc const & toc_vector = toclist_it->second;
-	TocBackend::TocIterator last = toc_vector.begin();
-	TocBackend::TocIterator it = toc_vector.end();
-	--it;
-
-	for (; it != last; --it) {
-		
-		// A good solution for Items inside insets would be to do:
-		//
-		//if (std::distance(it->par_it_, current) <= 0)
-		//	return it;
-		//
-		// But for an unknown reason, std::distance(current, it->par_it_) always
-		// returns  a positive value and std::distance(it->par_it_, current) takes forever...
-		// So for now, we do:
-		if (it->par_it_.pit() <= par_it.pit())
-			return it;
-	}
-
-	// We are before the first Toc Item:
-	return last;
-}
-
-
-void TocBackend::asciiTocList(string const & type, odocstream & os) const
-{
-	TocList::const_iterator cit = tocs_.find(type);
-	if (cit != tocs_.end()) {
-		Toc::const_iterator ccit = cit->second.begin();
-		Toc::const_iterator end = cit->second.end();
-		for (; ccit != end; ++ccit)
-			os << ccit->asString() << '\n';
-	}
-}
-
-
-} // namespace lyx
Index: src/frontends/qt4/TocModel.C
===================================================================
--- src/frontends/qt4/TocModel.C	(Revision 15835)
+++ src/frontends/qt4/TocModel.C	(Arbeitskopie)
@@ -29,13 +29,13 @@ namespace lyx {
 namespace frontend {
 
 
-TocModel::TocModel(TocBackend::Toc const & toc)
+TocModel::TocModel(toc::Toc const & toc)
 {
 	populate(toc);
 }
 
 
-TocModel const & TocModel::operator=(TocBackend::Toc const & toc)
+TocModel const & TocModel::operator=(toc::Toc const & toc)
 {
 	populate(toc);
 	return *this;
@@ -72,7 +72,7 @@ void TocModel::clear()
 }
 
 
-void TocModel::populate(TocBackend::Toc const & toc)
+void TocModel::populate(toc::Toc const & toc)
 {
 	clear();
 
Index: src/frontends/qt4/TocModel.h
===================================================================
--- src/frontends/qt4/TocModel.h	(Revision 15835)
+++ src/frontends/qt4/TocModel.h	(Arbeitskopie)
@@ -12,19 +12,16 @@
 #ifndef TOCMODEL_H
 #define TOCMODEL_H
 
-#include "TocBackend.h"
+#include "toc.h"
 
 #include "qt_helpers.h"
 
 #include <QStandardItemModel>
 
-#include <map>
-#include <string>
-
 namespace lyx {
 namespace frontend {
 
-typedef TocBackend::Toc::const_iterator TocIterator;
+typedef lyx::toc::TocIterator TocIterator;
 
 class TocModel: public QStandardItemModel {
 	Q_OBJECT
@@ -33,15 +30,15 @@ public:
 	///
 	TocModel() {}
 	///
-	TocModel(TocBackend::Toc const & toc);
+	TocModel(toc::Toc const & toc);
 	///
 	~TocModel() {}
 	///
-	TocModel const & operator=(TocBackend::Toc const & toc);
+	TocModel const & operator=(toc::Toc const & toc);
 	///
 	void clear();
 	///
-	void populate(TocBackend::Toc const & toc);
+	void populate(toc::Toc const & toc);
 	///
 	TocIterator const tocIterator(QModelIndex const & index) const;
 	///
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(Revision 15835)
+++ src/Makefile.am	(Arbeitskopie)
@@ -261,8 +261,6 @@ lyx_SOURCES = \
 	text.C \
 	text2.C \
 	text3.C \
-	TocBackend.C \
-	TocBackend.h \
 	toc.C \
 	toc.h \
 	trans.C \
Index: src/TocBackend.h
===================================================================
--- src/TocBackend.h	(Revision 15835)
+++ src/TocBackend.h	(Arbeitskopie)
@@ -1,139 +0,0 @@
-// -*- C++ -*-
-/**
- * \file TocBackend.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Jean-Marc Lasgouttes
- * \author Angus Leeming
- * \author Abdelrazak Younes
- *
- * Full author contact details are available in file CREDITS.
- *
- * TocBackend mainly used in toc.[Ch]
- */
-
-#ifndef TOC_BACKEND_H
-#define TOC_BACKEND_H
-
-#include <map>
-#include <iosfwd>
-#include <vector>
-#include <string>
-
-#include "pariterator.h"
-
-namespace lyx {
-
-class Buffer;
-class LyXView;
-class Paragraph;
-class FuncRequest;
-class LCursor;
-
-///
-/**
-*/
-class TocBackend
-{
-public:
-	///
-	/**
-	*/
-	class Item
-	{
-		friend class TocBackend;
-		friend bool operator==(Item const & a, Item const & b);
-
-	public:
-		///
-		Item(
-			ParConstIterator const & par_it = ParConstIterator(),
-			int d = -1,
-			docstring const & s = docstring());
-		///
-		~Item() {}
-		///
-		bool const isValid() const;
-		///
-		int const id() const;
-		///
-		int const depth() const;
-		///
-		docstring const & str() const;
-		///
-		docstring const asString() const;
-		/// set cursor in LyXView to this Item
-		void goTo(LyXView & lv_) const;
-		/// the action corresponding to the goTo above
-		FuncRequest action() const;
-		
-	protected:
-		/// Current position of item.
-		ParConstIterator par_it_;
-
-		/// nesting depth
-		int depth_;
-
-		/// Full item string
-		docstring str_;
-	};
-
-	///
-	typedef std::vector<Item> Toc;
-	typedef std::vector<Item>::const_iterator TocIterator;
-	///
-	typedef std::map<std::string, Toc> TocList;
-
-public:
-	///
-	TocBackend(Buffer const * buffer = NULL): buffer_(buffer) {}
-	///
-	~TocBackend() {}
-	///
-	void setBuffer(Buffer const * buffer)
-	{ buffer_ = buffer; }
-	///
-	bool addType(std::string const & type);
-	///
-	void update();
-	///
-	TocList const & tocs()
-	{ return tocs_; }
-	///
-	std::vector<std::string> const & types()
-	{ return types_; }
-	///
-	Toc const & toc(std::string const & type);
-	/// Return the first Toc Item before the cursor
-	TocIterator const item(std::string const & type, ParConstIterator const &);
-
-	void asciiTocList(std::string const & type, odocstream & os) const;
-
-private:
-	/// 
-	TocList tocs_;
-	///
-	std::vector<std::string> types_;
-	///
-	Buffer const * buffer_;
-
-}; // TocBackend
-
-inline
-bool operator==(TocBackend::Item const & a, TocBackend::Item const & b)
-{
-	return a.id() == b.id() && a.str() == b.str() && a.depth() == b.depth();
-}
-
-
-inline
-bool operator!=(TocBackend::Item const & a, TocBackend::Item const & b)
-{
-	return !(a == b);
-}
-
-
-} // namespace lyx
-
-#endif // TOC_BACKEND_H
Index: src/BufferView.C
===================================================================
--- src/BufferView.C	(Revision 15835)
+++ src/BufferView.C	(Arbeitskopie)
@@ -727,21 +727,32 @@ bool BufferView::dispatch(FuncRequest co
 
 	case LFUN_PARAGRAPH_GOTO: {
 		int const id = convert<int>(to_utf8(cmd.argument()));
-		ParIterator par = buffer_->getParFromID(id);
-		if (par == buffer_->par_iterator_end()) {
-			lyxerr[Debug::INFO] << "No matching paragraph found! ["
-					    << id << ']' << endl;
-			break;
-		} else {
-			lyxerr[Debug::INFO] << "Paragraph " << par->id()
-					    << " found." << endl;
+		int i = 0;
+		for (Buffer * b = buffer_; i == 0 || b != buffer_; b = theBufferList().next(b)) {
+			ParIterator par = b->getParFromID(id);
+			if (par == b->par_iterator_end()) {
+				lyxerr[Debug::INFO]
+					<< "No matching paragraph found! ["
+					<< id << "'], buffer `"
+					<< b->fileName() << "'." << endl;
+			} else {
+				lyxerr[Debug::INFO]
+					<< "Paragraph " << par->id()
+					<< " found in buffer `"
+					<< b->fileName() << "'." << endl;
+
+				if (b != buffer_)
+					setBuffer(b);
+
+				// Set the cursor
+				setCursor(makeDocIterator(par, 0));
+
+				update();
+				switchKeyMap();
+				break;
+			}
+			++i;
 		}
-
-		// Set the cursor
-		setCursor(makeDocIterator(par, 0));
-
-		update();
-		switchKeyMap();
 		break;
 	}
 
Index: src/MenuBackend.C
===================================================================
--- src/MenuBackend.C	(Revision 15835)
+++ src/MenuBackend.C	(Arbeitskopie)
@@ -35,6 +35,8 @@
 #include "lyx_main.h" // for lastfiles
 #include "lyxfunc.h"
 #include "lyxlex.h"
+#include "paragraph.h"
+#include "pariterator.h"
 #include "toc.h"
 #include "ToolbarBackend.h"
 
@@ -704,6 +706,15 @@ void expandToc(Menu & tomenu, Buffer con
 		return;
 	}
 
+	// Add an entry for the master doc if this is a child doc
+	Buffer const * const master = buf->getMasterBuffer();
+	if (buf != master) {
+		ParIterator const pit = par_iterator_begin(master->inset());
+		string const arg = convert<string>(pit->id());
+		FuncRequest f(LFUN_PARAGRAPH_GOTO, arg);
+		tomenu.add(MenuItem(MenuItem::Command, _("Master Document"), f));
+	}
+
 	FloatList const & floatlist = buf->params().getLyXTextClass().floats();
 	lyx::toc::TocList const & toc_list = lyx::toc::getTocList(*buf);
 	lyx::toc::TocList::const_iterator cit = toc_list.begin();
Index: src/toc.C
===================================================================
--- src/toc.C	(Revision 15835)
+++ src/toc.C	(Arbeitskopie)
@@ -26,6 +26,10 @@
 #include "debug.h"
 #include "undo.h"
 
+#include "frontends/LyXView.h"
+
+#include "insets/insetoptarg.h"
+
 #include "support/convert.h"
 
 #include <map>
@@ -45,6 +49,209 @@ namespace toc {
 typedef map<Buffer const *, TocBackend> TocMap;
 static TocMap toc_backend_;
 
+
+///////////////////////////////////////////////////////////////////////////
+// TocItem implementation
+
+TocItem::TocItem(ParConstIterator const & par_it, int d,
+		docstring const & s)
+		: par_it_(par_it), depth_(d), str_(s)
+{
+/*
+	if (!uid_.empty())
+		return;
+
+	size_t pos = s.find(" ");
+	if (pos == string::npos) {
+		// Non labelled item
+		uid_ = s;
+		return;
+	}
+
+	string s2 = s.substr(0, pos);
+
+	if (s2 == "Chapter" || s2 == "Part") {
+		size_t pos2 = s.find(" ", pos + 1);
+		if (pos2 == string::npos) {
+			// Unnumbered Chapter?? This should not happen.
+			uid_ = s.substr(pos + 1);
+			return;
+		}
+		// Chapter or Part
+		uid_ = s.substr(pos2 + 1);
+		return;
+	}
+	// Numbered Item.
+	uid_ = s.substr(pos + 1);
+	*/
+}
+
+bool const TocItem::isValid() const
+{
+	return depth_ != -1;
+}
+
+
+int const TocItem::id() const
+{
+	return par_it_->id();
+}
+
+
+int const TocItem::depth() const
+{
+	return depth_;
+}
+
+
+docstring const & TocItem::str() const
+{
+	return str_;
+}
+
+
+docstring const TocItem::asString() const
+{
+	return docstring(4 * depth_, ' ') + str_;
+}
+
+
+void TocItem::goTo(LyXView & lv_) const
+{
+	string const tmp = convert<string>(id());
+	lv_.dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, tmp));
+}
+
+FuncRequest TocItem::action() const
+{
+	return FuncRequest(LFUN_PARAGRAPH_GOTO, convert<string>(id()));
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// TocBackend implementation
+
+Toc const & TocBackend::toc(std::string const & type)
+{
+	// Is the type already supported?
+	TocList::const_iterator it = tocs_.find(type);
+	BOOST_ASSERT(it != tocs_.end());
+
+	return it->second;
+}
+
+
+bool TocBackend::addType(std::string const & type)
+{
+	// Is the type already supported?
+	TocList::iterator toclist_it = tocs_.find(type);
+	if (toclist_it != tocs_.end())
+		return false;
+
+	tocs_.insert(make_pair(type, Toc()));
+	types_.push_back(type);
+
+	return true;
+}
+
+
+void TocBackend::update()
+{
+	tocs_.clear();
+	types_.clear();
+
+	BufferParams const & bufparams = buffer_->params();
+	const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
+
+	ParConstIterator pit = buffer_->par_iterator_begin();
+	ParConstIterator end = buffer_->par_iterator_end();
+	for (; pit != end; ++pit) {
+
+		// the string that goes to the toc (could be the optarg)
+		docstring tocstring;
+
+		// For each paragraph, traverse its insets and let them add
+		// their toc items.
+		InsetList::const_iterator it = pit->insetlist.begin();
+		InsetList::const_iterator end = pit->insetlist.end();
+		for (; it != end; ++it) {
+			it->inset->addToToc(tocs_, *buffer_);
+			switch (it->inset->lyxCode()) {
+			case InsetBase::OPTARG_CODE: {
+				if (!tocstring.empty())
+					break;
+				Paragraph const & par = *static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();
+				if (!pit->getLabelstring().empty())
+					tocstring = pit->getLabelstring() + ' ';
+				tocstring += par.asString(*buffer_, false);
+				break;
+			}
+			default:
+				break;
+			}
+		}
+
+		/// now the toc entry for the paragraph
+		int const toclevel = pit->layout()->toclevel;
+		if (toclevel != LyXLayout::NOT_IN_TOC
+		    && toclevel >= min_toclevel
+		    && toclevel <= bufparams.tocdepth) {
+			// insert this into the table of contents
+			if (tocstring.empty())
+				tocstring = pit->asString(*buffer_, true);
+			TocItem const item(pit, toclevel - min_toclevel, tocstring);
+			tocs_["TOC"].push_back(item);
+		}
+	}
+
+	TocList::iterator it = tocs_.begin();
+	for (; it != tocs_.end(); ++it)
+		types_.push_back(it->first);
+}
+
+
+TocIterator const TocBackend::item(std::string const & type, ParConstIterator const & par_it)
+{
+	TocList::iterator toclist_it = tocs_.find(type);
+	// Is the type supported?
+	BOOST_ASSERT(toclist_it != tocs_.end());
+
+	Toc const & toc_vector = toclist_it->second;
+	TocIterator last = toc_vector.begin();
+	TocIterator it = toc_vector.end();
+	--it;
+
+	for (; it != last; --it) {
+		
+		// A good solution for Items inside insets would be to do:
+		//
+		//if (std::distance(it->par_it_, current) <= 0)
+		//	return it;
+		//
+		// But for an unknown reason, std::distance(current, it->par_it_) always
+		// returns  a positive value and std::distance(it->par_it_, current) takes forever...
+		// So for now, we do:
+		if (it->par_it_.pit() <= par_it.pit())
+			return it;
+	}
+
+	// We are before the first Toc Item:
+	return last;
+}
+
+
+void TocBackend::asciiTocList(string const & type, odocstream & os) const
+{
+	TocList::const_iterator cit = tocs_.find(type);
+	if (cit != tocs_.end()) {
+		Toc::const_iterator ccit = cit->second.begin();
+		Toc::const_iterator end = cit->second.end();
+		for (; ccit != end; ++ccit)
+			os << ccit->asString() << '\n';
+	}
+}
+
+
 ///////////////////////////////////////////////////////////////////////////
 // Interface to toc_backend_
 
@@ -94,6 +301,7 @@ void asciiTocList(string const & type, B
 	toc_backend_[&buf].asciiTocList(type, os);
 }
 
+
 ///////////////////////////////////////////////////////////////////////////
 // Other functions
 
Index: src/buffer_funcs.C
===================================================================
--- src/buffer_funcs.C	(Revision 15835)
+++ src/buffer_funcs.C	(Arbeitskopie)
@@ -38,6 +38,7 @@
 #include "frontends/Alert.h"
 
 #include "insets/insetbibitem.h"
+#include "insets/insetinclude.h"
 
 #include "support/filetools.h"
 #include "support/fs_extras.h"
@@ -349,11 +350,9 @@ bool needEnumCounterReset(ParIterator co
 
 
 // set the label of a paragraph. This includes the counters.
-void setLabel(Buffer const & buf, ParIterator & it)
+void setLabel(Buffer const & buf, ParIterator & it, LyXTextClass const & textclass)
 {
 	Paragraph & par = *it;
-	BufferParams const & bufparams = buf.params();
-	LyXTextClass const & textclass = bufparams.getLyXTextClass();
 	LyXLayout_ptr const & layout = par.layout();
 	Counters & counters = textclass.counters();
 
@@ -395,7 +394,7 @@ void setLabel(Buffer const & buf, ParIte
 		// At some point of time we should do something more
 		// clever here, like:
 		//   par.params().labelString(
-		//    bufparams.user_defined_bullet(par.itemdepth).getText());
+		//    buf.params().user_defined_bullet(par.itemdepth).getText());
 		// for now, use a simple hardcoded label
 		docstring itemlabel;
 		switch (par.itemdepth) {
@@ -528,7 +527,7 @@ bool updateCurrentLabel(Buffer const & b
 	case LABEL_CENTERED_TOP_ENVIRONMENT:
 	case LABEL_STATIC:
 	case LABEL_ITEMIZE:
-		setLabel(buf, it);
+		setLabel(buf, it, buf.params().getLyXTextClass());
 		return true;
 
 	case LABEL_SENSITIVE:
@@ -544,33 +543,44 @@ bool updateCurrentLabel(Buffer const & b
 
 
 void updateLabels(Buffer const & buf,
-	ParIterator & from, ParIterator & to)
+	ParIterator & from, ParIterator & to, bool childonly)
 {
 	for (ParIterator it = from; it != to; ++it) {
 		if (it.pit() > it.lastpit())
 			return;
 		if (!updateCurrentLabel (buf, it)) {
-			updateLabels(buf);
+			updateLabels(buf, childonly);
 			return;
 		}
 	}
 }
 
 
-void updateLabels(Buffer const & buf,
-	ParIterator & iter)
+void updateLabels(Buffer const & buf, ParIterator & iter, bool childonly)
 {
 	if (updateCurrentLabel(buf, iter))
 		return;
 
-	updateLabels(buf);
+	updateLabels(buf, childonly);
 }
 
 
-void updateLabels(Buffer const & buf)
+void updateLabels(Buffer const & buf, bool childonly)
 {
-	// start over the counters
-	buf.params().getLyXTextClass().counters().reset();
+	// Use the master text class also for child documents
+	LyXTextClass const & textclass = buf.params().getLyXTextClass();
+
+	if (!childonly) {
+		// If this is a child document start with the master
+		Buffer const * const master = buf.getMasterBuffer();
+		if (master != &buf) {
+			updateLabels(*master);
+			return;
+		}
+
+		// start over the counters
+		textclass.counters().reset();
+	}
 
 	ParIterator const end = par_iterator_end(buf.inset());
 
@@ -584,7 +594,16 @@ void updateLabels(Buffer const & buf)
 			it->params().depth(0);
 
 		// set the counter for this paragraph
-		setLabel(buf, it);
+		setLabel(buf, it, textclass);
+
+		// Now included docs
+		InsetList::const_iterator iit = it->insetlist.begin();
+		InsetList::const_iterator end = it->insetlist.end();
+		for (; iit != end; ++iit) {
+			if (iit->inset->lyxCode() == InsetBase::INCLUDE_CODE)
+				static_cast<InsetInclude const *>(iit->inset)
+					->updateLabels(buf);
+		}
 	}
 
 	toc::updateToc(buf);
Index: src/toc.h
===================================================================
--- src/toc.h	(Revision 15835)
+++ src/toc.h	(Arbeitskopie)
@@ -6,6 +6,7 @@
  *
  * \author Jean-Marc Lasgouttes
  * \author Angus Leeming
+ * \author Abdelrazak Younes
  *
  * Full author contact details are available in file CREDITS.
  *
@@ -15,17 +16,116 @@
 #ifndef TOC_H
 #define TOC_H
 
-#include "TocBackend.h"
+#include <map>
+#include <iosfwd>
+#include <vector>
 
-class LCursor;
+#include "pariterator.h"
 
 namespace lyx {
+
+class Buffer;
+class LyXView;
+class Paragraph;
+class FuncRequest;
+class LCursor;
+
 namespace toc {
 
-typedef TocBackend::Item TocItem;
-typedef TocBackend::Toc::const_iterator TocIterator;
-typedef TocBackend::Toc Toc;
-typedef TocBackend::TocList TocList;
+///
+/**
+*/
+class TocItem
+{
+	friend class TocBackend;
+
+public:
+	///
+	TocItem(ParConstIterator const & par_it = ParConstIterator(),
+		int d = -1,
+		docstring const & s = docstring());
+	///
+	~TocItem() {}
+	///
+	bool const isValid() const;
+	///
+	int const id() const;
+	///
+	int const depth() const;
+	///
+	docstring const & str() const;
+	///
+	docstring const asString() const;
+	/// set cursor in LyXView to this TocItem
+	void goTo(LyXView & lv_) const;
+	/// the action corresponding to the goTo above
+	FuncRequest action() const;
+	
+protected:
+	/// Current position of item.
+	ParConstIterator par_it_;
+
+	/// nesting depth
+	int depth_;
+
+	/// Full item string
+	docstring str_;
+};
+
+
+///
+typedef std::vector<TocItem> Toc;
+///
+typedef std::vector<TocItem>::const_iterator TocIterator;
+
+
+/// The ToC list.
+/// A class and no typedef because we want to forward declare it.
+class TocList : public std::map<std::string, Toc>
+{
+};
+
+
+///
+/**
+*/
+class TocBackend
+{
+public:
+	///
+	TocBackend(Buffer const * buffer = NULL): buffer_(buffer) {}
+	///
+	~TocBackend() {}
+	///
+	void setBuffer(Buffer const * buffer)
+	{ buffer_ = buffer; }
+	///
+	bool addType(std::string const & type);
+	///
+	void update();
+	///
+	TocList const & tocs()
+	{ return tocs_; }
+	///
+	std::vector<std::string> const & types()
+	{ return types_; }
+	///
+	Toc const & toc(std::string const & type);
+	/// Return the first Toc Item before the cursor
+	TocIterator const item(std::string const & type, ParConstIterator const &);
+
+	void asciiTocList(std::string const & type, odocstream & os) const;
+
+private:
+	/// 
+	TocList tocs_;
+	///
+	std::vector<std::string> types_;
+	///
+	Buffer const * buffer_;
+
+}; // TocBackend
+
 
 ///
 void updateToc(Buffer const &);
@@ -69,4 +169,19 @@ void outline(OutlineOp, LCursor &);
 } // namespace toc
 } // namespace lyx
 
-#endif // CONTROLTOC_H
+
+inline
+bool operator==(lyx::toc::TocItem const & a, lyx::toc::TocItem const & b)
+{
+	return a.id() == b.id() && a.str() == b.str() && a.depth() == b.depth();
+}
+
+
+inline
+bool operator!=(lyx::toc::TocItem const & a, lyx::toc::TocItem const & b)
+{
+	return !(a == b);
+}
+
+
+#endif // TOC_H
Index: development/scons/scons_manifest.py
===================================================================
--- development/scons/scons_manifest.py	(Revision 15835)
+++ development/scons/scons_manifest.py	(Arbeitskopie)
@@ -1055,7 +1055,6 @@ src_header_files = Split('''
     Spacing.h
     SpellBase.h
     Thesaurus.h
-    TocBackend.h
     ToolbarBackend.h
     Variables.h
     WordLangTuple.h
@@ -1169,7 +1168,6 @@ src_pre_files = Split('''
     MenuBackend.C
     ParagraphParameters.C
     Spacing.C
-    TocBackend.C
     ToolbarBackend.C
     author.C
     boost.C

Reply via email to