X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTocBackend.cpp;h=c0a4373923f631eb51a29688cd5051db2c927b19;hb=210ea66d2d1113cddcc1b0f3547c1063b7dc4d47;hp=f490c3534a1189022ae0de139b1d58626f425c0a;hpb=5e2071376972a3c16d0874f18cf31e329e4f773c;p=lyx.git diff --git a/src/TocBackend.cpp b/src/TocBackend.cpp index f490c3534a..c0a4373923 100644 --- a/src/TocBackend.cpp +++ b/src/TocBackend.cpp @@ -17,19 +17,13 @@ #include "Buffer.h" #include "BufferParams.h" -#include "Cursor.h" -#include "FloatList.h" -#include "FuncRequest.h" +#include "IndicesList.h" #include "InsetList.h" -#include "Layout.h" -#include "LyXAction.h" #include "Paragraph.h" -#include "ParIterator.h" #include "TextClass.h" -#include "insets/InsetText.h" +#include "insets/InsetArgument.h" -#include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" #include "support/gettext.h" @@ -49,8 +43,8 @@ namespace lyx { /////////////////////////////////////////////////////////////////////////// TocItem::TocItem(DocIterator const & dit, int d, docstring const & s, - bool output_active, FuncRequest action) - : dit_(dit), depth_(d), str_(s), output_(output_active), + bool output_active, bool missing, FuncRequest const & action) + : dit_(dit), depth_(d), str_(s), output_(output_active), missing_(missing), action_(action) { } @@ -71,25 +65,17 @@ docstring const TocItem::asString() const prefix += cross; prefix += thin; } + if (missing_) { + prefix += _("MISSING: "); + } return prefix + str_; } -namespace { - -// convert a DocIterator into an argument to LFUN_PARAGRAPH_GOTO -docstring paragraph_goto_arg(DocIterator const & dit) -{ - CursorSlice const & s = dit.innerTextSlice(); - return convert(s.paragraph().id()) + ' ' + - convert(s.pos()); -} - -} // namespace anon FuncRequest TocItem::action() const { if (action_.action() == LFUN_UNKNOWN_ACTION) { - return FuncRequest(LFUN_PARAGRAPH_GOTO, paragraph_goto_arg(dit_)); + return FuncRequest(LFUN_PARAGRAPH_GOTO, dit_.paragraphGotoArgument()); } else return action_; } @@ -97,7 +83,7 @@ FuncRequest TocItem::action() const /////////////////////////////////////////////////////////////////////////// // -// Toc implementation +// TocBackend implementation // /////////////////////////////////////////////////////////////////////////// @@ -115,9 +101,9 @@ Toc::const_iterator TocBackend::findItem(Toc const & toc, // 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()) + if (&it->dit()[0].inset() != &dit_text[0].inset()) continue; - if (it->dit_ <= dit_text) + if (it->dit() <= dit_text) return it; } @@ -140,85 +126,6 @@ Toc::iterator TocBackend::findItem(Toc & toc, int depth, docstring const & str) } -/////////////////////////////////////////////////////////////////////////// -// -// TocBuilder implementation -// -/////////////////////////////////////////////////////////////////////////// - -TocBuilder::TocBuilder(shared_ptr toc) - : toc_(toc ? toc : make_shared()), - 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::argumentItem(docstring const & arg_str) -{ - if (stack_.empty() || arg_str.empty()) - return; - TocItem & item = (*toc_)[stack_.top().pos]; - docstring const & str = item.str(); - string const & delim = - str.empty() ? "" : stack_.top().is_captioned ? ", " : ": "; - item.str(str + from_ascii(delim) + arg_str); - stack_.top().is_captioned = true; -} - -void TocBuilder::pop() -{ - if (!stack_.empty()) - stack_.pop(); -} - - - -/////////////////////////////////////////////////////////////////////////// -// -// TocBackend implementation -// -/////////////////////////////////////////////////////////////////////////// - shared_ptr TocBackend::toc(string const & type) const { // Is the type already supported? @@ -239,8 +146,8 @@ shared_ptr TocBackend::toc(string const & type) TocBuilder & TocBackend::builder(string const & type) { - auto p = make_unique(toc(type)); - return * builders_.insert(make_pair(type, move(p))).first->second; + auto p = lyx::make_unique(toc(type)); + return * builders_.insert(make_pair(type, std::move(p))).first->second; } @@ -249,8 +156,11 @@ TocBuilder & TocBackend::builder(string const & type) // TocItem creation and update should be made in a dedicated function and // updateItem should be rewritten to uniformly update the matching items from // all TOCs. -bool TocBackend::updateItem(DocIterator const & dit_in) +bool TocBackend::updateItem(DocIterator const & dit_in) const { + if (dit_in.buffer() && dit_in.buffer()->isInternal()) + return false; + // we need a text DocIterator dit = dit_in.getInnerText(); @@ -258,7 +168,7 @@ bool TocBackend::updateItem(DocIterator const & dit_in) return false; if (toc("tableofcontents")->empty()) { - // FIXME: should not happen, + // FIXME: should not happen, // a call to TocBackend::update() is missing somewhere LYXERR0("TocBackend::updateItem called but the TOC is empty!"); return false; @@ -276,22 +186,18 @@ bool TocBackend::updateItem(DocIterator const & dit_in) // // FIXME: This is supposed to accomplish the same as the body of // InsetText::iterateForToc(), probably - 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) { + Paragraph const & par = toc_item->dit().paragraph(); + for (auto const & table : par.insetList()) + if (InsetArgument const * arg = table.inset->asInsetArgument()) { tocstring = par.labelString(); if (!tocstring.empty()) tocstring += ' '; - inset.asInsetText()->text().forOutliner(tocstring,TOC_ENTRY_LENGTH); + arg->text().forOutliner(tocstring,TOC_ENTRY_LENGTH); break; } - } - int const toclevel = toc_item->dit_.text()-> - getTocLevel(toc_item->dit_.pit()); + int const toclevel = toc_item->dit().text()-> + getTocLevel(toc_item->dit().pit()); if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel && tocstring.empty()) par.forOutliner(tocstring, TOC_ENTRY_LENGTH); @@ -304,16 +210,24 @@ bool TocBackend::updateItem(DocIterator const & dit_in) } -void TocBackend::update(bool output_active, UpdateType utype) +void TocBackend::reset() { - for (TocList::iterator it = tocs_.begin(); it != tocs_.end(); ++it) - it->second->clear(); + for (auto const & t: tocs_) + t.second->clear(); tocs_.clear(); builders_.clear(); - if (!buffer_->isInternal()) { - DocIterator dit; - buffer_->inset().addToToc(dit, output_active, utype); - } + resetOutlinerNames(); +} + + +void TocBackend::update(bool output_active, UpdateType utype) +{ + reset(); + if (buffer_->isInternal()) + return; + + DocIterator dit; + buffer_->inset().addToToc(dit, output_active, utype, *this); } @@ -346,14 +260,62 @@ void TocBackend::writePlaintextTocList(string const & type, docstring TocBackend::outlinerName(string const & type) const { - return translateIfPossible( - buffer_->params().documentClass().outlinerName(type)); + map::const_iterator const it + = outliner_names_.find(type); + if (it != outliner_names_.end()) + return it->second; + + // Legacy treatment of index:... type + if (support::prefixIs(type, "index:")) { + string const itype = support::split(type, ':'); + IndicesList const & indiceslist = buffer_->params().indiceslist(); + Index const * index = indiceslist.findShortcut(from_utf8(itype)); + docstring indextype = _("unknown type!"); + if (index) + indextype = index->index(); + return support::bformat(_("Index Entries (%1$s)"), indextype); + } + + LYXERR0("Missing OutlinerName for " << type << "!"); + return from_utf8(type); +} + + +void TocBackend::resetOutlinerNames() +{ + outliner_names_.clear(); + // names from this document class + for (auto const & name + : buffer_->params().documentClass().outlinerNames()) + addName(name.first, translateIfPossible(name.second)); + // Hardcoded types + addName("tableofcontents", _("Table of Contents")); + addName("change", _("Changes")); + addName("senseless", _("Senseless")); + addName("citation", _("Citations")); + addName("label", _("Labels and References")); + addName("brokenrefs", _("Broken References and Citations")); + // Customizable, but the corresponding insets have no layout definition + addName("child", _("Child Documents")); + addName("graphics", _("Graphics[[listof]]")); + addName("equation", _("Equations")); + addName("external", _("External Material")); + addName("math-macro", _("Math Macros")); + addName("nomencl", _("Nomenclature Entries")); +} + + +void TocBackend::addName(string const & type, docstring const & name) +{ + if (name.empty()) + return; + // only inserts if the key does not exist + outliner_names_.insert({type, name}); } bool TocBackend::isOther(std::string const & type) { - // This is where having an Enum of types would have been more elegant... return type == "graphics" || type == "note" || type == "branch"