diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index 57286d9a6c..fdb61876d6 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -26,6 +26,7 @@ #include "insets/InsetTabular.h" +#include "support/convert.h" #include "support/debug.h" #include "support/ExceptionMessage.h" #include "support/gettext.h" @@ -207,7 +208,7 @@ FontSpan DocIterator::locateWord(word_location const loc) const return f; } - + CursorSlice const & DocIterator::innerTextSlice() const { LBUFERR(!empty()); @@ -226,6 +227,14 @@ CursorSlice const & DocIterator::innerTextSlice() const } +docstring DocIterator::paragraphGotoArgument() const +{ + CursorSlice const & s = innerTextSlice(); + return convert(s.paragraph().id()) + ' ' + + convert(s.pos()); +} + + DocIterator DocIterator::getInnerText() const { DocIterator texted = *this; diff --git a/src/DocIterator.h b/src/DocIterator.h index 3f718697ad..425bfa4f68 100644 --- a/src/DocIterator.h +++ b/src/DocIterator.h @@ -165,6 +165,8 @@ public: Paragraph & innerParagraph() const; /// return the inner text slice. CursorSlice const & innerTextSlice() const; + // convert a DocIterator into an argument to LFUN_PARAGRAPH_GOTO + docstring paragraphGotoArgument() const; /// returns a DocIterator for the containing text inset DocIterator getInnerText() const; /// the first and last positions of a word at top cursor slice diff --git a/src/Makefile.am b/src/Makefile.am index f87d0290b3..d2a5e85068 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -183,6 +183,7 @@ SOURCEFILESCORE = \ TextClass.cpp \ TextMetrics.cpp \ TocBackend.cpp \ + TocBuilder.cpp \ Trans.cpp \ Undo.cpp \ VCBackend.cpp \ @@ -288,6 +289,7 @@ HEADERFILESCORE = \ TextMetrics.h \ Toc.h \ TocBackend.h \ + TocBuilder.h \ Trans.h \ Undo.h \ update_flags.h \ diff --git a/src/TocBackend.cpp b/src/TocBackend.cpp index 1256a49865..1c1606608e 100644 --- a/src/TocBackend.cpp +++ b/src/TocBackend.cpp @@ -17,19 +17,12 @@ #include "Buffer.h" #include "BufferParams.h" -#include "Cursor.h" -#include "FloatList.h" -#include "FuncRequest.h" #include "InsetList.h" -#include "Layout.h" -#include "LyXAction.h" #include "Paragraph.h" -#include "ParIterator.h" #include "TextClass.h" #include "insets/InsetText.h" -#include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" #include "support/gettext.h" @@ -74,22 +67,11 @@ docstring const TocItem::asString() const 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 +79,7 @@ FuncRequest TocItem::action() const /////////////////////////////////////////////////////////////////////////// // -// Toc implementation +// TocBackend implementation // /////////////////////////////////////////////////////////////////////////// @@ -115,9 +97,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 +122,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? @@ -276,7 +179,7 @@ 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(); + Paragraph & par = toc_item->dit().paragraph(); InsetList::const_iterator it = par.insetList().begin(); InsetList::const_iterator end = par.insetList().end(); for (; it != end; ++it) { @@ -290,8 +193,8 @@ bool TocBackend::updateItem(DocIterator const & dit_in) } } - 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); diff --git a/src/TocBackend.h b/src/TocBackend.h index 1e58ec2f34..3f2ee419c0 100644 --- a/src/TocBackend.h +++ b/src/TocBackend.h @@ -19,12 +19,11 @@ #include "FuncRequest.h" #include "OutputEnums.h" #include "Toc.h" +#include "TocBuilder.h" #include "support/strfwd.h" #include "support/unique_ptr.h" -#include - namespace lyx { @@ -54,9 +53,6 @@ class Buffer; */ class TocItem { - friend class TocBackend; - friend class TocBuilder; - public: /// Default constructor for STL containers. TocItem() : dit_(0), depth_(0), output_(false) {} @@ -68,31 +64,28 @@ public: FuncRequest action = FuncRequest(LFUN_UNKNOWN_ACTION) ); /// - ~TocItem() {} - /// - int id() const; + DocIterator const & dit() const { return dit_; } /// int depth() const { return depth_; } /// docstring const & str() const { return str_; } /// void str(docstring const & s) { str_ = s; } - /// String for display, e.g. it has a mark if output is inactive - docstring const asString() const; - /// - DocIterator const & dit() const { return dit_; } /// bool isOutput() const { return output_; } /// void setAction(FuncRequest a) { action_ = a; } + /// custom action, or the default one (paragraph-goto) if not customised FuncRequest action() const; - -protected: - /// Current position of item. - DocIterator dit_; + /// + int id() const; + /// String for display, e.g. it has a mark if output is inactive + docstring const asString() const; private: + /// Current position of item. + DocIterator dit_; /// nesting depth int depth_; /// Full item string @@ -104,35 +97,6 @@ private: }; -/// Caption-enabled TOC builders -class TocBuilder -{ -public: - TocBuilder(std::shared_ptr toc); - /// When entering a float or flex or paragraph (with AddToToc) - void pushItem(DocIterator const & dit, docstring const & s, - bool output_active, bool is_captioned = false); - /// When encountering a float caption - void captionItem(DocIterator const & dit, docstring const & s, - bool output_active); - /// When encountering an argument (with isTocCaption) for flex or paragraph - void argumentItem(docstring const & arg_str); - /// When exiting a float or flex or paragraph - void pop(); -private: - TocBuilder(){} - /// - struct frame { - Toc::size_type pos; - bool is_captioned; - }; - /// - std::shared_ptr const toc_; - /// - std::stack stack_; -}; - - /// Class to build and access the Tocs of a particular buffer. class TocBackend { diff --git a/src/TocBuilder.cpp b/src/TocBuilder.cpp new file mode 100644 index 0000000000..deaace26c9 --- /dev/null +++ b/src/TocBuilder.cpp @@ -0,0 +1,92 @@ +/** + * \file TocBuilder.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Guillaume Munch + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "TocBuilder.h" + +#include "TocBackend.h" + +#include "support/lassert.h" + +using namespace std; + + +namespace lyx { + + + +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 " + dit.paragraphGotoArgument(); + if (!stack_.empty()) + arg = "paragraph-goto " + + (*toc_)[stack_.top().pos].dit().paragraphGotoArgument() + ";" + 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(); +} + + +} // namespace lyx diff --git a/src/TocBuilder.h b/src/TocBuilder.h new file mode 100644 index 0000000000..da016a632f --- /dev/null +++ b/src/TocBuilder.h @@ -0,0 +1,61 @@ +// -*- C++ -*- +/** + * \file TocBuilder.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Guillaume Munch + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef TOC_BUILDER_H +#define TOC_BUILDER_H + +#include "DocIterator.h" +#include "Toc.h" + +#include "support/strfwd.h" + +#include + + +namespace lyx { + + +/// Caption-enabled TOC builders +class TocBuilder +{ +public: + TocBuilder(std::shared_ptr toc); + /// Open a level. + /// When entering a float or flex or paragraph (with AddToToc) + void pushItem(DocIterator const & dit, docstring const & s, + bool output_active, bool is_captioned = false); + /// Edit entry at current level. Add new entry if already captioned. + /// When encountering a float caption + void captionItem(DocIterator const & dit, docstring const & s, + bool output_active); + /// Edit entry at current level (always). + /// When encountering an argument (with isTocCaption) for flex or paragraph + void argumentItem(docstring const & arg_str); + /// Close a level. + /// When exiting a float or flex or paragraph + void pop(); +private: + TocBuilder(){} + /// + struct frame { + Toc::size_type pos; + bool is_captioned; + }; + /// + std::shared_ptr const toc_; + /// + std::stack stack_; +}; + + +} // namespace lyx + +#endif // TOC_BUILDER_H