+ if (action_.action() == LFUN_UNKNOWN_ACTION) {
+ return FuncRequest(LFUN_PARAGRAPH_GOTO, paragraph_goto_arg(dit_));
+ } else
+ return action_;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Toc implementation
+//
+///////////////////////////////////////////////////////////////////////////
+
+Toc::const_iterator TocBackend::findItem(Toc const & toc,
+ DocIterator const & dit)
+{
+ Toc::const_iterator last = toc.begin();
+ Toc::const_iterator it = toc.end();
+ if (it == last)
+ return it;
+ --it;
+ DocIterator dit_text = dit.getInnerText();
+
+ for (; it != last; --it) {
+ // We verify that we don't compare contents of two
+ // different document. This happens when you
+ // have parent and child documents.
+ if (&it->dit_[0].inset() != &dit_text[0].inset())
+ continue;
+ if (it->dit_ <= dit_text)
+ return it;
+ }
+
+ // We are before the first Toc Item:
+ return last;
+}
+
+
+Toc::iterator TocBackend::findItem(Toc & toc, int depth, docstring const & str)
+{
+ if (toc.empty())
+ return toc.end();
+ Toc::iterator it = toc.begin();
+ Toc::iterator itend = toc.end();
+ for (; it != itend; ++it) {
+ if (it->depth() == depth && it->str() == str)
+ break;
+ }
+ return it;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// TocBuilder implementation
+//
+///////////////////////////////////////////////////////////////////////////
+
+TocBuilder::TocBuilder(shared_ptr<Toc> toc)
+ : toc_(toc ? toc : lyx::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)
+{
+ // first show the float before moving to the caption
+ docstring arg = "paragraph-goto " + paragraph_goto_arg(dit);
+ if (!stack_.empty())
+ arg = "paragraph-goto " +
+ paragraph_goto_arg((*toc_)[stack_.top().pos].dit_) + ";" + arg;
+ FuncRequest func(LFUN_COMMAND_SEQUENCE, arg);
+
+ if (!stack_.empty() && !stack_.top().is_captioned) {
+ // The float we entered has not yet been assigned a caption.
+ // Assign the caption string to it.
+ TocItem & captionable = (*toc_)[stack_.top().pos];
+ captionable.str(s);
+ captionable.setAction(func);
+ stack_.top().is_captioned = true;
+ } else {
+ // This is a new entry.
+ pop();
+ // the dit is at the float's level, e.g. for the contextual menu of
+ // outliner entries
+ DocIterator captionable_dit = dit;
+ captionable_dit.pop_back();
+ pushItem(captionable_dit, s, output_active, true);
+ (*toc_)[stack_.top().pos].setAction(func);
+ }
+}
+
+void TocBuilder::pop()
+{
+ if (!stack_.empty())
+ stack_.pop();