Reorganise and simplify

This commit is contained in:
Guillaume Munch 2017-01-09 23:15:16 +01:00
parent 597de9bb8d
commit 8914ddeaee
7 changed files with 183 additions and 150 deletions

View File

@ -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<docstring>(s.paragraph().id()) + ' ' +
convert<docstring>(s.pos());
}
DocIterator DocIterator::getInnerText() const
{
DocIterator texted = *this;

View File

@ -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

View File

@ -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 \

View File

@ -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<docstring>(s.paragraph().id()) + ' ' +
convert<docstring>(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 ? toc : 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::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<Toc const> 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);

View File

@ -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 <stack>
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> 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<Toc> const toc_;
///
std::stack<frame> stack_;
};
/// Class to build and access the Tocs of a particular buffer.
class TocBackend
{

92
src/TocBuilder.cpp Normal file
View File

@ -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 <config.h>
#include "TocBuilder.h"
#include "TocBackend.h"
#include "support/lassert.h"
using namespace std;
namespace lyx {
TocBuilder::TocBuilder(shared_ptr<Toc> toc)
: toc_(toc ? toc : 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 " + 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

61
src/TocBuilder.h Normal file
View File

@ -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 <stack>
namespace lyx {
/// Caption-enabled TOC builders
class TocBuilder
{
public:
TocBuilder(std::shared_ptr<Toc> 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<Toc> const toc_;
///
std::stack<frame> stack_;
};
} // namespace lyx
#endif // TOC_BUILDER_H