2001-08-19 13:25:15 +00:00
|
|
|
/**
|
|
|
|
* \file QToc.C
|
|
|
|
* Copyright 2001 the LyX Team
|
|
|
|
* Read the file COPYING
|
|
|
|
*
|
|
|
|
* \author John Levon <moz@compsoc.man.ac.uk>
|
2001-03-23 06:31:30 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stack>
|
|
|
|
|
|
|
|
#include <qslider.h>
|
2001-08-19 13:25:15 +00:00
|
|
|
#include "QTocDialog.h"
|
|
|
|
#include "QtLyXView.h"
|
2001-03-23 06:31:30 +00:00
|
|
|
|
|
|
|
#include "Dialogs.h"
|
2001-08-19 13:25:15 +00:00
|
|
|
#include "BufferView.h"
|
|
|
|
#include "QToc.h"
|
2001-03-23 06:31:30 +00:00
|
|
|
#include "gettext.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
#include "lyxfunc.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
2001-08-29 15:37:39 +00:00
|
|
|
#include <qlistview.h>
|
|
|
|
#include <qcombobox.h>
|
|
|
|
|
2001-03-23 06:31:30 +00:00
|
|
|
using std::vector;
|
|
|
|
using std::pair;
|
|
|
|
using std::stack;
|
|
|
|
using std::endl;
|
2001-08-29 15:37:39 +00:00
|
|
|
using SigC::slot;
|
|
|
|
|
2001-03-23 06:31:30 +00:00
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
QToc::QToc(LyXView *v, Dialogs *d)
|
2001-03-23 06:31:30 +00:00
|
|
|
: dialog_(0), lv_(v), d_(d), inset_(0), h_(0), u_(0), ih_(0),
|
2001-08-19 13:25:15 +00:00
|
|
|
/*toclist(0),*/ depth(1)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
2001-08-19 13:25:15 +00:00
|
|
|
d->showTOC.connect(slot(this, &QToc::showTOC));
|
|
|
|
d->createTOC.connect(slot(this, &QToc::createTOC));
|
2001-03-23 06:31:30 +00:00
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
QToc::~QToc()
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
delete dialog_;
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::showTOC(InsetCommand * const inset)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
// FIXME: when could inset be 0 here ?
|
2001-08-19 13:25:15 +00:00
|
|
|
if (inset == 0)
|
2001-03-23 06:31:30 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
inset_ = inset;
|
2001-08-19 13:25:15 +00:00
|
|
|
//FIXME ih_ = inset_->hide.connect(slot(this,&QToc::hide));
|
2001-03-23 06:31:30 +00:00
|
|
|
params = inset->params();
|
|
|
|
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::createTOC(string const & arg)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (inset_)
|
|
|
|
close();
|
|
|
|
|
|
|
|
params.setFromString(arg);
|
|
|
|
show();
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::updateToc(int newdepth)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (!lv_->view()->available()) {
|
2001-08-19 13:25:15 +00:00
|
|
|
//toclist.clear();
|
2001-03-23 06:31:30 +00:00
|
|
|
dialog_->tocLV->clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
#if 0
|
2001-03-23 06:31:30 +00:00
|
|
|
vector< vector<Buffer::TocItem> > tmp =
|
|
|
|
lv_->view()->buffer()->getTocList();
|
|
|
|
|
|
|
|
// Check if all elements are the same.
|
|
|
|
if (newdepth==depth && toclist.size() == tmp[type].size()) {
|
|
|
|
unsigned int i = 0;
|
|
|
|
for (; i < toclist.size(); ++i) {
|
|
|
|
if (toclist[i] != tmp[type][i])
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i >= toclist.size())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
depth=newdepth;
|
|
|
|
|
|
|
|
toclist = tmp[type];
|
|
|
|
|
|
|
|
dialog_->tocLV->clear();
|
|
|
|
if (toclist.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
dialog_->tocLV->setUpdatesEnabled(false);
|
|
|
|
|
|
|
|
int curdepth = 0;
|
|
|
|
stack< pair< QListViewItem *, QListViewItem *> > istack;
|
|
|
|
QListViewItem *last = 0;
|
|
|
|
QListViewItem *parent = 0;
|
|
|
|
QListViewItem *item;
|
|
|
|
|
|
|
|
// Yes, it is this ugly. Two reasons - root items must have a QListView parent,
|
|
|
|
// rather than QListViewItem; and the TOC can move in and out an arbitrary number
|
|
|
|
// of levels
|
|
|
|
|
|
|
|
for (vector< Buffer::TocItem >::const_iterator iter = toclist.begin();
|
|
|
|
iter != toclist.end(); ++iter) {
|
|
|
|
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;
|
|
|
|
// 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;
|
|
|
|
pair< QListViewItem *, QListViewItem * > top;
|
|
|
|
// restore context
|
|
|
|
while (diff--) {
|
|
|
|
top = istack.top();
|
|
|
|
istack.pop();
|
|
|
|
}
|
|
|
|
parent = top.first;
|
|
|
|
last = top.second;
|
|
|
|
// 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));
|
|
|
|
}
|
|
|
|
lyxerr[Debug::GUI] << "Table of contents" << endl << "Added item " << iter->str.c_str()
|
|
|
|
<< " at depth " << iter->depth << ", previous sibling \"" << (last ? last->text(0).latin1() : "0")
|
|
|
|
<< "\", parent \"" << (parent ? parent->text(0).latin1() : "0") << "\"" << endl;
|
|
|
|
item->setText(0,iter->str.c_str());
|
|
|
|
item->setOpen(iter->depth < depth);
|
|
|
|
curdepth = iter->depth;
|
|
|
|
last = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
dialog_->tocLV->setUpdatesEnabled(true);
|
|
|
|
dialog_->tocLV->update();
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::setType(Buffer::TocType toctype)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
type = toctype;
|
|
|
|
switch (type) {
|
|
|
|
case Buffer::TOC_TOC:
|
|
|
|
dialog_->setCaption(_("Table of Contents"));
|
|
|
|
dialog_->tocLV->setColumnText(0,_("Table of Contents"));
|
|
|
|
dialog_->depthSL->setEnabled(true);
|
|
|
|
break;
|
|
|
|
case Buffer::TOC_LOF:
|
|
|
|
dialog_->setCaption(_("List of Figures"));
|
|
|
|
dialog_->tocLV->setColumnText(0,_("List of Figures"));
|
|
|
|
dialog_->depthSL->setEnabled(false);
|
|
|
|
break;
|
|
|
|
case Buffer::TOC_LOT:
|
|
|
|
dialog_->setCaption(_("List of Tables"));
|
|
|
|
dialog_->tocLV->setColumnText(0,_("List of Tables"));
|
|
|
|
dialog_->depthSL->setEnabled(false);
|
|
|
|
break;
|
|
|
|
case Buffer::TOC_LOA:
|
|
|
|
dialog_->setCaption(_("List of Algorithms"));
|
|
|
|
dialog_->tocLV->setColumnText(0,_("List of Algorithms"));
|
|
|
|
dialog_->depthSL->setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::set_depth(int newdepth)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (newdepth!=depth)
|
|
|
|
updateToc(newdepth);
|
2001-08-19 13:25:15 +00:00
|
|
|
#endif
|
2001-03-23 06:31:30 +00:00
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::update()
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
2001-08-19 13:25:15 +00:00
|
|
|
#if 0
|
2001-03-23 06:31:30 +00:00
|
|
|
if (params.getCmdName()=="tableofcontents") {
|
|
|
|
setType(Buffer::TOC_TOC);
|
|
|
|
dialog_->typeCO->setCurrentItem(0);
|
|
|
|
} else if (params.getCmdName()=="listoffigures") {
|
|
|
|
setType(Buffer::TOC_LOF);
|
|
|
|
dialog_->typeCO->setCurrentItem(1);
|
|
|
|
} else if (params.getCmdName()=="listoftables") {
|
|
|
|
setType(Buffer::TOC_LOT);
|
|
|
|
dialog_->typeCO->setCurrentItem(2);
|
|
|
|
} else {
|
|
|
|
setType(Buffer::TOC_LOA);
|
|
|
|
dialog_->typeCO->setCurrentItem(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
updateToc(depth);
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::select(const char *text)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (!lv_->view()->available())
|
|
|
|
return;
|
|
|
|
|
|
|
|
vector <Buffer::TocItem>::const_iterator iter = toclist.begin();
|
|
|
|
for (; iter != toclist.end(); ++iter) {
|
|
|
|
if (iter->str==text)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iter==toclist.end()) {
|
|
|
|
lyxerr[Debug::GUI] << "Couldn't find highlighted TOC entry : " << text << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lv_->getLyXFunc()->Dispatch(LFUN_GOTO_PARAGRAPH, tostr(iter->par->id()).c_str());
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::set_type(Buffer::TocType toctype)
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (toctype==type)
|
|
|
|
return;
|
|
|
|
|
|
|
|
setType(toctype);
|
|
|
|
updateToc(depth);
|
2001-08-19 13:25:15 +00:00
|
|
|
#endif
|
2001-03-23 06:31:30 +00:00
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::show()
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
if (!dialog_)
|
2001-08-19 13:25:15 +00:00
|
|
|
dialog_ = new QTocDialog(this, 0, _("LyX: Table of Contents"), false);
|
2001-03-23 06:31:30 +00:00
|
|
|
|
|
|
|
if (!dialog_->isVisible()) {
|
2001-08-19 13:25:15 +00:00
|
|
|
h_ = d_->hideBufferDependent.connect(slot(this, &QToc::hide));
|
|
|
|
//u_ = d_->updateBufferDependent.connect(slot(this, &QToc::update));
|
2001-03-23 06:31:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dialog_->raise();
|
|
|
|
dialog_->setActiveWindow();
|
|
|
|
|
|
|
|
update();
|
|
|
|
dialog_->show();
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::close()
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
h_.disconnect();
|
|
|
|
u_.disconnect();
|
|
|
|
ih_.disconnect();
|
|
|
|
inset_ = 0;
|
|
|
|
}
|
|
|
|
|
2001-08-19 13:25:15 +00:00
|
|
|
|
|
|
|
void QToc::hide()
|
2001-03-23 06:31:30 +00:00
|
|
|
{
|
|
|
|
dialog_->hide();
|
|
|
|
close();
|
|
|
|
}
|