Support code for advanced Toc management and bug correction.

* buffer.h:
  - structureChanged(): new boost signal. I intend to use that also when a text is changed in a section or caption item.

* buffer_funcs.C:
  - updateLabels(): emit Buffer::structureChanged() after TocBackend is updated.
  - checkBufferStructure(): new method for updating the TocBackend if needed.

* LyXView:
  - updateToc(): new slot for Buffer::structureChanged() signal.

* text.C:
  - call checkBufferStructure() whenever text is added or erased.

* TocBackend.[Ch]:
  - updateItem(): new method to update a specific item (called from checkBufferStructure()).



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17413 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2007-03-12 11:23:41 +00:00
parent 145c4d9afe
commit bf61ecc2de
8 changed files with 84 additions and 1 deletions

View File

@ -134,6 +134,43 @@ bool TocBackend::addType(std::string const & type)
return true; return true;
} }
void TocBackend::updateItem(ParConstIterator const & par_it)
{
BufferParams const & bufparams = buffer_->params();
const int min_toclevel = bufparams.getLyXTextClass().min_toclevel();
TocIterator toc_item = item("tableofcontents", par_it);
docstring tocstring;
// For each paragraph, traverse its insets and let them add
// their toc items
InsetList::const_iterator it = toc_item->par_it_->insetlist.begin();
InsetList::const_iterator end = toc_item->par_it_->insetlist.end();
for (; it != end; ++it) {
InsetBase & inset = *it->inset;
if (inset.lyxCode() == InsetBase::OPTARG_CODE) {
if (!tocstring.empty())
break;
Paragraph const & par =
*static_cast<InsetOptArg&>(inset).paragraphs().begin();
if (!toc_item->par_it_->getLabelstring().empty())
tocstring = toc_item->par_it_->getLabelstring() + ' ';
tocstring += par.asString(*buffer_, false);
break;
}
}
int const toclevel = toc_item->par_it_->layout()->toclevel;
if (toclevel != LyXLayout::NOT_IN_TOC
&& toclevel >= min_toclevel
&& toclevel <= bufparams.tocdepth
&& tocstring.empty())
tocstring = toc_item->par_it_->asString(*buffer_, true);
const_cast<TocItem &>(*toc_item).str_ = tocstring;
}
void TocBackend::update() void TocBackend::update()
{ {

View File

@ -99,6 +99,9 @@ public:
bool addType(std::string const & type); bool addType(std::string const & type);
/// ///
void update(); void update();
///
void updateItem(ParConstIterator const & pit);
/// ///
TocList const & tocs() const TocList const & tocs() const
{ return tocs_; } { return tocs_; }

View File

@ -130,6 +130,8 @@ public:
/// This signal is emitted when the buffer is changed. /// This signal is emitted when the buffer is changed.
boost::signal<void()> changed; boost::signal<void()> changed;
/// This signal is emitted when the buffer structure is changed.
boost::signal<void()> structureChanged;
/// This signal is emitted when some parsing error shows up. /// This signal is emitted when some parsing error shows up.
boost::signal<void(std::string)> errors; boost::signal<void(std::string)> errors;
/// This signal is emitted when some message shows up. /// This signal is emitted when some message shows up.

View File

@ -695,8 +695,18 @@ void updateLabels(Buffer const & buf, bool childonly)
} }
} }
const_cast<Buffer &>(buf).tocBackend().update(); Buffer & cbuf = const_cast<Buffer &>(buf);
cbuf.tocBackend().update();
cbuf.structureChanged();
} }
void checkBufferStructure(Buffer & buffer, ParIterator const & par_it)
{
if (par_it->layout()->labeltype == LABEL_COUNTER) {
buffer.tocBackend().updateItem(par_it);
buffer.structureChanged();
}
}
} // namespace lyx } // namespace lyx

View File

@ -65,6 +65,8 @@ void updateLabels(Buffer const & buf,
/// updates all counters /// updates all counters
void updateLabels(Buffer const &, bool childonly = false); void updateLabels(Buffer const &, bool childonly = false);
///
void checkBufferStructure(Buffer &, ParIterator const &);
} // namespace lyx } // namespace lyx

View File

@ -133,6 +133,8 @@ void LyXView::setBuffer(Buffer * b)
getDialogs().hideBufferDependent(); getDialogs().hideBufferDependent();
work_area_->bufferView().setBuffer(b); work_area_->bufferView().setBuffer(b);
// Make sure the TOC is updated before anything else.
updateToc();
if (work_area_->bufferView().buffer()) { if (work_area_->bufferView().buffer()) {
// Buffer-dependent dialogs should be updated or // Buffer-dependent dialogs should be updated or
@ -166,6 +168,7 @@ bool LyXView::loadLyXFile(FileName const & filename, bool tolastfiles)
bool loaded = work_area_->bufferView().loadLyXFile(filename, tolastfiles); bool loaded = work_area_->bufferView().loadLyXFile(filename, tolastfiles);
updateToc();
updateMenubar(); updateMenubar();
updateToolbars(); updateToolbars();
updateLayoutChoice(); updateLayoutChoice();
@ -192,6 +195,10 @@ void LyXView::connectBuffer(Buffer & buf)
buf.changed.connect( buf.changed.connect(
boost::bind(&WorkArea::redraw, work_area_)); boost::bind(&WorkArea::redraw, work_area_));
bufferStructureChangedConnection_ =
buf.structureChanged.connect(
boost::bind(&LyXView::updateToc, this));
errorsConnection_ = errorsConnection_ =
buf.errors.connect( buf.errors.connect(
boost::bind(&LyXView::showErrorList, this, _1)); boost::bind(&LyXView::showErrorList, this, _1));
@ -226,6 +233,7 @@ void LyXView::disconnectBuffer()
{ {
errorsConnection_.disconnect(); errorsConnection_.disconnect();
bufferChangedConnection_.disconnect(); bufferChangedConnection_.disconnect();
bufferStructureChangedConnection_.disconnect();
messageConnection_.disconnect(); messageConnection_.disconnect();
busyConnection_.disconnect(); busyConnection_.disconnect();
titleConnection_.disconnect(); titleConnection_.disconnect();
@ -309,6 +317,12 @@ BufferView * LyXView::view() const
} }
void LyXView::updateToc()
{
updateDialog("toc", "");
}
void LyXView::updateToolbars() void LyXView::updateToolbars()
{ {
BOOST_ASSERT(work_area_); BOOST_ASSERT(work_area_);

View File

@ -224,6 +224,8 @@ private:
/// buffer changed signal connection /// buffer changed signal connection
boost::signals::connection bufferChangedConnection_; boost::signals::connection bufferChangedConnection_;
/// buffer structure changed signal connection
boost::signals::connection bufferStructureChangedConnection_;
/// buffer errors signal connection /// buffer errors signal connection
boost::signals::connection errorsConnection_; boost::signals::connection errorsConnection_;
/// buffer messages signal connection /// buffer messages signal connection
@ -268,6 +270,9 @@ private:
void showReadonly(bool); void showReadonly(bool);
protected: protected:
///
void updateToc();
/// view's command buffer controller /// view's command buffer controller
// this has to be declared _after_ lyxfunc_ as its initialization depends // this has to be declared _after_ lyxfunc_ as its initialization depends
// on it! // on it!

View File

@ -744,6 +744,7 @@ void LyXText::insertChar(LCursor & cur, char_type c)
} }
par.insertChar(cur.pos(), c, current_font, cur.buffer().params().trackChanges); par.insertChar(cur.pos(), c, current_font, cur.buffer().params().trackChanges);
checkBufferStructure(cur.buffer(), cur);
// cur.updateFlags(Update::Force); // cur.updateFlags(Update::Force);
setCursor(cur.top(), cur.pit(), cur.pos() + 1); setCursor(cur.top(), cur.pit(), cur.pos() + 1);
@ -1025,6 +1026,7 @@ void LyXText::deleteWordForward(LCursor & cur)
cursorRightOneWord(cur); cursorRightOneWord(cur);
cur.setSelection(); cur.setSelection();
cutSelection(cur, true, false); cutSelection(cur, true, false);
checkBufferStructure(cur.buffer(), cur);
} }
} }
@ -1041,6 +1043,7 @@ void LyXText::deleteWordBackward(LCursor & cur)
cursorLeftOneWord(cur); cursorLeftOneWord(cur);
cur.setSelection(); cur.setSelection();
cutSelection(cur, true, false); cutSelection(cur, true, false);
checkBufferStructure(cur.buffer(), cur);
} }
} }
@ -1062,6 +1065,7 @@ void LyXText::deleteLineForward(LCursor & cur)
deleteWordForward(cur); deleteWordForward(cur);
else else
cutSelection(cur, true, false); cutSelection(cur, true, false);
checkBufferStructure(cur.buffer(), cur);
} }
} }
@ -1115,6 +1119,7 @@ void LyXText::changeCase(LCursor & cur, LyXText::TextCase action)
//pars_[pit].setChar(pos, c); //pars_[pit].setChar(pos, c);
++pos; ++pos;
} }
checkBufferStructure(cur.buffer(), cur);
} }
@ -1132,6 +1137,7 @@ bool LyXText::erase(LCursor & cur)
// the character has been logically deleted only => skip it // the character has been logically deleted only => skip it
cur.forwardPosNoDescend(); cur.forwardPosNoDescend();
} }
checkBufferStructure(cur.buffer(), cur);
needsUpdate = true; needsUpdate = true;
} else { } else {
if (cur.pit() == cur.lastpit()) if (cur.pit() == cur.lastpit())
@ -1151,6 +1157,7 @@ bool LyXText::erase(LCursor & cur)
// Make sure the cursor is correct. Is this really needed? // Make sure the cursor is correct. Is this really needed?
// No, not really... at least not here! // No, not really... at least not here!
cur.text()->setCursor(cur.top(), cur.pit(), cur.pos()); cur.text()->setCursor(cur.top(), cur.pit(), cur.pos());
checkBufferStructure(cur.buffer(), cur);
} }
return needsUpdate; return needsUpdate;
@ -1238,6 +1245,7 @@ bool LyXText::backspace(LCursor & cur)
setCursorIntern(cur, cur.pit(), cur.pos() - 1, setCursorIntern(cur, cur.pit(), cur.pos() - 1,
false, cur.boundary()); false, cur.boundary());
cur.paragraph().eraseChar(cur.pos(), cur.buffer().params().trackChanges); cur.paragraph().eraseChar(cur.pos(), cur.buffer().params().trackChanges);
checkBufferStructure(cur.buffer(), cur);
} }
if (cur.pos() == cur.lastpos()) if (cur.pos() == cur.lastpos())
@ -1874,6 +1882,8 @@ void LyXText::charsTranspose(LCursor & cur)
par.insertChar(pos1, char2, font2, trackChanges); par.insertChar(pos1, char2, font2, trackChanges);
par.insertChar(pos2, char1, font1, trackChanges); par.insertChar(pos2, char1, font1, trackChanges);
checkBufferStructure(cur.buffer(), cur);
// After the transposition, move cursor to after the transposition. // After the transposition, move cursor to after the transposition.
setCursor(cur, cur.pit(), pos2); setCursor(cur, cur.pit(), pos2);
cur.forwardPos(); cur.forwardPos();