X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Finsets%2FInsetTOC.cpp;h=76a8dc9d1bfbe3f0b240a7908f853a1fb1d70d32;hb=57b69a5efddf9f3c148007322f00dad6c253a2ed;hp=bac2f43699b27c9aa5dd92656ab4aabfa3bea2d6;hpb=bfddee97e191a853f0576f4fab3f095c4e9ce0de;p=lyx.git diff --git a/src/insets/InsetTOC.cpp b/src/insets/InsetTOC.cpp index bac2f43699..76a8dc9d1b 100644 --- a/src/insets/InsetTOC.cpp +++ b/src/insets/InsetTOC.cpp @@ -14,6 +14,7 @@ #include "Buffer.h" #include "BufferParams.h" +#include "BufferView.h" #include "Cursor.h" #include "DispatchResult.h" #include "Font.h" @@ -29,6 +30,7 @@ #include "support/debug.h" #include "support/gettext.h" +#include "support/lassert.h" #include @@ -36,6 +38,15 @@ using namespace std; namespace lyx { +namespace { +string cmd2type(string const & cmd) +{ + if (cmd == "lstlistoflistings") + return "listing"; + return cmd; +} +} + InsetTOC::InsetTOC(Buffer * buf, InsetCommandParams const & p) : InsetCommand(buf, p) @@ -52,10 +63,18 @@ ParamInfo const & InsetTOC::findInfo(string const & /* cmdName */) } +bool InsetTOC::isCompatibleCommand(string const & cmd) +{ + return cmd == defaultCommand() || cmd == "lstlistoflistings"; +} + + docstring InsetTOC::screenLabel() const { if (getCmdName() == "tableofcontents") return buffer().B_("Table of Contents"); + if (getCmdName() == "lstlistoflistings") + return buffer().B_("List of Listings"); return _("Unknown TOC type"); } @@ -64,7 +83,7 @@ void InsetTOC::doDispatch(Cursor & cur, FuncRequest & cmd) { switch (cmd.action()) { case LFUN_MOUSE_RELEASE: if (!cur.selection() && cmd.button() == mouse_button::button1) { - showInsetDialog(&cur.bv()); + cur.bv().showDialog("toc", params2string(params())); cur.dispatched(); } break; @@ -75,10 +94,28 @@ void InsetTOC::doDispatch(Cursor & cur, FuncRequest & cmd) { } -int InsetTOC::plaintext(odocstream & os, OutputParams const &) const +docstring InsetTOC::layoutName() const +{ + if (getCmdName() == "lstlistoflistings") + return from_ascii("TOC:Listings"); + return from_ascii("TOC"); +} + + +void InsetTOC::validate(LaTeXFeatures & features) const +{ + InsetCommand::validate(features); + features.useInsetLayout(getLayout()); + if (getCmdName() == "lstlistoflistings") + features.require("listings"); +} + + +int InsetTOC::plaintext(odocstringstream & os, + OutputParams const &, size_t max_length) const { os << screenLabel() << "\n\n"; - buffer().tocBackend().writePlaintextTocList(getCmdName(), os); + buffer().tocBackend().writePlaintextTocList(cmd2type(getCmdName()), os, max_length); return PLAINTEXT_NEWLINE; } @@ -91,37 +128,40 @@ int InsetTOC::docbook(odocstream & os, OutputParams const &) const } -docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const +void InsetTOC::makeTOCEntry(XHTMLStream & xs, + Paragraph const & par, OutputParams const & op) const { - Layout const & lay = buffer().params().documentClass().htmlTOCLayout(); - string const & tocclass = lay.defaultCSSClass(); - string const tocattr = "class='tochead " + tocclass + "'"; - - // we'll use our own stream, because we are going to defer everything. - // that's how we deal with the fact that we're probably inside a standard - // paragraph, and we don't want to be. - odocstringstream ods; - XHTMLStream xs(ods); + string const attr = "href='#" + par.magicLabel() + "' class='tocentry'"; + xs << html::StartTag("a", attr); - Toc const & toc = buffer().tocBackend().toc("tableofcontents"); - if (toc.empty()) - return docstring(); + // First the label, if there is one + docstring const & label = par.params().labelString(); + if (!label.empty()) + xs << label << " "; + // Now the content of the TOC entry, taken from the paragraph itself + OutputParams ours = op; + ours.for_toc = true; + Font const dummy; + par.simpleLyXHTMLOnePar(buffer(), xs, ours, dummy); - xs << html::StartTag("div", "class='toc'"); + xs << html::EndTag("a") << html::CR(); +} - // Title of TOC - static string toctitle = N_("Table of Contents"); - docstring title = buffer().B_(toctitle); - xs << html::StartTag("div", tocattr) - << title - << html::EndTag("div"); - // Output of TOC +void InsetTOC::makeTOCWithDepth(XHTMLStream & xs, + Toc const & toc, OutputParams const & op) const +{ Toc::const_iterator it = toc.begin(); Toc::const_iterator const en = toc.end(); int lastdepth = 0; for (; it != en; ++it) { + // do not output entries that are not actually included in the output, + // e.g., stuff in non-active branches or notes or whatever. + if (!it->isOutput()) + continue; + // First, we need to manage increases and decreases of depth + // If there's no depth to deal with, we artifically set it to 1. int const depth = it->depth(); // Ignore stuff above the tocdepth @@ -159,33 +199,76 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const // Now output TOC info for this entry Paragraph const & par = it->dit().innerParagraph(); - - string const attr = "href='#" + par.magicLabel() + "' class='tocentry'"; - xs << html::StartTag("a", attr); - - // First the label, if there is one - docstring const & label = par.params().labelString(); - if (!label.empty()) - xs << label << " "; - // Now the content of the TOC entry, taken from the paragraph itself - OutputParams ours = op; - ours.for_toc = true; - Font const dummy; - par.simpleLyXHTMLOnePar(buffer(), xs, ours, dummy); - - xs << html::EndTag("a") << " "; - - // Now a link to that paragraph - string const parattr = "href='#" + par.magicLabel() + "' class='tocarrow'"; - xs << html::StartTag("a", parattr); - // FIXME XHTML - // There ought to be a simple way to customize this. - // Maybe if we had an InsetLayout for TOC... - xs << XHTMLStream::ESCAPE_NONE << ">"; - xs << html::EndTag("a"); + makeTOCEntry(xs, par, op); } for (int i = lastdepth; i > 0; --i) xs << html::EndTag("div") << html::CR(); +} + + +void InsetTOC::makeTOCNoDepth(XHTMLStream & xs, + Toc const & toc, const OutputParams & op) const +{ + Toc::const_iterator it = toc.begin(); + Toc::const_iterator const en = toc.end(); + for (; it != en; ++it) { + // do not output entries that are not actually included in the output, + // e.g., stuff in non-active branches or notes or whatever. + if (!it->isOutput()) + continue; + + xs << html::StartTag("div", "class='lyxtoc-flat'") << html::CR(); + + Paragraph const & par = it->dit().innerParagraph(); + makeTOCEntry(xs, par, op); + + xs << html::EndTag("div"); + } +} + + +docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const +{ + string const & command = getCmdName(); + if (command != "tableofcontents" && command != "lstlistoflistings") { + LYXERR0("TOC type " << command << " not yet implemented."); + LASSERT(false, return docstring()); + } + + shared_ptr 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. + // that's how we deal with the fact that we're probably inside a standard + // paragraph, and we don't want to be. + odocstringstream ods; + XHTMLStream xs(ods); + + xs << html::StartTag("div", "class='toc'"); + + // Title of TOC + InsetLayout const & il = getLayout(); + string const & tag = il.htmltag(); + docstring title = screenLabel(); + Layout const & lay = buffer().params().documentClass().htmlTOCLayout(); + string const & tocclass = lay.defaultCSSClass(); + string const tocattr = "class='tochead " + tocclass + "'"; + xs << html::StartTag(tag, tocattr) + << title + << html::EndTag(tag); + + // with lists of listings, at least, there is no depth + // to worry about. so the code can be simpler. + bool const use_depth = (command == "tableofcontents"); + + // Output of TOC + if (use_depth) + makeTOCWithDepth(xs, *toc, op); + else + makeTOCNoDepth(xs, *toc, op); + xs << html::EndTag("div") << html::CR(); return ods.str(); }