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