]> git.lyx.org Git - lyx.git/blobdiff - src/TocBackend.cpp
Cmake tests for translators: Added check for required program phantomjs
[lyx.git] / src / TocBackend.cpp
index 1eb8f8098c09937c3d4f430567021c4f754a915c..9bd435f2f209283245b5ae9d7ad2ef9c7115a5ff 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "Buffer.h"
 #include "BufferParams.h"
+#include "Cursor.h"
 #include "FloatList.h"
 #include "FuncRequest.h"
 #include "InsetList.h"
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
-
+#include "support/gettext.h"
 #include "support/lassert.h"
+#include "support/lstrings.h"
 
 using namespace std;
 
 
 namespace lyx {
 
+
 ///////////////////////////////////////////////////////////////////////////
 //
 // TocItem implementation
@@ -46,8 +49,9 @@ namespace lyx {
 ///////////////////////////////////////////////////////////////////////////
 
 TocItem::TocItem(DocIterator const & dit, int d, docstring const & s,
-       bool output_active, docstring const & t) :
-  dit_(dit), depth_(d), str_(s), tooltip_(t), output_(output_active)
+                       bool output_active, docstring const & t, FuncRequest action) :
+       dit_(dit), depth_(d), str_(s), tooltip_(t), output_(output_active),
+       action_(action)
 {
 }
 
@@ -66,15 +70,34 @@ docstring const & TocItem::tooltip() const
 
 docstring const TocItem::asString() const
 {
-       return docstring(4 * depth_, ' ') + str_;
+       static char_type const cross = 0x2716; // ✖ U+2716 HEAVY MULTIPLICATION X
+       static char_type const thin = 0x2009; // U+2009 THIN SPACE
+       docstring prefix;
+       if (!output_) {
+               prefix += cross;
+               prefix += thin;
+       }
+       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<docstring>(s.paragraph().id()) + ' ' +
+               convert<docstring>(s.pos());
 }
 
+} // namespace anon
 
 FuncRequest TocItem::action() const
 {
-       string const arg = convert<string>(dit_.paragraph().id())
-               + ' ' + convert<string>(dit_.pos());
-       return FuncRequest(LFUN_PARAGRAPH_GOTO, arg);
+       if (action_.action() == LFUN_UNKNOWN_ACTION) {
+               return FuncRequest(LFUN_PARAGRAPH_GOTO, paragraph_goto_arg(dit_));
+       } else
+               return action_;
 }
 
 
@@ -136,7 +159,7 @@ Toc::iterator Toc::item(int depth, docstring const & str)
 ///////////////////////////////////////////////////////////////////////////
 
 TocBuilder::TocBuilder(shared_ptr<Toc> toc)
-       : toc_(toc ? toc : make_shared<Toc>()),
+       : toc_(toc ? toc : lyx::make_shared<Toc>()),
          stack_()
 {
        LATTEST(toc);
@@ -156,15 +179,29 @@ void TocBuilder::pushItem(DocIterator const & dit, docstring const & s,
 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.
-               (*toc_)[stack_.top().pos].str(s);
+               TocItem & captionable = (*toc_)[stack_.top().pos];
+               captionable.str(s);
+               captionable.setAction(func);
                stack_.top().is_captioned = true;
        } else {
                // This is a new entry.
                pop();
-               pushItem(dit, s, output_active, true);
+               // 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);
        }
 }
 
@@ -188,7 +225,7 @@ shared_ptr<TocBuilder> TocBuilderStore::get(string const & type,
        map_t::const_iterator it = map_.find(type);
        if (it == map_.end()) {
                it = map_.insert(std::make_pair(type,
-                                                                               make_shared<TocBuilder>(toc))).first;
+                                                                       lyx::make_shared<TocBuilder>(toc))).first;
        }
        return it->second;
 }
@@ -205,7 +242,7 @@ 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>(); });
+       LASSERT(it != tocs_.end(), { return lyx::make_shared<Toc>(); });
        return it->second;
 }
 
@@ -214,7 +251,7 @@ 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;
+               it = tocs_.insert(std::make_pair(type, lyx::make_shared<Toc>())).first;
        }
        return it->second;
 }
@@ -226,8 +263,16 @@ shared_ptr<TocBuilder> TocBackend::builder(string const & type)
 }
 
 
-bool TocBackend::updateItem(DocIterator const & dit)
+// FIXME: This function duplicates functionality from InsetText::iterateForToc.
+// Both have their own way of computing the TocItem for "tableofcontents". The
+// 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)
 {
+       // we need a text
+       DocIterator dit = dit_in.getInnerText();
+
        if (dit.text()->getTocLevel(dit.pit()) == Layout::NOT_IN_TOC)
                return false;
 
@@ -247,36 +292,38 @@ bool TocBackend::updateItem(DocIterator const & dit)
 
        // For each paragraph, traverse its insets and let them add
        // their toc items
+       //
+       // 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) {
+                       tocstring = par.labelString();
                        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);
+                               tocstring += ' ';
+                       inset.asInsetText()->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())
-                       tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
+               par.forOutliner(tocstring, TOC_ENTRY_LENGTH);
 
-       const_cast<TocItem &>(*toc_item).str_ = tocstring;
+       support::truncateWithEllipsis(tocstring, TOC_ENTRY_LENGTH);
+       const_cast<TocItem &>(*toc_item).str(tocstring);
 
        buffer_->updateTocItem("tableofcontents", dit);
        return true;
 }
 
 
-void TocBackend::update(bool output_active)
+void TocBackend::update(bool output_active, UpdateType utype)
 {
        for (TocList::iterator it = tocs_.begin(); it != tocs_.end(); ++it)
                it->second->clear();
@@ -284,7 +331,7 @@ void TocBackend::update(bool output_active)
        builders_.clear();
        if (!buffer_->isInternal()) {
                DocIterator dit;
-               buffer_->inset().addToToc(dit, output_active);
+               buffer_->inset().addToToc(dit, output_active, utype);
        }
 }
 
@@ -316,4 +363,11 @@ void TocBackend::writePlaintextTocList(string const & type,
 }
 
 
+docstring TocBackend::outlinerName(std::string const & type) const
+{
+       return translateIfPossible(
+           buffer_->params().documentClass().outlinerName(type));
+}
+
+
 } // namespace lyx