Better construction of the TOC for floats and captions

We introduce TocBuilder for building TOCs that take into account both float
insets and their captions.

* Floats without caption are shown with their content.

* Floats with a caption are shown with their caption, but clicking the entry now
  correctly moves to the float and not to the caption.

* Subsequent captions produce additional entries in the TOC.

* Figures and subfigures are correctly ordered in the outliner.

* New TOC "senseless" for captions appearing alone (a bit like broken references
are still displayed in the menu and outliner).

* Disable LFUN_CAPTION_INSERT if there is already a caption in a listing

Known issues:

* Inconsistent output for includes located inside floats

* We should record the end of the float in addition of the beginning for a more
  accurate cursor -> outliner entry conversion
This commit is contained in:
Guillaume Munch 2015-09-01 17:08:35 +01:00
parent c02f6bd8a7
commit 94e992c5ed
28 changed files with 397 additions and 238 deletions

View File

@ -1005,9 +1005,9 @@ void BiblioInfo::collectCitedEntries(Buffer const & buf)
// FIXME We may want to collect these differently, in the first case,
// so that we might have them in order of appearance.
set<docstring> citekeys;
Toc const & toc = buf.tocBackend().toc("citation");
Toc::const_iterator it = toc.begin();
Toc::const_iterator const en = toc.end();
shared_ptr<Toc const> toc = buf.tocBackend().toc("citation");
Toc::const_iterator it = toc->begin();
Toc::const_iterator const en = toc->end();
for (; it != en; ++it) {
if (it->str().empty())
continue;

View File

@ -2163,9 +2163,9 @@ void Buffer::getLabelList(vector<docstring> & list) const
}
list.clear();
Toc & toc = d->toc_backend.toc("label");
TocIterator toc_it = toc.begin();
TocIterator end = toc.end();
shared_ptr<Toc> toc = d->toc_backend.toc("label");
TocIterator toc_it = toc->begin();
TocIterator end = toc->end();
for (; toc_it != end; ++toc_it) {
if (toc_it->depth() == 0)
list.push_back(toc_it->str());
@ -4461,6 +4461,7 @@ void Buffer::updateBuffer(UpdateScope scope, UpdateType utype) const
d->bibinfo_cache_valid_ = true;
d->cite_labels_valid_ = true;
/// FIXME: Perf
cbuf.tocBackend().update(utype == OutputUpdate);
if (scope == UpdateMaster)
cbuf.structureChanged();

View File

@ -2429,9 +2429,9 @@ void BufferView::gotoLabel(docstring const & label)
Buffer const * buf = *it;
// find label
Toc & toc = buf->tocBackend().toc("label");
TocIterator toc_it = toc.begin();
TocIterator end = toc.end();
shared_ptr<Toc> toc = buf->tocBackend().toc("label");
TocIterator toc_it = toc->begin();
TocIterator end = toc->end();
for (; toc_it != end; ++toc_it) {
if (label == toc_it->str()) {
lyx::dispatch(toc_it->action());

View File

@ -474,7 +474,7 @@ void Changes::addToToc(DocIterator const & cdit, Buffer const & buffer,
if (table_.empty())
return;
Toc & change_list = buffer.tocBackend().toc("change");
shared_ptr<Toc> change_list = buffer.tocBackend().toc("change");
AuthorList const & author_list = buffer.params().authors();
DocIterator dit = cdit;
@ -500,18 +500,18 @@ void Changes::addToToc(DocIterator const & cdit, Buffer const & buffer,
// the end of paragraph symbol from the Punctuation group
str.push_back(0x204B);
docstring const & author = author_list.get(it->change.author).name();
Toc::iterator it = change_list.item(0, author);
if (it == change_list.end()) {
change_list.push_back(TocItem(dit, 0, author, output_active));
change_list.push_back(TocItem(dit, 1, str, output_active,
Toc::iterator it = change_list->item(0, author);
if (it == change_list->end()) {
change_list->push_back(TocItem(dit, 0, author, output_active));
change_list->push_back(TocItem(dit, 1, str, output_active,
support::wrapParas(str, 4)));
continue;
}
for (++it; it != change_list.end(); ++it) {
for (++it; it != change_list->end(); ++it) {
if (it->depth() == 0 && it->str() != author)
break;
}
change_list.insert(it, TocItem(dit, 1, str, output_active,
change_list->insert(it, TocItem(dit, 1, str, output_active,
support::wrapParas(str, 4)));
}
}

View File

@ -6,6 +6,7 @@
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author Abdelrazak Younes
* \author Guillaume Munch
*
* Full author contact details are available in file CREDITS.
*/
@ -57,18 +58,6 @@ int TocItem::id() const
}
int TocItem::depth() const
{
return depth_;
}
docstring const & TocItem::str() const
{
return str_;
}
docstring const & TocItem::tooltip() const
{
return tooltip_.empty() ? str_ : tooltip_;
@ -81,12 +70,6 @@ docstring const TocItem::asString() const
}
DocIterator const & TocItem::dit() const
{
return dit_;
}
FuncRequest TocItem::action() const
{
string const arg = convert<string>(dit_.paragraph().id())
@ -97,97 +80,10 @@ FuncRequest TocItem::action() const
///////////////////////////////////////////////////////////////////////////
//
// TocBackend implementation
// Toc implementation
//
///////////////////////////////////////////////////////////////////////////
Toc const & TocBackend::toc(string const & type) const
{
// Is the type already supported?
TocList::const_iterator it = tocs_.find(type);
LASSERT(it != tocs_.end(), { static Toc dummy; return dummy; });
return it->second;
}
Toc & TocBackend::toc(string const & type)
{
return tocs_[type];
}
bool TocBackend::updateItem(DocIterator const & dit)
{
if (dit.text()->getTocLevel(dit.pit()) == Layout::NOT_IN_TOC)
return false;
if (toc("tableofcontents").empty()) {
// FIXME: should not happen,
// a call to TocBackend::update() is missing somewhere
LYXERR0("TocBackend::updateItem called but the TOC is empty!");
return false;
}
BufferParams const & bufparams = buffer_->params();
const int min_toclevel = bufparams.documentClass().min_toclevel();
TocIterator toc_item = item("tableofcontents", dit);
docstring tocstring;
// For each paragraph, traverse its insets and let them add
// their toc items
Paragraph & par = toc_item->dit_.paragraph();
InsetList::const_iterator it = par.insetList().begin();
InsetList::const_iterator end = par.insetList().end();
for (; it != end; ++it) {
Inset & inset = *it->inset;
if (inset.lyxCode() == ARG_CODE) {
if (!tocstring.empty())
break;
Paragraph const & inset_par =
*static_cast<InsetArgument&>(inset).paragraphs().begin();
if (!par.labelString().empty())
tocstring = par.labelString() + ' ';
tocstring += inset_par.asString(AS_STR_INSETS);
break;
}
}
int const toclevel = toc_item->dit_.text()->getTocLevel(toc_item->dit_.pit());
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel
&& tocstring.empty())
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
const_cast<TocItem &>(*toc_item).str_ = tocstring;
buffer_->updateTocItem("tableofcontents", dit);
return true;
}
void TocBackend::update(bool output_active)
{
tocs_.clear();
if (!buffer_->isInternal()) {
DocIterator dit;
buffer_->inset().addToToc(dit, output_active);
}
}
TocIterator TocBackend::item(string const & type,
DocIterator const & dit) const
{
TocList::const_iterator toclist_it = tocs_.find(type);
// Is the type supported?
// We will try to make the best of it in release mode
LASSERT(toclist_it != tocs_.end(), toclist_it = tocs_.begin());
return toclist_it->second.item(dit);
}
TocIterator Toc::item(DocIterator const & dit) const
{
TocIterator last = begin();
@ -233,13 +129,184 @@ Toc::iterator Toc::item(int depth, docstring const & str)
}
///////////////////////////////////////////////////////////////////////////
//
// TocBuilder implementation
//
///////////////////////////////////////////////////////////////////////////
TocBuilder::TocBuilder(shared_ptr<Toc> toc)
: toc_(toc ? toc : make_shared<Toc>()),
stack_()
{
LATTEST(toc);
}
void TocBuilder::pushItem(DocIterator const & dit, docstring const & s,
bool output_active, bool is_captioned)
{
toc_->push_back(TocItem(dit, stack_.size(), s, output_active));
frame f = {
toc_->size() - 1, //pos
is_captioned, //is_captioned
};
stack_.push(f);
}
void TocBuilder::captionItem(DocIterator const & dit, docstring const & s,
bool output_active)
{
if (!stack_.empty() && !stack_.top().is_captioned) {
// The float we entered has not yet been assigned a caption.
// Assign the caption string to it.
(*toc_)[stack_.top().pos].str(s);
stack_.top().is_captioned = true;
} else {
// This is a new entry.
pop();
pushItem(dit, s, output_active, true);
}
}
void TocBuilder::pop()
{
if (!stack_.empty())
stack_.pop();
}
///////////////////////////////////////////////////////////////////////////
//
// TocBuilderStore implementation
//
///////////////////////////////////////////////////////////////////////////
shared_ptr<TocBuilder> TocBuilderStore::get(string const & type,
shared_ptr<Toc> toc)
{
map_t::const_iterator it = map_.find(type);
if (it == map_.end()) {
it = map_.insert(std::make_pair(type,
make_shared<TocBuilder>(toc))).first;
}
return it->second;
}
///////////////////////////////////////////////////////////////////////////
//
// TocBackend implementation
//
///////////////////////////////////////////////////////////////////////////
shared_ptr<Toc const> TocBackend::toc(string const & type) const
{
// Is the type already supported?
TocList::const_iterator it = tocs_.find(type);
LASSERT(it != tocs_.end(), { return make_shared<Toc>(); });
return it->second;
}
shared_ptr<Toc> TocBackend::toc(string const & type)
{
TocList::const_iterator it = tocs_.find(type);
if (it == tocs_.end()) {
it = tocs_.insert(std::make_pair(type, make_shared<Toc>())).first;
}
return it->second;
}
shared_ptr<TocBuilder> TocBackend::builder(string const & type)
{
return builders_.get(type, toc(type));
}
bool TocBackend::updateItem(DocIterator const & dit)
{
if (dit.text()->getTocLevel(dit.pit()) == Layout::NOT_IN_TOC)
return false;
if (toc("tableofcontents")->empty()) {
// FIXME: should not happen,
// a call to TocBackend::update() is missing somewhere
LYXERR0("TocBackend::updateItem called but the TOC is empty!");
return false;
}
BufferParams const & bufparams = buffer_->params();
const int min_toclevel = bufparams.documentClass().min_toclevel();
TocIterator toc_item = item("tableofcontents", dit);
docstring tocstring;
// For each paragraph, traverse its insets and let them add
// their toc items
Paragraph & par = toc_item->dit_.paragraph();
InsetList::const_iterator it = par.insetList().begin();
InsetList::const_iterator end = par.insetList().end();
for (; it != end; ++it) {
Inset & inset = *it->inset;
if (inset.lyxCode() == ARG_CODE) {
if (!tocstring.empty())
break;
Paragraph const & inset_par =
*static_cast<InsetArgument&>(inset).paragraphs().begin();
if (!par.labelString().empty())
tocstring = par.labelString() + ' ';
tocstring += inset_par.asString(AS_STR_INSETS);
break;
}
}
int const toclevel = toc_item->dit_.text()->getTocLevel(toc_item->dit_.pit());
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel
&& tocstring.empty())
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
const_cast<TocItem &>(*toc_item).str_ = tocstring;
buffer_->updateTocItem("tableofcontents", dit);
return true;
}
void TocBackend::update(bool output_active)
{
for (TocList::iterator it = tocs_.begin(); it != tocs_.end(); ++it)
it->second->clear();
tocs_.clear();
builders_.clear();
if (!buffer_->isInternal()) {
DocIterator dit;
buffer_->inset().addToToc(dit, output_active);
}
}
TocIterator TocBackend::item(string const & type,
DocIterator const & dit) const
{
TocList::const_iterator toclist_it = tocs_.find(type);
// Is the type supported?
// We will try to make the best of it in release mode
LASSERT(toclist_it != tocs_.end(), toclist_it = tocs_.begin());
return toclist_it->second->item(dit);
}
void TocBackend::writePlaintextTocList(string const & type,
odocstringstream & os, size_t max_length) const
{
TocList::const_iterator cit = tocs_.find(type);
if (cit != tocs_.end()) {
TocIterator ccit = cit->second.begin();
TocIterator end = cit->second.end();
TocIterator ccit = cit->second->begin();
TocIterator end = cit->second->end();
for (; ccit != end; ++ccit) {
os << ccit->asString() << from_utf8("\n");
if (os.str().size() > max_length)

View File

@ -7,6 +7,7 @@
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author Abdelrazak Younes
* \author Guillaume Munch
*
* Full author contact details are available in file CREDITS.
*/
@ -16,10 +17,12 @@
#include "DocIterator.h"
#include "support/shared_ptr.h"
#include "support/strfwd.h"
#include <map>
#include <vector>
#include <stack>
#include <string>
@ -28,6 +31,34 @@ namespace lyx {
class Buffer;
class FuncRequest;
/* FIXME: toc types are currently identified by strings. It cannot be converted
* into an enum because of the user-configurable indexing categories and
* the user-definable float types provided by layout files.
*
* I leave this for documentation purposes for the moment.
*
enum TocType {
TABLE_OF_CONTENTS,//"tableofcontents"
CHILD,//"child"
GRAPHICS,//"graphics"
NOTE,//"note"
BRANCH,//"branch"
CHANGE,//"change"
LABEL,//"label"
CITATION,//"citation"
EQUATION,//"equation"
FOOTNOTE,//"footnote"
MARGINAL_NOTE,//"marginalnote"
INDEX,//"index", "index:<user-str>" (from interface)
NOMENCL,//"nomencl"
LISTING,//"listings"
FLOAT,//"figure", "table", "algorithm", user-defined (from layout?)
SENSELESS,//"senseless"
TOC_TYPE_COUNT
}
*/
///
/**
*/
@ -51,15 +82,17 @@ public:
///
int id() const;
///
int depth() const;
int depth() const { return depth_; }
///
docstring const & str() const;
docstring const & str() const { return str_; }
///
void str(docstring const & s) { str_ = s; }
///
docstring const & tooltip() const;
///
docstring const asString() const;
///
DocIterator const & dit() const;
DocIterator const & dit() const { return dit_; }
///
bool isOutput() const { return output_; }
@ -95,9 +128,57 @@ public:
typedef Toc::const_iterator TocIterator;
/// Caption-enabled TOC builders
class TocBuilder
{
public:
TocBuilder(shared_ptr<Toc> const toc);
/// When entering a float
void pushItem(DocIterator const & dit, docstring const & s,
bool output_active, bool is_captioned = false);
/// When encountering a caption
void captionItem(DocIterator const & dit, docstring const & s,
bool output_active);
/// When exiting a float
void pop();
private:
TocBuilder(){}
///
struct frame {
Toc::size_type const pos;
bool is_captioned;
};
///
shared_ptr<Toc> const toc_;
///
std::stack<frame> stack_;
};
/// The ToC list.
/// A class and no typedef because we want to forward declare it.
class TocList : public std::map<std::string, Toc> {};
class TocList : public std::map<std::string, shared_ptr<Toc> >
{
private:
// this can create null pointers
using std::map<std::string, shared_ptr<Toc> >::operator[];
};
///
class TocBuilderStore
{
public:
TocBuilderStore() {};
///
shared_ptr<TocBuilder> get(std::string const & type, shared_ptr<Toc> toc);
///
void clear() { map_.clear(); };
private:
typedef std::map<std::string, shared_ptr<TocBuilder> > map_t;
map_t map_;
};
///
@ -114,15 +195,13 @@ public:
void update(bool output_active);
/// \return true if the item was updated.
bool updateItem(DocIterator const & pit);
///
TocList const & tocs() const { return tocs_; }
TocList & tocs() { return tocs_; }
///
Toc const & toc(std::string const & type) const;
Toc & toc(std::string const & type);
/// never null
shared_ptr<Toc const> toc(std::string const & type) const;
shared_ptr<Toc> toc(std::string const & type);
/// nevel null
shared_ptr<TocBuilder> builder(std::string const & type);
/// Return the first Toc Item before the cursor
TocIterator item(
std::string const & type, ///< Type of Toc.
@ -137,20 +216,11 @@ private:
///
TocList tocs_;
///
TocBuilderStore builders_;
///
Buffer const * buffer_;
}; // TocBackend
inline bool operator==(TocItem const & a, TocItem const & b)
{
return a.id() == b.id() && a.str() == b.str() && a.depth() == b.depth();
}
inline bool operator!=(TocItem const & a, TocItem const & b)
{
return !(a == b);
}
} // namespace lyx

View File

@ -1313,8 +1313,8 @@ void MenuDefinition::expandToc(Buffer const * buf)
MenuDefinition submenu;
if (floatlist.typeExist(cit->first)) {
TocIterator ccit = cit->second.begin();
TocIterator eend = cit->second.end();
TocIterator ccit = cit->second->begin();
TocIterator eend = cit->second->end();
for (; ccit != eend; ++ccit) {
if (0 == ccit->depth()) {// omit subfloats
submenu.add(MenuItem(MenuItem::Command,
@ -1331,15 +1331,15 @@ void MenuDefinition::expandToc(Buffer const * buf)
item.setSubmenu(submenu);
add(item);
} else {
if (cit->second.size() >= 30) {
if (cit->second->size() >= 30) {
// FIXME: the behaviour of the interface should not change
// arbitrarily. Each type should be audited to see if the list
// can be optimised like for floats above.
FuncRequest f(LFUN_DIALOG_SHOW, "toc " + cit->first);
submenu.add(MenuItem(MenuItem::Command, qt_("Open Navigator..."), f));
} else {
TocIterator ccit = cit->second.begin();
TocIterator eend = cit->second.end();
TocIterator ccit = cit->second->begin();
TocIterator eend = cit->second->end();
for (; ccit != eend; ++ccit) {
submenu.add(MenuItem(MenuItem::Command,
limitStringLength(ccit->str()) + '|',
@ -1367,8 +1367,8 @@ void MenuDefinition::expandToc(Buffer const * buf)
if (cit == end)
LYXERR(Debug::GUI, "No table of contents.");
else {
if (!cit->second.empty())
expandToc2(cit->second, 0, cit->second.size(), 0);
if (!cit->second->empty())
expandToc2(* cit->second, 0, cit->second->size(), 0);
else
add(MenuItem(MenuItem::Info, qt_("<Empty Table of Contents>")));
}

View File

@ -364,7 +364,7 @@ void TocModels::reset(BufferView const * bv)
iterator mod_it = models_.find(type);
if (mod_it == models_.end())
mod_it = models_.insert(type, new TocModel(this));
mod_it.value()->reset(it->second);
mod_it.value()->reset(*it->second);
// Fill in the names_ model.
QString const gui_name = guiName(it->first, bv->buffer().params());

View File

@ -628,6 +628,8 @@ QString guiName(string const & type, BufferParams const & bp)
return qt_("Branches");
if (type == "change")
return qt_("Changes");
if (type == "senseless")
return qt_("Senseless");
if (prefixIs(type, "index:")) {
string const itype = split(type, ':');
IndicesList const & indiceslist = bp.indiceslist();

View File

@ -353,10 +353,10 @@ void InsetBranch::addToToc(DocIterator const & cpit, bool output_active) const
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetBranch &>(*this)));
Toc & toc = buffer().tocBackend().toc("branch");
shared_ptr<Toc> toc = buffer().tocBackend().toc("branch");
docstring str = params_.branch + ": ";
text().forOutliner(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
toc->push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
// Proceed with the rest of the inset.
bool const doing_output = output_active && isBranchSelected();
InsetCollapsable::addToToc(cpit, doing_output);

View File

@ -92,18 +92,13 @@ void InsetCaption::setCustomLabel(docstring const & label)
void InsetCaption::addToToc(DocIterator const & cpit, bool output_active) const
{
if (floattype_.empty())
return;
string const & type = floattype_.empty() ? "senseless" : floattype_;
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetCaption &>(*this)));
Toc & toc = buffer().tocBackend().toc(floattype_);
docstring str = full_label_;
int length = output_active ? INT_MAX : TOC_ENTRY_LENGTH;
text().forOutliner(str, length);
toc.push_back(TocItem(pit, is_subfloat_ ? 1 : 0, str, output_active));
buffer().tocBackend().builder(type)->captionItem(pit, str, output_active);
// Proceed with the rest of the inset.
InsetText::addToToc(cpit, output_active);
}
@ -368,7 +363,7 @@ void InsetCaption::updateBuffer(ParIterator const & it, UpdateType utype)
}
// Memorize type for addToToc().
floattype_ = type;
if (type.empty())
if (type.empty() || type == "senseless")
full_label_ = master.B_("Senseless!!! ");
else {
// FIXME: life would be _much_ simpler if listings was

View File

@ -339,8 +339,8 @@ void InsetCitation::addToToc(DocIterator const & cpit, bool output_active) const
// by both XHTML and plaintext output. So, if we change what goes into the TOC,
// then we will also need to change that routine.
docstring const tocitem = getParam("key");
Toc & toc = buffer().tocBackend().toc("citation");
toc.push_back(TocItem(cpit, 0, tocitem, output_active));
shared_ptr<Toc> toc = buffer().tocBackend().toc("citation");
toc->push_back(TocItem(cpit, 0, tocitem, output_active));
}

View File

@ -30,6 +30,7 @@
#include "output_xhtml.h"
#include "ParIterator.h"
#include "TextClass.h"
#include "TocBackend.h"
#include "support/debug.h"
#include "support/docstream.h"
@ -202,6 +203,22 @@ bool InsetFloat::getStatus(Cursor & cur, FuncRequest const & cmd,
}
void InsetFloat::addToToc(DocIterator const & cpit, bool output_active) const
{
string const & type = params().type;
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetFloat &>(*this)));
docstring str;
int length = output_active ? INT_MAX : TOC_ENTRY_LENGTH;
text().forOutliner(str, length);
shared_ptr<TocBuilder> builder = buffer().tocBackend().builder(type);
builder->pushItem(pit, str, output_active);
// Proceed with the rest of the inset.
InsetCollapsable::addToToc(cpit, output_active);
builder->pop();
}
void InsetFloat::updateBuffer(ParIterator const & it, UpdateType utype)
{
Counters & cnts =

View File

@ -18,7 +18,8 @@
namespace lyx {
class InsetFloatParams {
class InsetFloatParams
{
public:
///
InsetFloatParams() : wide(false), sideways(false), subfloat(false) {}
@ -99,7 +100,9 @@ private:
bool inheritFont() const { return false; }
///
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
// Update the counters of this inset and of its contents
///
void addToToc(DocIterator const & di, bool output_active) const;
/// Update the counters of this inset and of its contents
void updateBuffer(ParIterator const &, UpdateType);
///
void doDispatch(Cursor & cur, FuncRequest & cmd);

View File

@ -211,8 +211,8 @@ docstring InsetFloatList::xhtml(XHTMLStream &, OutputParams const & op) const {
// FIXME Do we need to check if it exists? If so, we need a new
// routine in TocBackend to do that.
Toc const & toc = buffer().tocBackend().toc(toctype);
if (toc.empty())
shared_ptr<Toc const> toc = buffer().tocBackend().toc(toctype);
if (toc->empty())
return docstring();
// we want to look like a chapter, section, or whatever.
@ -249,8 +249,8 @@ docstring InsetFloatList::xhtml(XHTMLStream &, OutputParams const & op) const {
<< toclabel
<< html::EndTag(tag);
Toc::const_iterator it = toc.begin();
Toc::const_iterator const en = toc.end();
Toc::const_iterator it = toc->begin();
Toc::const_iterator const en = toc->end();
for (; it != en; ++it) {
Paragraph const & par = it->dit().innerParagraph();
string const attr = "class='lyxtoc-floats lyxtoc-" + toctype + "'";

View File

@ -79,10 +79,10 @@ void InsetFoot::addToToc(DocIterator const & cpit, bool output_active) const
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetFoot &>(*this)));
Toc & toc = buffer().tocBackend().toc("footnote");
shared_ptr<Toc> toc = buffer().tocBackend().toc("footnote");
docstring str = custom_label_ + ": ";
text().forOutliner(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
toc->push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
// Proceed with the rest of the inset.
InsetFootlike::addToToc(cpit, output_active);
}

View File

@ -1031,7 +1031,7 @@ void InsetGraphics::addToToc(DocIterator const & cpit, bool output_active) const
{
//FIXME UNICODE
docstring const str = from_utf8(params_.filename.onlyFileName());
buffer().tocBackend().toc("graphics").push_back(TocItem(cpit, 0, str, output_active));
buffer().tocBackend().toc("graphics")->push_back(TocItem(cpit, 0, str, output_active));
}

View File

@ -1137,29 +1137,30 @@ void InsetInclude::addToToc(DocIterator const & cpit, bool output_active) const
string caption = p.getParamValue("caption");
if (caption.empty())
return;
Toc & toc = backend.toc("listing");
docstring str = convert<docstring>(toc.size() + 1)
shared_ptr<Toc> toc = backend.toc("listing");
docstring str = convert<docstring>(toc->size() + 1)
+ ". " + from_utf8(caption);
DocIterator pit = cpit;
toc.push_back(TocItem(pit, 0, str, output_active));
return;
}
toc->push_back(TocItem(pit, 0, str, output_active));
} else {
Buffer const * const childbuffer = getChildBuffer();
if (!childbuffer)
return;
Toc & toc = backend.toc("child");
shared_ptr<Toc> toc = backend.toc("child");
docstring str = childbuffer->fileName().displayName();
toc.push_back(TocItem(cpit, 0, str, output_active));
toc->push_back(TocItem(cpit, 0, str, output_active));
TocList & toclist = backend.tocs();
//TocList & toclist = backend.tocs();
childbuffer->tocBackend().update(output_active);
TocList const & childtoclist = childbuffer->tocBackend().tocs();
TocList::const_iterator it = childtoclist.begin();
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());
for(; it != end; ++it) {
shared_ptr<Toc> toc = backend.toc(it->first);
toc->insert(toc->end(), it->second->begin(), it->second->end());
}
}
}

View File

@ -358,7 +358,7 @@ void InsetIndex::addToToc(DocIterator const & cpit, bool output_active) const
type += ":" + to_utf8(params_.index);
// this is unlikely to be terribly long
text().forOutliner(str, INT_MAX);
buffer().tocBackend().toc(type).push_back(TocItem(pit, 0, str, output_active));
buffer().tocBackend().toc(type)->push_back(TocItem(pit, 0, str, output_active));
// Proceed with the rest of the inset.
InsetCollapsable::addToToc(cpit, output_active);
}
@ -689,13 +689,13 @@ docstring InsetPrintIndex::xhtml(XHTMLStream &, OutputParams const & op) const
if (bp.use_indices && getParam("type") != from_ascii("idx"))
return docstring();
Toc const & toc = buffer().tocBackend().toc("index");
if (toc.empty())
shared_ptr<Toc const> toc = buffer().tocBackend().toc("index");
if (toc->empty())
return docstring();
// Collect the index entries in a form we can use them.
Toc::const_iterator it = toc.begin();
Toc::const_iterator const en = toc.end();
Toc::const_iterator it = toc->begin();
Toc::const_iterator const en = toc->end();
vector<IndexEntry> entries;
for (; it != en; ++it)
if (it->isOutput())

View File

@ -172,27 +172,27 @@ void InsetLabel::updateBuffer(ParIterator const & par, UpdateType utype)
void InsetLabel::addToToc(DocIterator const & cpit, bool output_active) const
{
docstring const & label = getParam("name");
Toc & toc = buffer().tocBackend().toc("label");
shared_ptr<Toc> toc = buffer().tocBackend().toc("label");
if (buffer().insetLabel(label) != this) {
toc.push_back(TocItem(cpit, 0, screen_label_, output_active));
return;
}
toc.push_back(TocItem(cpit, 0, screen_label_, output_active));
toc->push_back(TocItem(cpit, 0, screen_label_, output_active));
} else {
toc->push_back(TocItem(cpit, 0, screen_label_, output_active));
Buffer::References const & refs = buffer().references(label);
Buffer::References::const_iterator it = refs.begin();
Buffer::References::const_iterator end = refs.end();
for (; it != end; ++it) {
DocIterator const ref_pit(it->second);
if (it->first->lyxCode() == MATH_REF_CODE)
toc.push_back(TocItem(ref_pit, 1,
toc->push_back(TocItem(ref_pit, 1,
it->first->asInsetMath()->asRefInset()->screenLabel(),
output_active));
else
toc.push_back(TocItem(ref_pit, 1,
toc->push_back(TocItem(ref_pit, 1,
static_cast<InsetRef *>(it->first)->getTOCString(),
output_active));
}
}
}
bool InsetLabel::getStatus(Cursor & cur, FuncRequest const & cmd,

View File

@ -349,7 +349,8 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd,
status.setEnabled(true);
return true;
case LFUN_CAPTION_INSERT: {
if (params().isInline()) {
// the inset outputs at most one caption
if (params().isInline() || getCaptionInset()) {
status.setEnabled(false);
return true;
}

View File

@ -56,10 +56,10 @@ void InsetMarginal::addToToc(DocIterator const & cpit, bool output_active) const
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetMarginal &>(*this)));
Toc & toc = buffer().tocBackend().toc("marginalnote");
shared_ptr<Toc> toc = buffer().tocBackend().toc("marginalnote");
docstring str;
text().forOutliner(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
toc->push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
// Proceed with the rest of the inset.
InsetFootlike::addToToc(cpit, output_active);
}

View File

@ -135,7 +135,7 @@ void InsetNomencl::validate(LaTeXFeatures & features) const
void InsetNomencl::addToToc(DocIterator const & cpit, bool output_active) const
{
docstring const str = getParam("symbol");
buffer().tocBackend().toc("nomencl").push_back(TocItem(cpit, 0, str, output_active));
buffer().tocBackend().toc("nomencl")->push_back(TocItem(cpit, 0, str, output_active));
}
@ -190,11 +190,11 @@ typedef map<docstring, NomenclEntry > EntryMap;
docstring InsetPrintNomencl::xhtml(XHTMLStream &, OutputParams const & op) const
{
Toc const & toc = buffer().tocBackend().toc("nomencl");
shared_ptr<Toc const> toc = buffer().tocBackend().toc("nomencl");
EntryMap entries;
Toc::const_iterator it = toc.begin();
Toc::const_iterator const en = toc.end();
Toc::const_iterator it = toc->begin();
Toc::const_iterator const en = toc->end();
for (; it != en; ++it) {
DocIterator dit = it->dit();
Paragraph const & par = dit.innerParagraph();

View File

@ -212,11 +212,11 @@ void InsetNote::addToToc(DocIterator const & cpit, bool output_active) const
DocIterator pit = cpit;
pit.push_back(CursorSlice(const_cast<InsetNote &>(*this)));
Toc & toc = buffer().tocBackend().toc("note");
shared_ptr<Toc> toc = buffer().tocBackend().toc("note");
InsetLayout const & il = getLayout();
docstring str = translateIfPossible(il.labelstring()) + from_ascii(": ");
text().forOutliner(str, TOC_ENTRY_LENGTH);
toc.push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
toc->push_back(TocItem(pit, 0, str, output_active, toolTipText(docstring(), 3, 60)));
// Proceed with the rest of the inset.
bool doing_output = output_active && producesOutput();

View File

@ -312,8 +312,8 @@ void InsetRef::addToToc(DocIterator const & cpit, bool output_active) const
// It seems that this reference does not point to any valid label.
screen_label_ = _("BROKEN: ") + screen_label_;
Toc & toc = buffer().tocBackend().toc("label");
toc.push_back(TocItem(cpit, 0, screen_label_, output_active));
shared_ptr<Toc> toc = buffer().tocBackend().toc("label");
toc->push_back(TocItem(cpit, 0, screen_label_, output_active));
}

View File

@ -235,8 +235,9 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
LASSERT(false, return docstring());
}
Toc const & toc = buffer().masterBuffer()->tocBackend().toc(cmd2type(command));
if (toc.empty())
shared_ptr<Toc const> toc =
buffer().masterBuffer()->tocBackend().toc(cmd2type(command));
if (toc->empty())
return docstring();
// we'll use our own stream, because we are going to defer everything.
@ -264,9 +265,9 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
// Output of TOC
if (use_depth)
makeTOCWithDepth(xs, toc, op);
makeTOCWithDepth(xs, *toc, op);
else
makeTOCNoDepth(xs, toc, op);
makeTOCNoDepth(xs, *toc, op);
xs << html::EndTag("div") << html::CR();
return ods.str();

View File

@ -805,7 +805,8 @@ void InsetText::addToToc(DocIterator const & cdit, bool output_active) const
void InsetText::iterateForToc(DocIterator const & cdit, bool output_active) const
{
DocIterator dit = cdit;
Toc & toc = buffer().tocBackend().toc("tableofcontents");
// Ensure that any document has a table of contents
shared_ptr<Toc> toc = buffer().tocBackend().toc("tableofcontents");
BufferParams const & bufparams = buffer_->params();
int const min_toclevel = bufparams.documentClass().min_toclevel();
@ -846,7 +847,7 @@ void InsetText::iterateForToc(DocIterator const & cdit, bool output_active) cons
} else
par.forOutliner(tocstring, length);
dit.pos() = 0;
toc.push_back(TocItem(dit, toclevel - min_toclevel,
toc->push_back(TocItem(dit, toclevel - min_toclevel,
tocstring, doing_output, tocstring));
}

View File

@ -301,14 +301,14 @@ void InsetMathHull::addToToc(DocIterator const & pit, bool output_active) const
return;
}
Toc & toc = buffer().tocBackend().toc("equation");
shared_ptr<Toc> toc = buffer().tocBackend().toc("equation");
for (row_type row = 0; row != nrows(); ++row) {
if (!numbered(row))
continue;
if (label_[row])
label_[row]->addToToc(pit, output_active);
toc.push_back(TocItem(pit, 0, nicelabel(row), output_active));
toc->push_back(TocItem(pit, 0, nicelabel(row), output_active));
}
}