And with this yet another updated patch, the dialog will automatically
update itself if a new section is created or modified or deleted... Even
Microsoft Word doesn't do this correctly :-)
Abdel.
Index: src/buffer_funcs.C
===================================================================
--- src/buffer_funcs.C (revision 13695)
+++ src/buffer_funcs.C (working copy)
@@ -33,6 +33,7 @@
#include "lyxvc.h"
#include "texrow.h"
#include "vc-backend.h"
+#include "toc.h"
#include "frontends/Alert.h"
@@ -513,8 +514,11 @@
ParIterator & it)
{
if (it == par_iterator_end(buf.inset()))
- return true;
-
+ return false;
+
+// if (it.lastpit == 0 && LyXText::isMainText())
+// return false;
+
switch (it->layout()->labeltype) {
case LABEL_NO_LABEL:
@@ -582,6 +586,8 @@
// set the counter for this paragraph
setLabel(buf, it);
}
+
+ lyx::toc::updateToc(buf);
}
Index: src/frontends/controllers/ControlToc.C
===================================================================
--- src/frontends/controllers/ControlToc.C (revision 13695)
+++ src/frontends/controllers/ControlToc.C (working copy)
@@ -16,6 +16,7 @@
#include "funcrequest.h"
#include "gettext.h"
#include "BufferView.h"
+#include "debug.h"
using std::vector;
using std::string;
@@ -52,20 +53,19 @@
}
-vector<string> const ControlToc::getTypes() const
+vector<string> const & ControlToc::getTypes() const
{
return toc::getTypes(kernel().buffer());
}
-toc::TocItem const ControlToc::getCurrentTocItem(
+toc::TocIterator const ControlToc::getCurrentTocItem(
string const & type) const
{
- BufferView const * const bv = kernel().bufferview();
- if (!bv)
- return toc::TocItem(-1, -1, "");
+ BOOST_ASSERT(kernel().bufferview());
- return toc::getCurrentTocItem(kernel().buffer(), bv->cursor(), type);
+ return toc::getCurrentTocItem(kernel().buffer(),
+ kernel().bufferview()->cursor(), type);
}
@@ -78,22 +78,16 @@
}
-toc::Toc const ControlToc::getContents(string const & type) const
-{
- toc::Toc empty_list;
+toc::Toc const empty_list;
+toc::Toc const & ControlToc::getContents(string const & type) const
+{
// This shouldn't be possible...
if (!kernel().isBufferAvailable()) {
return empty_list;
}
- toc::TocList tmp = toc::getTocList(kernel().buffer());
- toc::TocList::iterator it = tmp.find(type);
- if (it == tmp.end()) {
- return empty_list;
- }
-
- return it->second;
+ return toc::getToc(kernel().buffer(), type);
}
} // namespace frontend
Index: src/frontends/controllers/ControlToc.h
===================================================================
--- src/frontends/controllers/ControlToc.h (revision 13695)
+++ src/frontends/controllers/ControlToc.h (working copy)
@@ -31,17 +31,17 @@
void goTo(toc::TocItem const &);
/// Return the list of types available
- std::vector<std::string> const getTypes() const;
+ std::vector<std::string> const & getTypes() const;
/// Return the guiname from a given cmdName of the TOC param
std::string const getGuiName(std::string const & type) const;
/// Return the first TocItem before the cursor
- toc::TocItem const getCurrentTocItem(
+ toc::TocIterator const getCurrentTocItem(
std::string const & type) const;
/// Given a type, returns the contents
- toc::Toc const getContents(std::string const & type) const;
+ toc::Toc const & getContents(std::string const & type) const;
/// Apply the selected outlining operation
void outline(toc::OutlineOp op);
Index: src/frontends/qt2/QToc.C
===================================================================
--- src/frontends/qt2/QToc.C (revision 13707)
+++ src/frontends/qt2/QToc.C (working copy)
@@ -116,21 +116,21 @@
for (toc::Toc::const_iterator iter = toclist.begin();
iter != toclist.end(); ++iter) {
- if (iter->depth == curdepth) {
+ if (iter->depth() == curdepth) {
// insert it after the last one we processed
if (!parent)
item = (last ? new
QListViewItem(dialog_->tocLV,last) : new QListViewItem(dialog_->tocLV));
else
item = (last ? new QListViewItem(parent,last) :
new QListViewItem(parent));
- } else if (iter->depth > curdepth) {
- int diff = iter->depth - curdepth;
+ } else if (iter->depth() > curdepth) {
+ int diff = iter->depth() - curdepth;
// first save old parent and last
while (diff--)
istack.push(pair< QListViewItem *,
QListViewItem * >(parent,last));
item = (last ? new QListViewItem(last) : new
QListViewItem(dialog_->tocLV));
parent = last;
} else {
- int diff = curdepth - iter->depth;
+ int diff = curdepth - iter->depth();
pair<QListViewItem *, QListViewItem * > top;
// restore context
while (diff--) {
@@ -148,20 +148,20 @@
lyxerr[Debug::GUI]
<< "Table of contents\n"
- << "Added item " << iter->str
- << " at depth " << iter->depth
+ << "Added item " << iter->str()
+ << " at depth " << iter->depth()
<< ", previous sibling \""
<< (last ? fromqstr(last->text(0)) : "0")
<< "\", parent \""
<< (parent ? fromqstr(parent->text(0)) : "0") << '"'
<< endl;
- item->setText(0, toqstr(iter->str));
- item->setOpen(iter->depth < depth_);
- curdepth = iter->depth;
+ item->setText(0, toqstr(iter->str()));
+ item->setOpen(iter->depth() < depth_);
+ curdepth = iter->depth();
last = item;
// Recognise part past the counter
- if (iter->str.substr(iter->str.find(' ') + 1) == text_) {
+ if (iter->str().substr(iter->str().find(' ') + 1) == text_) {
if (selected_item == 0)
selected_item = item;
else
@@ -186,7 +186,7 @@
toc::Toc::const_iterator iter = toclist.begin();
for (; iter != toclist.end(); ++iter) {
- if (iter->str == text)
+ if (iter->str() == text)
break;
}
Index: src/frontends/qt4/QToc.C
===================================================================
--- src/frontends/qt4/QToc.C (revision 13695)
+++ src/frontends/qt4/QToc.C (working copy)
@@ -31,6 +31,7 @@
namespace lyx {
namespace frontend {
+
QToc::QToc(Dialog & parent)
: ControlToc(parent)
{
@@ -76,17 +77,13 @@
QModelIndex const QToc::getCurrentIndex()
{
vector<string> const & types = getTypes();
- toc::TocItem const item = getCurrentTocItem(types[type_]);
- if (item.id_ == -1) {
- lyxerr[Debug::GUI]
- << "QToc::getCurrentIndex(): TocItem is invalid!" <<
endl;
+ TocIterator const it = getCurrentTocItem(types[type_]);
+ if (!it->isValid()) {
+ lyxerr[Debug::GUI] << "QToc::getCurrentIndex(): TocItem is
invalid!" << endl;
return QModelIndex();
}
- string toc_str = item.str;
- toc_str.erase(0, toc_str.find(' ') + 1);
-
- return toc_models_[type_]->index(toc_str);
+ return toc_models_[type_]->modelIndex(it);
}
@@ -98,12 +95,14 @@
<< endl;
return;
}
+
+ TocIterator const it = toc_models_[type_]->tocIterator(index);
lyxerr[Debug::GUI]
- << "QToc::goTo " << toc_models_[type_]->item(index).str
+ << "QToc::goTo " << it->str()
<< endl;
- ControlToc::goTo(toc_models_[type_]->item(index));
+ it->goTo(kernel().lyxview());
}
@@ -139,27 +138,15 @@
void QToc::updateToc(int type)
{
- vector<string> const & choice = getTypes();
-
- toc_models_[type] = new TocModel(getContents(choice[type]));
+ toc_models_[type] = new TocModel(getContents(getTypes()[type]));
}
-void QToc::move(toc::OutlineOp const operation, QModelIndex & index)
+void QToc::move(toc::OutlineOp const operation)
{
- int toc_id = toc_models_[type_]->item(index).id_;
- string toc_str = toc_models_[type_]->item(index).str;
- toc_str.erase(0, toc_str.find(' ') + 1);
-
outline(operation);
- updateToc(type_);
-
- lyxerr[Debug::GUI]
- << "Toc id " << toc_id
- << " Toc str " << toc_str
- << endl;
-
- index = toc_models_[type_]->index(toc_str);
+// updateToc(type_);
+ update();
}
} // namespace frontend
Index: src/frontends/qt4/QToc.h
===================================================================
--- src/frontends/qt4/QToc.h (revision 13695)
+++ src/frontends/qt4/QToc.h (working copy)
@@ -48,7 +48,7 @@
///
void goTo(QModelIndex const & index);
- void move(toc::OutlineOp const operation, QModelIndex & index);
+ void move(toc::OutlineOp const operation);
private:
Index: src/frontends/qt4/QTocDialog.C
===================================================================
--- src/frontends/qt4/QTocDialog.C (revision 13695)
+++ src/frontends/qt4/QTocDialog.C (working copy)
@@ -43,7 +43,7 @@
{
setupUi(this);
- update();
+ updateGui();
connect(tocTV->selectionModel(),
SIGNAL(currentChanged(const QModelIndex &,
@@ -88,7 +88,6 @@
void QTocDialog::on_updatePB_clicked()
{
- form_->update();
update();
}
@@ -103,9 +102,9 @@
/*
while (
tocTv->setExpanded();
- if (iter->depth > depth_)
+ if (iter->depth() > depth_)
tocTV->collapseItem(topLevelItem);
- else if (iter->depth <= depth_)
+ else if (iter->depth() <= depth_)
tocTV->expandItem(topLevelItem);
*/
}
@@ -147,14 +146,16 @@
enableButtons(false);
QModelIndex index = tocTV->selectionModel()->selectedIndexes()[0];
form_->goTo(index);
- form_->move(operation, index);
- select(index);
- enableButtons();
+ form_->move(operation);
+ updateGui();
+// select(index);
+// enableButtons();
}
+
void QTocDialog::select(QModelIndex const & index)
{
- tocTV->setModel(form_->tocModel());
+// tocTV->setModel(form_->tocModel());
if (!index.isValid()) {
lyxerr[Debug::GUI]
@@ -166,6 +167,7 @@
tocTV->selectionModel()->select(index, QItemSelectionModel::Select);
}
+
void QTocDialog::enableButtons(bool enable)
{
updatePB->setEnabled(enable);
@@ -182,6 +184,13 @@
void QTocDialog::update()
{
+ form_->update();
+ updateGui();
+}
+
+
+void QTocDialog::updateGui()
+{
typeCO->setModel(form_->typeModel());
tocTV->setModel(form_->tocModel());
tocTV->showColumn(0);
@@ -223,7 +232,6 @@
void QTocDialog::show()
{
- form_->update();
update();
QDialog::show();
}
Index: src/frontends/qt4/QTocDialog.h
===================================================================
--- src/frontends/qt4/QTocDialog.h (revision 13695)
+++ src/frontends/qt4/QTocDialog.h (working copy)
@@ -46,6 +46,9 @@
/// Update the display of the dialog whilst it is still visible.
void update();
+ /// Update Gui of the display.
+ void updateGui();
+
/// \return true if the dialog is visible.
bool isVisible() const;
Index: src/frontends/qt4/TocModel.C
===================================================================
--- src/frontends/qt4/TocModel.C (revision 13695)
+++ src/frontends/qt4/TocModel.C (working copy)
@@ -25,80 +25,81 @@
namespace lyx {
namespace frontend {
+
-
-TocModel::TocModel(toc::Toc const & toc_list)
+TocModel::TocModel(TocBackend::Toc const & toc)
{
- populate(toc_list);
+ populate(toc);
}
-TocModel const & TocModel::operator=(toc::Toc const & toc_list)
+TocModel const & TocModel::operator=(TocBackend::Toc const & toc)
{
- populate(toc_list);
+ populate(toc);
return *this;
}
+
-toc::TocItem const TocModel::item(QModelIndex const & index) const
+TocIterator const TocModel::tocIterator(QModelIndex const & index) const
{
- ItemMap::const_iterator it = item_map_.find(index);
- BOOST_ASSERT(it != item_map_.end());
-
- return it->second;
+ TocMap::const_iterator map_it = toc_map_.find(index);
+ BOOST_ASSERT(map_it != toc_map_.end());
+ return map_it->second;
}
+
-QModelIndex const TocModel::index(string const & toc_str) const
+QModelIndex const TocModel::modelIndex(TocIterator const & it) const
{
- IndexMap::const_iterator it = index_map_.find(toc_str);
- //BOOST_ASSERT(it != index_map_.end());
+ ModelMap::const_iterator map_it = model_map_.find(it);
+ //BOOST_ASSERT(it != model_map_.end());
- if (it == index_map_.end())
+ if (map_it == model_map_.end())
return QModelIndex();
- return it->second;
+ return map_it->second;
}
+
void TocModel::clear()
{
QStandardItemModel::clear();
- item_map_.clear();
- index_map_.clear();
+ toc_map_.clear();
+ model_map_.clear();
removeRows(0, rowCount());
removeColumns(0, columnCount());
}
-void TocModel::populate(toc::Toc const & toc_list)
+void TocModel::populate(TocBackend::Toc const & toc)
{
clear();
- if (toc_list.empty())
+ if (toc.empty())
return;
int current_row;
QModelIndex top_level_item;
- toc::Toc::const_iterator iter = toc_list.begin();
- toc::Toc::const_iterator end = toc_list.end();
+ TocIterator iter = toc.begin();
+ TocIterator end = toc.end();
insertColumns(0, 1);
while (iter != end) {
- if (iter->depth == 1) {
+ if (iter->depth() >= 1) {
current_row = rowCount();
insertRows(current_row, 1);
top_level_item = QStandardItemModel::index(current_row,
0);
- //setData(top_level_item, toqstr(iter->str));
- setData(top_level_item, toqstr(iter->str),
Qt::DisplayRole);
- item_map_.insert(make_pair(top_level_item, *iter));
- index_map_.insert(make_pair(
- iter->str.substr(iter->str.find(' ') + 1),
top_level_item));
+ //setData(top_level_item, toqstr(iter->str()));
+ setData(top_level_item, toqstr(iter->str()),
Qt::DisplayRole);
+ toc_map_.insert(make_pair(top_level_item, iter));
+ model_map_.insert(make_pair(iter, top_level_item));
lyxerr[Debug::GUI]
- << "Toc: at depth " << iter->depth
- << ", added item " << iter->str
+ << "Toc: at depth " << iter->depth()
+ << ", added item " << iter->str()
<< endl;
populate(iter, end, top_level_item);
@@ -115,11 +116,11 @@
}
-void TocModel::populate(toc::Toc::const_iterator & iter,
- toc::Toc::const_iterator const
& end,
+void TocModel::populate(TocIterator & iter,
+ TocIterator const & end,
QModelIndex const & parent)
{
- int curdepth = iter->depth + 1;
+ int curdepth = iter->depth() + 1;
int current_row;
QModelIndex child_item;
@@ -131,31 +132,31 @@
if (iter == end)
break;
- if (iter->depth < curdepth) {
+ if (iter->depth() < curdepth) {
--iter;
return;
}
- if (iter->depth > curdepth) {
+ if (iter->depth() > curdepth) {
return;
}
current_row = rowCount(parent);
insertRows(current_row, 1, parent);
child_item = QStandardItemModel::index(current_row, 0, parent);
- //setData(child_item, toqstr(iter->str));
- setData(child_item, toqstr(iter->str), Qt::DisplayRole);
- item_map_.insert(make_pair(child_item, *iter));
- index_map_.insert(make_pair(
- iter->str.substr(iter->str.find(' ') + 1), child_item));
+ //setData(child_item, toqstr(iter->str()));
+ setData(child_item, toqstr(iter->str()), Qt::DisplayRole);
+ toc_map_.insert(make_pair(child_item, iter));
+ model_map_.insert(make_pair(iter, child_item));
// lyxerr[Debug::GUI]
-// << "Toc: at depth " << iter->depth
-// << ", added item " << iter->str
+// << "Toc: at depth " << iter->depth()
+// << ", added item " << iter->str()
// << endl;
populate(iter, end, child_item);
}
}
+
} // namespace frontend
} // namespace lyx
Index: src/frontends/qt4/TocModel.h
===================================================================
--- src/frontends/qt4/TocModel.h (revision 13695)
+++ src/frontends/qt4/TocModel.h (working copy)
@@ -12,7 +12,7 @@
#ifndef TOCMODEL_H
#define TOCMODEL_H
-#include "toc.h"
+#include "TocBackend.h"
#include "qt_helpers.h"
@@ -24,38 +24,42 @@
namespace lyx {
namespace frontend {
+typedef TocBackend::Toc::const_iterator TocIterator;
+
class TocModel: public QStandardItemModel {
Q_OBJECT
+
public:
///
TocModel() {}
///
- TocModel(toc::Toc const & toc_list);
+ TocModel(TocBackend::Toc const & toc);
///
~TocModel() {}
///
- TocModel const & operator=(toc::Toc const & toc_list);
+ TocModel const & operator=(TocBackend::Toc const & toc);
///
void clear();
///
- void populate(toc::Toc const & toc_list);
+ void populate(TocBackend::Toc const & toc);
///
- toc::TocItem const item(QModelIndex const & index) const;
+ TocIterator const tocIterator(QModelIndex const & index) const;
///
- QModelIndex const index(std::string const & toc_str) const;
+ QModelIndex const modelIndex(TocIterator const & it) const;
private:
///
- void populate(toc::Toc::const_iterator & iter,
- toc::Toc::const_iterator const & end,
- QModelIndex const & parent);
-
- typedef std::map<QModelIndex, toc::TocItem> ItemMap;
+ void populate(TocIterator & it,
+ TocIterator const & end,
+ QModelIndex const & parent);
///
- typedef std::map<std::string, QModelIndex> IndexMap;
+ typedef std::map<QModelIndex, TocIterator> TocMap;
///
- ItemMap item_map_;
- IndexMap index_map_;
+ typedef std::map<TocIterator, QModelIndex> ModelMap;
+ ///
+ TocMap toc_map_;
+ ///
+ ModelMap model_map_;
};
} // namespace frontend
Index: src/insets/insetfloat.C
===================================================================
--- src/insets/insetfloat.C (revision 13695)
+++ src/insets/insetfloat.C (working copy)
@@ -438,7 +438,7 @@
string const str =
convert<string>(toclist[type].size() + 1)
+ ". " + pit->asString(buf, false);
- lyx::toc::TocItem const item(pit->id(), 0 , str);
+ lyx::toc::TocItem const item(pit, 0 , str);
toclist[type].push_back(item);
}
}
Index: src/insets/insetwrap.C
===================================================================
--- src/insets/insetwrap.C (revision 13695)
+++ src/insets/insetwrap.C (working copy)
@@ -246,7 +246,7 @@
string const str =
convert<string>(toclist[type].size() + 1)
+ ". " + pit->asString(buf, false);
- lyx::toc::TocItem const item(pit->id(), 0 , str);
+ lyx::toc::TocItem const item(pit, 0 , str);
toclist[type].push_back(item);
}
}
Index: src/Makefile.am
===================================================================
--- src/Makefile.am (revision 13695)
+++ src/Makefile.am (working copy)
@@ -280,6 +280,8 @@
text.C \
text2.C \
text3.C \
+ TocBackend.C \
+ TocBackend.h \
toc.C \
toc.h \
trans.C \
Index: src/MenuBackend.C
===================================================================
--- src/MenuBackend.C (revision 13695)
+++ src/MenuBackend.C (working copy)
@@ -615,16 +615,16 @@
// check whether depth is smaller than the smallest depth in toc.
int min_depth = 1000;
for (lyx::toc::Toc::size_type i = from; i < to; ++i)
- min_depth = std::min(min_depth, toc_list[i].depth);
+ 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 (lyx::toc::Toc::size_type i = from; i < to; ++i) {
- string label(4 * max(0, toc_list[i].depth - depth),' ');
- label += limit_string_length(toc_list[i].str);
- if (toc_list[i].depth == depth
+ string label(4 * max(0, toc_list[i].depth() - depth),'
');
+ label += limit_string_length(toc_list[i].str());
+ if (toc_list[i].depth() == depth
&& shortcut_count < 9) {
if (label.find(convert<string>(shortcut_count +
1)) != string::npos)
label += '|' +
convert<string>(++shortcut_count);
@@ -637,12 +637,12 @@
while (pos < to) {
lyx::toc::Toc::size_type new_pos = pos + 1;
while (new_pos < to &&
- toc_list[new_pos].depth > depth)
+ toc_list[new_pos].depth() > depth)
++new_pos;
- string label(4 * max(0, toc_list[pos].depth - depth), '
');
- label += limit_string_length(toc_list[pos].str);
- if (toc_list[pos].depth == depth &&
+ string label(4 * max(0, toc_list[pos].depth() - depth),
' ');
+ label += limit_string_length(toc_list[pos].str());
+ if (toc_list[pos].depth() == depth &&
shortcut_count < 9) {
if (label.find(convert<string>(shortcut_count +
1)) != string::npos)
label += '|' +
convert<string>(++shortcut_count);
@@ -681,7 +681,7 @@
}
FloatList const & floatlist = buf->params().getLyXTextClass().floats();
- lyx::toc::TocList toc_list = lyx::toc::getTocList(*buf);
+ lyx::toc::TocList const & toc_list = lyx::toc::getTocList(*buf);
lyx::toc::TocList::const_iterator cit = toc_list.begin();
lyx::toc::TocList::const_iterator end = toc_list.end();
for (; cit != end; ++cit) {
@@ -694,7 +694,7 @@
lyx::toc::Toc::const_iterator ccit = cit->second.begin();
lyx::toc::Toc::const_iterator eend = cit->second.end();
for (; ccit != eend; ++ccit) {
- string const label = limit_string_length(ccit->str);
+ string const label = limit_string_length(ccit->str());
menu->add(MenuItem(MenuItem::Command,
label,
FuncRequest(ccit->action())));
Index: src/pariterator.h
===================================================================
--- src/pariterator.h (revision 13695)
+++ src/pariterator.h (working copy)
@@ -93,6 +93,8 @@
{
public:
///
+ ParConstIterator(): DocIterator() {}
+ ///
ParConstIterator(ParConstIterator const &);
///
ParConstIterator(DocIterator const &);
Index: src/toc.C
===================================================================
--- src/toc.C (revision 13695)
+++ src/toc.C (working copy)
@@ -31,181 +31,95 @@
#include "support/convert.h"
+#include <iostream>
+#include <map>
+
+using std::map;
+using std::pair;
+using std::make_pair;
using std::vector;
using std::max;
using std::ostream;
using std::string;
+using std::cout;
+using std::endl;
namespace lyx {
namespace toc {
-string const TocItem::asString() const
-{
- return string(4 * depth, ' ') + str;
-}
+typedef map<Buffer const *, lyx::TocBackend> TocMap;
+static TocMap toc_backend_;
+///////////////////////////////////////////////////////////////////////////
+// Interface to toc_backend_
-void TocItem::goTo(LyXView & lv_) const
+void updateToc(Buffer const & buf)
{
- string const tmp = convert<string>(id_);
- lv_.dispatch(FuncRequest(LFUN_GOTO_PARAGRAPH, tmp));
-}
+ TocMap::iterator it = toc_backend_.find(&buf);
+ if (it == toc_backend_.end()) {
+ pair<TocMap::iterator, bool> result
+ = toc_backend_.insert(make_pair(&buf,
TocBackend(&buf)));
+ if (!result.second)
+ return;
+ it = result.first;
+ }
-FuncRequest TocItem::action() const
-{
- return FuncRequest(LFUN_GOTO_PARAGRAPH, convert<string>(id_));
+ it->second.update();
}
-string const getType(string const & cmdName)
+TocList const & getTocList(Buffer const & buf)
{
- // special case
- if (cmdName == "tableofcontents")
- return "TOC";
- else
- return cmdName;
+ return toc_backend_[&buf].tocs();
}
-string const getGuiName(string const & type, Buffer const & buffer)
+Toc const & getToc(Buffer const & buf, std::string const & type)
{
- FloatList const & floats =
- buffer.params().getLyXTextClass().floats();
- if (floats.typeExist(type))
- return floats.getType(type).name();
- else
- return type;
+ return toc_backend_[&buf].toc(type);
}
-TocList const getTocList(Buffer const & buf)
+TocIterator const getCurrentTocItem(Buffer const & buf, LCursor const & cur,
+ std::string
const & type)
{
- TocList toclist;
-
- BufferParams const & bufparams = buf.params();
- const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
-
- ParConstIterator pit = buf.par_iterator_begin();
- ParConstIterator end = buf.par_iterator_end();
- for (; pit != end; ++pit) {
-
- // the string that goes to the toc (could be the optarg)
- string tocstring;
-
- // For each paragraph, traverse its insets and look for
- // FLOAT_CODE or WRAP_CODE
- InsetList::const_iterator it = pit->insetlist.begin();
- InsetList::const_iterator end = pit->insetlist.end();
- for (; it != end; ++it) {
- switch (it->inset->lyxCode()) {
- case InsetBase::FLOAT_CODE:
- static_cast<InsetFloat*>(it->inset)
- ->addToToc(toclist, buf);
- break;
- case InsetBase::WRAP_CODE:
- static_cast<InsetWrap*>(it->inset)
- ->addToToc(toclist, buf);
- break;
- case InsetBase::OPTARG_CODE: {
- if (!tocstring.empty())
- break;
- Paragraph const & par =
*static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();
- if (!pit->getLabelstring().empty())
- tocstring = pit->getLabelstring()
- + ' ';
- tocstring += par.asString(buf, false);
- break;
- }
- default:
- break;
- }
- }
-
- /// now the toc entry for the paragraph
- int const toclevel = pit->layout()->toclevel;
- if (toclevel != LyXLayout::NOT_IN_TOC
- && toclevel >= min_toclevel
- && toclevel <= bufparams.tocdepth) {
- // insert this into the table of contents
- if (tocstring.empty())
- tocstring = pit->asString(buf, true);
- TocItem const item(pit->id(), toclevel - min_toclevel,
- tocstring);
- toclist["TOC"].push_back(item);
- }
- }
- return toclist;
+ return toc_backend_[&buf].item(type, ParConstIterator(cur));
}
-TocItem const getCurrentTocItem(Buffer const & buf, LCursor const & cur,
- std::string
const & type)
+vector<string> const & getTypes(Buffer const & buf)
{
- // This should be cached:
- TocList tmp = getTocList(buf);
-
- // Is the type supported?
- /// \todo TocItem() should create an invalid TocItem()
- /// \todo create TocItem::isValid()
- TocList::iterator toclist_it = tmp.find(type);
- if (toclist_it == tmp.end())
- return TocItem(-1, -1, string());
-
- Toc const toc_vector = toclist_it->second;
- ParConstIterator const current(cur);
- int start = toc_vector.size() - 1;
-
- /// \todo cache the ParConstIterator values inside TocItem
- for (int i = start; i >= 0; --i) {
-
- ParConstIterator const it
- = buf.getParFromID(toc_vector[i].id_);
-
- // A good solution for TocItems inside insets would be to do:
- //
- //if (std::distance(it, current) <= 0)
- // return toc_vector[i];
- //
- // But for an unknown reason, std::distance(current, it) always
- // returns a positive value and std::distance(it, current)
takes forever...
- // So for now, we do:
- if (it.pit() <= current.pit())
- return toc_vector[i];
- }
-
- // We are before the first TocItem:
- return toc_vector[0];
+ return toc_backend_[&buf].types();
}
-vector<string> const getTypes(Buffer const & buffer)
+void asciiTocList(string const & type, Buffer const & buf, ostream & os)
{
- vector<string> types;
+ toc_backend_[&buf].asciiTocList(type, os);
+}
- TocList const tmp = getTocList(buffer);
+///////////////////////////////////////////////////////////////////////////
+// Other functions
- TocList::const_iterator cit = tmp.begin();
- TocList::const_iterator end = tmp.end();
-
- for (; cit != end; ++cit) {
- types.push_back(cit->first);
- }
-
- return types;
+string const getType(string const & cmdName)
+{
+ // special case
+ if (cmdName == "tableofcontents")
+ return "TOC";
+ else
+ return cmdName;
}
-void asciiTocList(string const & type, Buffer const & buffer, ostream & os)
+string const getGuiName(string const & type, Buffer const & buffer)
{
- TocList const toc_list = getTocList(buffer);
- TocList::const_iterator cit = toc_list.find(type);
- if (cit != toc_list.end()) {
- Toc::const_iterator ccit = cit->second.begin();
- Toc::const_iterator end = cit->second.end();
- for (; ccit != end; ++ccit)
- os << ccit->asString() << '\n';
- }
+ FloatList const & floats =
+ buffer.params().getLyXTextClass().floats();
+ if (floats.typeExist(type))
+ return floats.getType(type).name();
+ else
+ return type;
}
Index: src/toc.h
===================================================================
--- src/toc.h (revision 13695)
+++ src/toc.h (working copy)
@@ -15,55 +15,33 @@
#ifndef TOC_H
#define TOC_H
-#include <map>
-#include <iosfwd>
-#include <vector>
-#include <string>
+#include "TocBackend.h"
-#include "pariterator.h"
-
-class Buffer;
-class LyXView;
-class Paragraph;
-class FuncRequest;
class LCursor;
namespace lyx {
namespace toc {
+typedef TocBackend::Item TocItem;
+typedef TocBackend::Toc::const_iterator TocIterator;
+typedef TocBackend::Toc Toc;
+typedef TocBackend::TocList TocList;
+
///
-class TocItem {
-public:
- TocItem(int par_id, int d, std::string const & s)
- : id_(par_id), depth(d), str(s) {}
- ///
- std::string const asString() const;
- /// set cursor in LyXView to this TocItem
- void goTo(LyXView & lv_) const;
- /// the action corresponding to the goTo above
- FuncRequest action() const;
- /// Paragraph ID containing this item
- int id_;
- /// nesting depth
- int depth;
- ///
- std::string str;
-};
+void updateToc(Buffer const &);
///
-typedef std::vector<TocItem> Toc;
-///
-typedef std::map<std::string, Toc> TocList;
+TocList const & getTocList(Buffer const &);
///
-TocList const getTocList(Buffer const &);
+Toc const & getToc(Buffer const & buf, std::string const & type);
///
-std::vector<std::string> const getTypes(Buffer const &);
+std::vector<std::string> const & getTypes(Buffer const &);
/// Return the first TocItem before the cursor
-TocItem const getCurrentTocItem(Buffer const &, LCursor const &,
- std::string
const & type);
+TocIterator const getCurrentTocItem(Buffer const &, LCursor const &,
+
std::string const & type);
///
void asciiTocList(std::string const &, Buffer const &, std::ostream &);
@@ -76,21 +54,6 @@
The localization of the names will be done in the frontends */
std::string const getGuiName(std::string const & type, Buffer const &);
-inline
-bool operator==(TocItem const & a, TocItem const & b)
-{
- return a.id_ == b.id_ && a.str == b.str;
- // No need to compare depth.
-}
-
-
-inline
-bool operator!=(TocItem const & a, TocItem const & b)
-{
- return !(a == b);
-}
-
-
/// the type of outline operation
enum OutlineOp {
UP, // Move this header with text down
Index: src/TocBackend.C
===================================================================
--- src/TocBackend.C (revision 0)
+++ src/TocBackend.C (revision 0)
@@ -0,0 +1,261 @@
+/**
+ * \file TocBackend.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "toc.h"
+
+#include "buffer.h"
+#include "bufferparams.h"
+#include "FloatList.h"
+#include "funcrequest.h"
+#include "LyXAction.h"
+#include "paragraph.h"
+#include "cursor.h"
+#include "debug.h"
+
+#include "frontends/LyXView.h"
+
+#include "insets/insetfloat.h"
+#include "insets/insetoptarg.h"
+#include "insets/insetwrap.h"
+
+#include "support/convert.h"
+
+#include <iostream>
+
+using std::vector;
+using std::max;
+using std::ostream;
+using std::string;
+using std::cout;
+using std::endl;
+
+namespace lyx {
+
+///////////////////////////////////////////////////////////////////////////
+// TocBackend::Item implementation
+
+TocBackend::Item::Item(ParConstIterator const & par_it, int d,
+ std::string const & s)
+ : par_it_(par_it), depth_(d), str_(s)
+{
+/*
+ if (!uid_.empty())
+ return;
+
+ size_t pos = s.find(" ");
+ if (pos == string::npos) {
+ // Non labelled item
+ uid_ = s;
+ return;
+ }
+
+ string s2 = s.substr(0, pos);
+
+ if (s2 == "Chapter" || s2 == "Part") {
+ size_t pos2 = s.find(" ", pos + 1);
+ if (pos2 == string::npos) {
+ // Unnumbered Chapter?? This should not happen.
+ uid_ = s.substr(pos + 1);
+ return;
+ }
+ // Chapter or Part
+ uid_ = s.substr(pos2 + 1);
+ return;
+ }
+ // Numbered Item.
+ uid_ = s.substr(pos + 1);
+ */
+}
+
+bool const TocBackend::Item::isValid() const
+{
+ return depth_ != -1;
+}
+
+
+int const TocBackend::Item::id() const
+{
+ return par_it_->id();
+}
+
+
+int const TocBackend::Item::depth() const
+{
+ return depth_;
+}
+
+
+std::string const & TocBackend::Item::str() const
+{
+ return str_;
+}
+
+
+string const TocBackend::Item::asString() const
+{
+ return string(4 * depth_, ' ') + str_;
+}
+
+
+void TocBackend::Item::goTo(LyXView & lv_) const
+{
+ string const tmp = convert<string>(id());
+ lv_.dispatch(FuncRequest(LFUN_GOTO_PARAGRAPH, tmp));
+}
+
+FuncRequest TocBackend::Item::action() const
+{
+ return FuncRequest(LFUN_GOTO_PARAGRAPH, convert<string>(id()));
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// TocBackend implementation
+
+TocBackend::Toc const & TocBackend::toc(std::string const & type)
+{
+ // Is the type already supported?
+ TocList::const_iterator it = tocs_.find(type);
+ if (it == tocs_.end())
+ return empty_toc_;
+
+ return it->second;
+}
+
+
+bool TocBackend::addType(std::string const & type)
+{
+ // Is the type already supported?
+ TocList::iterator toclist_it = tocs_.find(type);
+ if (toclist_it != tocs_.end())
+ return false;
+
+ tocs_.insert(make_pair(type, Toc()));
+ types_.push_back(type);
+
+ return true;
+}
+
+
+void TocBackend::update()
+{
+ tocs_.clear();
+ types_.clear();
+
+ BufferParams const & bufparams = buffer_->params();
+ const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
+
+ ParConstIterator pit = buffer_->par_iterator_begin();
+ ParConstIterator end = buffer_->par_iterator_end();
+ for (; pit != end; ++pit) {
+
+ // the string that goes to the toc (could be the optarg)
+ string tocstring;
+
+ // For each paragraph, traverse its insets and look for
+ // FLOAT_CODE or WRAP_CODE
+ InsetList::const_iterator it = pit->insetlist.begin();
+ InsetList::const_iterator end = pit->insetlist.end();
+ for (; it != end; ++it) {
+ 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;
+ Paragraph const & par =
*static_cast<InsetOptArg*>(it->inset)->paragraphs().begin();
+ if (!pit->getLabelstring().empty())
+ tocstring = pit->getLabelstring()
+ + ' ';
+ tocstring += par.asString(*buffer_, false);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /// now the toc entry for the paragraph
+ int const toclevel = pit->layout()->toclevel;
+ if (toclevel != LyXLayout::NOT_IN_TOC
+ && toclevel >= min_toclevel
+ && toclevel <= bufparams.tocdepth) {
+ // insert this into the table of contents
+ if (tocstring.empty())
+ tocstring = pit->asString(*buffer_, true);
+ Item const item(pit, toclevel - min_toclevel,
tocstring);
+ tocs_["TOC"].push_back(item);
+ //cout << "item inserted str " << item.str()
+ // << " id " << item.id() << endl;
+ }
+ }
+
+ TocList::iterator it = tocs_.begin();
+ for (; it != tocs_.end(); ++it)
+ types_.push_back(it->first);
+}
+
+
+TocBackend::TocIterator const TocBackend::item(std::string const & type,
ParConstIterator const & par_it)
+{
+ TocList::iterator toclist_it = tocs_.find(type);
+ // Is the type supported?
+ 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();
+ --it;
+
+ for (; it != last; --it) {
+
+ // A good solution for Items inside insets would be to do:
+ //
+ //if (std::distance(it->par_it_, current) <= 0)
+ // return it;
+ //
+ // But for an unknown reason, std::distance(current,
it->par_it_) always
+ // returns a positive value and std::distance(it->par_it_,
current) takes forever...
+ // So for now, we do:
+ if (it->par_it_.pit() <= par_it.pit())
+ return it;
+ }
+
+ // We are before the first Toc Item:
+ return last;
+}
+
+
+void TocBackend::asciiTocList(string const & type, ostream & 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();
+ for (; ccit != end; ++ccit)
+ os << ccit->asString() << '\n';
+ }
+}
+
+
+} // namespace lyx
Index: src/TocBackend.h
===================================================================
--- src/TocBackend.h (revision 0)
+++ src/TocBackend.h (revision 0)
@@ -0,0 +1,145 @@
+// -*- C++ -*-
+/**
+ * \file TocBackend.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ *
+ * TocBackend mainly used in toc.[Ch]
+ */
+
+#ifndef TOC_BACKEND_H
+#define TOC_BACKEND_H
+
+#include <map>
+#include <iosfwd>
+#include <vector>
+#include <string>
+
+#include "pariterator.h"
+
+class Buffer;
+class LyXView;
+class Paragraph;
+class FuncRequest;
+class LCursor;
+
+namespace lyx {
+
+///
+/**
+*/
+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,
+ std::string const & s = std::string());
+ ///
+ ~Item() {}
+ ///
+ bool const isValid() const;
+ ///
+ int const id() const;
+ ///
+ int const depth() const;
+ ///
+ std::string const & str() const;
+ ///
+ std::string const asString() const;
+ /// set cursor in LyXView to this Item
+ void goTo(LyXView & lv_) 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
+ std::string str_;
+ };
+
+ ///
+ typedef std::vector<Item> Toc;
+ typedef std::vector<Item>::const_iterator TocIterator;
+ ///
+ typedef std::map<std::string, Toc> TocList;
+
+public:
+ ///
+ TocBackend(Buffer const * buffer = NULL): buffer_(buffer) {}
+ ///
+ ~TocBackend() {}
+ ///
+ void setBuffer(Buffer const * buffer)
+ { buffer_ = buffer; }
+ ///
+ bool addType(std::string const & type);
+ ///
+ void update();
+ ///
+ TocList const & tocs()
+ { return tocs_; }
+ ///
+ std::vector<std::string> const & types()
+ { return types_; }
+ ///
+ Toc const & toc(std::string const & type);
+ /// Return the first Toc Item before the cursor
+ TocIterator const item(std::string const & type, ParConstIterator const
&);
+
+ void asciiTocList(std::string const & type, std::ostream & os) const;
+
+private:
+ ///
+ TocList tocs_;
+ ///
+ std::vector<std::string> types_;
+ ///
+ Item const invalid_item_;
+ ///
+ Toc const empty_toc_;
+ ///
+ Buffer const * buffer_;
+
+}; // TocBackend
+
+inline
+bool operator==(TocBackend::Item const & a, TocBackend::Item const & b)
+{
+ return a.id() == b.id() && a.str() == b.str();
+ // No need to compare depth.
+}
+
+
+inline
+bool operator!=(TocBackend::Item const & a, TocBackend::Item const & b)
+{
+ return !(a == b);
+}
+
+
+} // namespace lyx
+
+#endif // TOC_BACKEND_H