Extend the navigate menu to child docs

* src/buffer_funcs.h
	(updateLabels): Add bool childonly argument

	* src/insets/insetbase.h
	(addToToc): New virtual method

	* src/insets/insetinclude.[Ch]
	(addToToc): New virtual method
	(updateLabels): New method

	* src/TocBackend.h: reorganize classes so that we can forward
	declare TocList

	* src/insets/insetfloat.[Ch]
	* src/insets/insetwrap.[Ch]
	(addToToc): Adjust to type changes in TocBackend.h

	* src/frontends/qt4/TocModel.[Ch]: ditto

	* src/frontends/controllers/ControlToc.[Ch]: ditto

	* src/TocBackend.C: ditto
	(TocBackend::update) Remove test for float and wrap inset,
	call virtual method instead

	* src/BufferView.C
	(BufferView::dispatch): make LFUN_PARAGRAPH_GOTO work even if the
	target paragraph is in a different buffer

	* src/MenuBackend.C: Adjust to type changes in TocBackend.h
	(expandToc): Add an entry for the master doc in child docs

	* src/buffer_funcs.C
	(setLabel): Add text class parameter
	(updateLabels): handle included docs if requested by the caller


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15904 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2006-11-13 16:53:49 +00:00
parent b43bb0c2c2
commit 2734cc1548
17 changed files with 205 additions and 149 deletions

View File

@ -727,21 +727,34 @@ bool BufferView::dispatch(FuncRequest const & cmd)
case LFUN_PARAGRAPH_GOTO: {
int const id = convert<int>(to_utf8(cmd.argument()));
ParIterator par = buffer_->getParFromID(id);
if (par == buffer_->par_iterator_end()) {
lyxerr[Debug::INFO] << "No matching paragraph found! ["
<< id << ']' << endl;
break;
} else {
lyxerr[Debug::INFO] << "Paragraph " << par->id()
<< " found." << endl;
int i = 0;
for (Buffer * b = buffer_; i == 0 || b != buffer_; b = theBufferList().next(b)) {
ParIterator par = b->getParFromID(id);
if (par == b->par_iterator_end()) {
lyxerr[Debug::INFO]
<< "No matching paragraph found! ["
<< id << "]." << endl;
} else {
lyxerr[Debug::INFO]
<< "Paragraph " << par->id()
<< " found in buffer `"
<< b->fileName() << "'." << endl;
if (b == buffer_) {
// Set the cursor
setCursor(makeDocIterator(par, 0));
update();
switchKeyMap();
} else {
// Switch to other buffer view and resend cmd
theLyXFunc().dispatch(FuncRequest(
LFUN_BUFFER_SWITCH, b->fileName()));
theLyXFunc().dispatch(cmd);
}
break;
}
++i;
}
// Set the cursor
setCursor(makeDocIterator(par, 0));
update();
switchKeyMap();
break;
}

View File

@ -35,6 +35,7 @@
#include "lyx_main.h" // for lastfiles
#include "lyxfunc.h"
#include "lyxlex.h"
#include "paragraph.h"
#include "TocBackend.h"
#include "ToolbarBackend.h"
@ -633,22 +634,22 @@ void expandCharStyleInsert(Menu & tomenu, Buffer const * buf)
Menu::size_type const max_number_of_items = 25;
void expandToc2(Menu & tomenu,
TocBackend::Toc const & toc_list,
TocBackend::Toc::size_type from,
TocBackend::Toc::size_type to, int depth)
Toc const & toc_list,
Toc::size_type from,
Toc::size_type to, int depth)
{
int shortcut_count = 0;
// check whether depth is smaller than the smallest depth in toc.
int min_depth = 1000;
for (TocBackend::Toc::size_type i = from; i < to; ++i)
for (Toc::size_type i = from; i < to; ++i)
min_depth = std::min(min_depth, toc_list[i].depth());
if (min_depth > depth)
depth = min_depth;
if (to - from <= max_number_of_items) {
for (TocBackend::Toc::size_type i = from; i < to; ++i) {
for (Toc::size_type i = from; i < to; ++i) {
docstring label(4 * max(0, toc_list[i].depth() - depth), char_type(' '));
label += limit_string_length(toc_list[i].str());
if (toc_list[i].depth() == depth
@ -660,9 +661,9 @@ void expandToc2(Menu & tomenu,
FuncRequest(toc_list[i].action())));
}
} else {
TocBackend::Toc::size_type pos = from;
Toc::size_type pos = from;
while (pos < to) {
TocBackend::Toc::size_type new_pos = pos + 1;
Toc::size_type new_pos = pos + 1;
while (new_pos < to &&
toc_list[new_pos].depth() > depth)
++new_pos;
@ -704,10 +705,19 @@ void expandToc(Menu & tomenu, Buffer const * buf)
return;
}
// Add an entry for the master doc if this is a child doc
Buffer const * const master = buf->getMasterBuffer();
if (buf != master) {
ParIterator const pit = par_iterator_begin(master->inset());
string const arg = convert<string>(pit->id());
FuncRequest f(LFUN_PARAGRAPH_GOTO, arg);
tomenu.add(MenuItem(MenuItem::Command, _("Master Document"), f));
}
FloatList const & floatlist = buf->params().getLyXTextClass().floats();
TocBackend::TocList const & toc_list = buf->tocBackend().tocs();
TocBackend::TocList::const_iterator cit = toc_list.begin();
TocBackend::TocList::const_iterator end = toc_list.end();
TocList const & toc_list = buf->tocBackend().tocs();
TocList::const_iterator cit = toc_list.begin();
TocList::const_iterator end = toc_list.end();
for (; cit != end; ++cit) {
// Handle this later
if (cit->first == "tableofcontents")
@ -715,8 +725,8 @@ void expandToc(Menu & tomenu, Buffer const * buf)
// All the rest is for floats
auto_ptr<Menu> menu(new Menu);
TocBackend::Toc::const_iterator ccit = cit->second.begin();
TocBackend::Toc::const_iterator eend = cit->second.end();
TocIterator ccit = cit->second.begin();
TocIterator eend = cit->second.end();
for (; ccit != eend; ++ccit) {
docstring const label = limit_string_length(ccit->str());
menu->add(MenuItem(MenuItem::Command,

View File

@ -22,9 +22,7 @@
#include "paragraph.h"
#include "debug.h"
#include "insets/insetfloat.h"
#include "insets/insetoptarg.h"
#include "insets/insetwrap.h"
#include "support/convert.h"
@ -36,9 +34,9 @@ using std::string;
///////////////////////////////////////////////////////////////////////////
// TocBackend::Item implementation
// TocItem implementation
TocBackend::Item::Item(ParConstIterator const & par_it, int d,
TocItem::TocItem(ParConstIterator const & par_it, int d,
docstring const & s)
: par_it_(par_it), depth_(d), str_(s)
{
@ -71,37 +69,37 @@ TocBackend::Item::Item(ParConstIterator const & par_it, int d,
*/
}
bool const TocBackend::Item::isValid() const
bool const TocItem::isValid() const
{
return depth_ != -1;
}
int const TocBackend::Item::id() const
int const TocItem::id() const
{
return par_it_->id();
}
int const TocBackend::Item::depth() const
int const TocItem::depth() const
{
return depth_;
}
docstring const & TocBackend::Item::str() const
docstring const & TocItem::str() const
{
return str_;
}
docstring const TocBackend::Item::asString() const
docstring const TocItem::asString() const
{
return docstring(4 * depth_, ' ') + str_;
}
FuncRequest TocBackend::Item::action() const
FuncRequest TocItem::action() const
{
return FuncRequest(LFUN_PARAGRAPH_GOTO, convert<string>(id()));
}
@ -113,7 +111,7 @@ FuncRequest TocBackend::Item::action() const
///////////////////////////////////////////////////////////////////////////
// TocBackend implementation
TocBackend::Toc const & TocBackend::toc(std::string const & type) const
Toc const & TocBackend::toc(std::string const & type) const
{
// Is the type already supported?
TocList::const_iterator it = tocs_.find(type);
@ -152,20 +150,13 @@ void TocBackend::update()
// the string that goes to the toc (could be the optarg)
docstring tocstring;
// For each paragraph, traverse its insets and look for
// FLOAT_CODE or WRAP_CODE
// For each paragraph, traverse its insets and let them add
// their toc items
InsetList::const_iterator it = pit->insetlist.begin();
InsetList::const_iterator end = pit->insetlist.end();
for (; it != end; ++it) {
it->inset->addToToc(tocs_, *buffer_);
switch (it->inset->lyxCode()) {
case InsetBase::FLOAT_CODE:
static_cast<InsetFloat*>(it->inset)
->addToToc(tocs_, *buffer_);
break;
case InsetBase::WRAP_CODE:
static_cast<InsetWrap*>(it->inset)
->addToToc(tocs_, *buffer_);
break;
case InsetBase::OPTARG_CODE: {
if (!tocstring.empty())
break;
@ -188,7 +179,7 @@ void TocBackend::update()
// insert this into the table of contents
if (tocstring.empty())
tocstring = pit->asString(*buffer_, true);
Item const item(pit, toclevel - min_toclevel, tocstring);
TocItem const item(pit, toclevel - min_toclevel, tocstring);
tocs_["tableofcontents"].push_back(item);
}
}
@ -199,7 +190,7 @@ void TocBackend::update()
}
TocBackend::TocIterator const TocBackend::item(
TocIterator const TocBackend::item(
std::string const & type, ParConstIterator const & par_it) const
{
TocList::const_iterator toclist_it = tocs_.find(type);
@ -207,8 +198,8 @@ TocBackend::TocIterator const TocBackend::item(
BOOST_ASSERT(toclist_it != tocs_.end());
Toc const & toc_vector = toclist_it->second;
TocBackend::TocIterator last = toc_vector.begin();
TocBackend::TocIterator it = toc_vector.end();
TocIterator last = toc_vector.begin();
TocIterator it = toc_vector.end();
--it;
for (; it != last; --it) {
@ -234,8 +225,8 @@ void TocBackend::asciiTocList(string const & type, odocstream & os) const
{
TocList::const_iterator cit = tocs_.find(type);
if (cit != tocs_.end()) {
Toc::const_iterator ccit = cit->second.begin();
Toc::const_iterator end = cit->second.end();
TocIterator ccit = cit->second.begin();
TocIterator end = cit->second.end();
for (; ccit != end; ++ccit)
os << ccit->asString() << '\n';
}

View File

@ -35,56 +35,58 @@ class LCursor;
///
/**
*/
class TocBackend
class TocItem
{
friend class TocBackend;
public:
///
/**
*/
class Item
{
friend class TocBackend;
friend bool operator==(Item const & a, Item const & b);
public:
///
Item(
ParConstIterator const & par_it = ParConstIterator(),
int d = -1,
docstring const & s = docstring());
///
~Item() {}
///
bool const isValid() const;
///
int const id() const;
///
int const depth() const;
///
docstring const & str() const;
///
docstring const asString() const;
/// the action corresponding to the goTo above
FuncRequest action() const;
protected:
/// Current position of item.
ParConstIterator par_it_;
/// nesting depth
int depth_;
/// Full item string
docstring str_;
};
TocItem(ParConstIterator const & par_it = ParConstIterator(),
int d = -1,
docstring const & s = docstring());
///
typedef std::vector<Item> Toc;
typedef std::vector<Item>::const_iterator TocIterator;
~TocItem() {}
///
typedef std::map<std::string, Toc> TocList;
bool const isValid() const;
///
int const id() const;
///
int const depth() const;
///
docstring const & str() const;
///
docstring const asString() const;
/// the action corresponding to the goTo above
FuncRequest action() const;
protected:
/// Current position of item.
ParConstIterator par_it_;
/// nesting depth
int depth_;
/// Full item string
docstring str_;
};
///
typedef std::vector<TocItem> Toc;
typedef Toc::const_iterator TocIterator;
/// The ToC list.
/// A class and no typedef because we want to forward declare it.
class TocList : public std::map<std::string, Toc>
{
};
///
/**
*/
class TocBackend
{
public:
///
TocBackend(Buffer const * buffer = NULL): buffer_(buffer) {}
@ -121,14 +123,14 @@ private:
}; // TocBackend
inline
bool operator==(TocBackend::Item const & a, TocBackend::Item const & b)
bool operator==(TocItem const & a, TocItem const & b)
{
return a.id() == b.id() && a.str() == b.str() && a.depth() == b.depth();
}
inline
bool operator!=(TocBackend::Item const & a, TocBackend::Item const & b)
bool operator!=(TocItem const & a, TocItem const & b)
{
return !(a == b);
}

View File

@ -38,6 +38,7 @@
#include "frontends/Alert.h"
#include "insets/insetbibitem.h"
#include "insets/insetinclude.h"
#include "support/filetools.h"
#include "support/fs_extras.h"
@ -347,11 +348,9 @@ bool needEnumCounterReset(ParIterator const & it)
// set the label of a paragraph. This includes the counters.
void setLabel(Buffer const & buf, ParIterator & it)
void setLabel(Buffer const & buf, ParIterator & it, LyXTextClass const & textclass)
{
Paragraph & par = *it;
BufferParams const & bufparams = buf.params();
LyXTextClass const & textclass = bufparams.getLyXTextClass();
LyXLayout_ptr const & layout = par.layout();
Counters & counters = textclass.counters();
@ -393,7 +392,7 @@ void setLabel(Buffer const & buf, ParIterator & it)
// At some point of time we should do something more
// clever here, like:
// par.params().labelString(
// bufparams.user_defined_bullet(par.itemdepth).getText());
// buf.params().user_defined_bullet(par.itemdepth).getText());
// for now, use a simple hardcoded label
docstring itemlabel;
switch (par.itemdepth) {
@ -523,7 +522,7 @@ bool updateCurrentLabel(Buffer const & buf,
case LABEL_CENTERED_TOP_ENVIRONMENT:
case LABEL_STATIC:
case LABEL_ITEMIZE:
setLabel(buf, it);
setLabel(buf, it, buf.params().getLyXTextClass());
return true;
case LABEL_SENSITIVE:
@ -539,33 +538,44 @@ bool updateCurrentLabel(Buffer const & buf,
void updateLabels(Buffer const & buf,
ParIterator & from, ParIterator & to)
ParIterator & from, ParIterator & to, bool childonly)
{
for (ParIterator it = from; it != to; ++it) {
if (it.pit() > it.lastpit())
return;
if (!updateCurrentLabel (buf, it)) {
updateLabels(buf);
updateLabels(buf, childonly);
return;
}
}
}
void updateLabels(Buffer const & buf,
ParIterator & iter)
void updateLabels(Buffer const & buf, ParIterator & iter, bool childonly)
{
if (updateCurrentLabel(buf, iter))
return;
updateLabels(buf);
updateLabels(buf, childonly);
}
void updateLabels(Buffer const & buf)
void updateLabels(Buffer const & buf, bool childonly)
{
// start over the counters
buf.params().getLyXTextClass().counters().reset();
// Use the master text class also for child documents
LyXTextClass const & textclass = buf.params().getLyXTextClass();
if (!childonly) {
// If this is a child document start with the master
Buffer const * const master = buf.getMasterBuffer();
if (master != &buf) {
updateLabels(*master);
return;
}
// start over the counters
textclass.counters().reset();
}
ParIterator const end = par_iterator_end(buf.inset());
@ -579,7 +589,16 @@ void updateLabels(Buffer const & buf)
it->params().depth(0);
// set the counter for this paragraph
setLabel(buf, it);
setLabel(buf, it, textclass);
// Now included docs
InsetList::const_iterator iit = it->insetlist.begin();
InsetList::const_iterator end = it->insetlist.end();
for (; iit != end; ++iit) {
if (iit->inset->lyxCode() == InsetBase::INCLUDE_CODE)
static_cast<InsetInclude const *>(iit->inset)
->updateLabels(buf);
}
}
const_cast<Buffer &>(buf).tocBackend().update();

View File

@ -58,17 +58,17 @@ lyx::docstring expandLabel(Buffer const & buf,
/**
A full updateLabels(Buffer const &) will be called if not possible.
*/
void updateLabels(Buffer const & buf, ParIterator & it);
void updateLabels(Buffer const & buf, ParIterator & it, bool childonly = false);
/// update labels between "from" and "to" if possible.
/**
A full updateLabels(Buffer const &) will be called if not possible.
*/
void updateLabels(Buffer const & buf,
ParIterator & from, ParIterator & to);
ParIterator & from, ParIterator & to, bool childonly = false);
/// updates all counters
void updateLabels(Buffer const &);
void updateLabels(Buffer const &, bool childonly = false);
} // namespace lyx

View File

@ -40,7 +40,7 @@ ControlToc::ControlToc(Dialog & d)
{}
void ControlToc::goTo(TocBackend::Item const & item)
void ControlToc::goTo(TocItem const & item)
{
string const tmp = convert<string>(item.id());
kernel().lyxview().dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, tmp));
@ -83,7 +83,7 @@ vector<string> const & ControlToc::getTypes() const
}
TocBackend::Toc::const_iterator const ControlToc::getCurrentTocItem(
TocIterator const ControlToc::getCurrentTocItem(
string const & type) const
{
BOOST_ASSERT(kernel().bufferview());
@ -107,9 +107,9 @@ string const ControlToc::getGuiName(string const & type) const
}
TocBackend::Toc const empty_list;
Toc const empty_list;
TocBackend::Toc const & ControlToc::getContents(string const & type) const
Toc const & ControlToc::getContents(string const & type) const
{
// This shouldn't be possible...
if (!kernel().isBufferAvailable()) {

View File

@ -29,7 +29,7 @@ public:
ControlToc(Dialog &);
/// Goto this paragraph id
void goTo(TocBackend::Item const &);
void goTo(TocItem const &);
/// Return the list of types available
std::vector<std::string> const & getTypes() const;
@ -38,11 +38,10 @@ public:
std::string const getGuiName(std::string const & type) const;
/// Return the first TocItem before the cursor
TocBackend::Toc::const_iterator const getCurrentTocItem(
std::string const & type) const;
TocIterator const getCurrentTocItem(std::string const & type) const;
/// Given a type, returns the contents
TocBackend::Toc const & getContents(std::string const & type) const;
Toc const & getContents(std::string const & type) const;
/// Apply the selected outlining operation
void outlineUp();

View File

@ -29,13 +29,13 @@ namespace lyx {
namespace frontend {
TocModel::TocModel(TocBackend::Toc const & toc)
TocModel::TocModel(Toc const & toc)
{
populate(toc);
}
TocModel const & TocModel::operator=(TocBackend::Toc const & toc)
TocModel const & TocModel::operator=(Toc const & toc)
{
populate(toc);
return *this;
@ -72,7 +72,7 @@ void TocModel::clear()
}
void TocModel::populate(TocBackend::Toc const & toc)
void TocModel::populate(Toc const & toc)
{
clear();

View File

@ -19,13 +19,10 @@
#include <QStandardItemModel>
#include <map>
#include <string>
namespace lyx {
namespace frontend {
typedef TocBackend::Toc::const_iterator TocIterator;
class TocModel: public QStandardItemModel {
Q_OBJECT
@ -33,15 +30,15 @@ public:
///
TocModel() {}
///
TocModel(TocBackend::Toc const & toc);
TocModel(Toc const & toc);
///
~TocModel() {}
///
TocModel const & operator=(TocBackend::Toc const & toc);
TocModel const & operator=(Toc const & toc);
///
void clear();
///
void populate(TocBackend::Toc const & toc);
void populate(Toc const & toc);
///
TocIterator const tocIterator(QModelIndex const & index) const;
///

View File

@ -36,6 +36,7 @@ class MetricsInfo;
class Dimension;
class PainterInfo;
class OutputParams;
class TocList;
namespace graphics { class PreviewLoader; }
@ -381,6 +382,8 @@ public:
* defaults to empty.
*/
virtual void addPreview(graphics::PreviewLoader &) const {}
/// Add an antry to the TocList
virtual void addToToc(TocList &, Buffer const &) const {}
public:
/// returns LyX code associated with the inset. Used for TOC, ...)

View File

@ -29,13 +29,11 @@
#include "lyxlex.h"
#include "outputparams.h"
#include "paragraph.h"
#include "pariterator.h"
#include "TocBackend.h"
#include "support/lstrings.h"
#include "support/convert.h"
#include <sstream>
namespace lyx {
@ -378,7 +376,7 @@ void InsetFloat::sideways(bool s, BufferParams const & bp)
}
void InsetFloat::addToToc(TocBackend::TocList & toclist, Buffer const & buf) const
void InsetFloat::addToToc(TocList & toclist, Buffer const & buf) const
{
ParConstIterator pit = par_const_iterator_begin(*this);
ParConstIterator end = par_const_iterator_end(*this);
@ -390,7 +388,7 @@ void InsetFloat::addToToc(TocBackend::TocList & toclist, Buffer const & buf) con
docstring const str =
convert<docstring>(toclist[type].size() + 1)
+ ". " + pit->asString(buf, false);
TocBackend::Item const item(pit, 0, str);
TocItem const item(pit, 0, str);
toclist[type].push_back(item);
}
}

View File

@ -14,7 +14,6 @@
#define INSETFLOAT_H
#include "insetcollapsable.h"
#include "TocBackend.h"
#include "mailinset.h"
@ -76,7 +75,7 @@ public:
///
void sideways(bool s, BufferParams const &);
///
void addToToc(TocBackend::TocList &, Buffer const &) const;
void addToToc(TocList &, Buffer const &) const;
///
bool showInsetDialog(BufferView *) const;
///

View File

@ -30,6 +30,7 @@
#include "lyxlex.h"
#include "metricsinfo.h"
#include "outputparams.h"
#include "TocBackend.h"
#include "frontends/Alert.h"
#include "frontends/Painter.h"
@ -49,10 +50,6 @@
#include <boost/bind.hpp>
#include <boost/filesystem/operations.hpp>
#include "support/std_ostream.h"
#include <sstream>
namespace lyx {
@ -771,6 +768,31 @@ void InsetInclude::addPreview(graphics::PreviewLoader & ploader) const
}
void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer) const
{
Buffer const * const childbuffer = getChildBuffer(buffer, params_);
if (!childbuffer)
return;
TocList const & childtoclist = childbuffer->tocBackend().tocs();
TocList::const_iterator it = childtoclist.begin();
TocList::const_iterator const end = childtoclist.end();
for(; it != end; ++it)
toclist[it->first].insert(toclist[it->first].end(),
it->second.begin(), it->second.end());
}
void InsetInclude::updateLabels(Buffer const & buffer) const
{
Buffer const * const childbuffer = getChildBuffer(buffer, params_);
if (!childbuffer)
return;
lyx::updateLabels(*childbuffer, true);
}
string const InsetIncludeMailer::name_("include");
InsetIncludeMailer::InsetIncludeMailer(InsetInclude & inset)

View File

@ -92,6 +92,10 @@ public:
///
void addPreview(graphics::PreviewLoader &) const;
///
void addToToc(TocList &, Buffer const &) const;
///
void updateLabels(Buffer const & buffer) const;
///
bool getStatus(LCursor &, FuncRequest const &, FuncStatus &) const;
protected:
InsetInclude(InsetInclude const &);

View File

@ -28,7 +28,7 @@
#include "lyxlex.h"
#include "outputparams.h"
#include "paragraph.h"
#include "pariterator.h"
#include "TocBackend.h"
#include "support/convert.h"
@ -224,7 +224,7 @@ bool InsetWrap::showInsetDialog(BufferView * bv) const
}
void InsetWrap::addToToc(TocBackend::TocList & toclist, Buffer const & buf) const
void InsetWrap::addToToc(TocList & toclist, Buffer const & buf) const
{
ParConstIterator pit = par_const_iterator_begin(*this);
ParConstIterator end = par_const_iterator_end(*this);
@ -236,7 +236,7 @@ void InsetWrap::addToToc(TocBackend::TocList & toclist, Buffer const & buf) cons
docstring const str =
convert<docstring>(toclist[type].size() + 1)
+ ". " + pit->asString(buf, false);
TocBackend::Item const item(pit, 0, str);
TocItem const item(pit, 0, str);
toclist[type].push_back(item);
}
}

View File

@ -15,7 +15,6 @@
#include "insetcollapsable.h"
#include "lyxlength.h"
#include "mailinset.h"
#include "TocBackend.h"
namespace lyx {
@ -64,7 +63,7 @@ public:
///
bool insetAllowed(InsetBase::Code) const;
///
void addToToc(TocBackend::TocList &, Buffer const &) const;
void addToToc(TocList &, Buffer const &) const;
///
bool showInsetDialog(BufferView *) const;
///