The situation with counters is still very bad: captions in floats do not have a label when loading a file. Also, updateCounters renumbers the whole lyxtext without trying to go into nested insets. I suspect that all paragraphs will have to be visited at each updatecounters, but I am not sure how expensive this is going to be...
The following patch modifies updateCounters to recompute the counters recursively for the whooe document everytime. As expected, this is _very_ expensive on a file like UserGuide. The profiler says that DocIterator::forwardPos is to blame.
To make this faster, I think DocIterator::forwardPar should take advantage of the inset list of paragraphs. This is the only way to avoid
visiting all cursor positions... So each cursor slice should keep
an up to date InsetList::iterator. This is too much work for me right now, though...
JMarc
Index: lib/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ChangeLog,v retrieving revision 1.674 diff -u -r1.674 ChangeLog --- lib/ChangeLog 17 Feb 2005 13:21:08 -0000 1.674 +++ lib/ChangeLog 20 Feb 2005 22:48:51 -0000 @@ -1,3 +1,7 @@ +2005-02-20 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + + * layouts/stdlayouts.inc: change labelstring to "Senseless!" + 2005-02-17 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> * configure.m4: do not use -swap option for gv (it does not work Index: lib/layouts/stdlayouts.inc =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/layouts/stdlayouts.inc,v retrieving revision 1.8 diff -u -r1.8 stdlayouts.inc --- lib/layouts/stdlayouts.inc 13 Oct 2003 09:50:10 -0000 1.8 +++ lib/layouts/stdlayouts.inc 20 Feb 2005 22:48:51 -0000 @@ -71,7 +71,7 @@ Align Center AlignPossible Center LabelType Sensitive - LabelString Caption + LabelString "Senseless!" OptionalArgs 1 LabelFont Series Bold Index: src/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v retrieving revision 1.2126 diff -u -r1.2126 ChangeLog --- src/ChangeLog 20 Feb 2005 19:09:39 -0000 1.2126 +++ src/ChangeLog 20 Feb 2005 22:49:55 -0000 @@ -1,5 +1,22 @@ 2005-02-20 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + * cursor.C: remove unused variable + + * text3.C (dispatch): + * text.C (breakParagraph, backspace): + * CutAndPaste.C (cutSelection, pasteSelection): pass a buffer and + a cursor to updateCounters. + + * text2.C (updateCounters): turn into a free standing function and + add a buffer and dociterator parameters. Remove dead code for + tracking labelstring change. + (init, setLayout, changeDepth): pass a buffer and a cursor to + updateCounters. + (setCounter): change into a free-standing function which gets a + dociterator as argument. Use this iteraror to fix captions in a + simple way. When no float is found above the caption, use the + labelstring of the caption layout as default. + * lyx_main.C (queryUserLyXDir): fix test for rerunning configure 2005-02-15 Angus Leeming <[EMAIL PROTECTED]> Index: src/text.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v retrieving revision 1.594 diff -u -r1.594 text.C --- src/text.C 8 Feb 2005 02:06:35 -0000 1.594 +++ src/text.C 20 Feb 2005 22:49:58 -0000 @@ -1074,7 +1074,7 @@ while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) pars_[next_par].erase(0); - updateCounters(); + updateCounters(cur.buffer(), cur); // This check is necessary. Otherwise the new empty paragraph will // be deleted automatically. And it is more friendly for the user! @@ -1609,7 +1609,7 @@ --cur.pos(); // the counters may have changed - updateCounters(); + updateCounters(cur.buffer(), cur); setCursor(cur, cur.pit(), cur.pos(), false); } } else { Index: src/text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.600 diff -u -r1.600 text2.C --- src/text2.C 14 Feb 2005 08:17:23 -0000 1.600 +++ src/text2.C 20 Feb 2005 22:50:08 -0000 @@ -45,6 +45,7 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" +#include "pariterator.h" #include "undo.h" #include "vspace.h" @@ -67,6 +68,7 @@ using lyx::support::bformat; using std::endl; +using std::min; using std::ostringstream; using std::string; @@ -93,7 +95,8 @@ pars_[pit].rows().clear(); current_font = getFont(pars_[0], 0); - updateCounters(); + updateCounters(*bv->buffer(), + doc_iterator_begin(bv->buffer()->inset())); } @@ -337,7 +340,7 @@ pit_type start = cur.selBegin().pit(); pit_type end = cur.selEnd().pit() + 1; setLayout(start, end, layout); - updateCounters(); + updateCounters(cur.buffer(), cur); } @@ -398,7 +401,7 @@ } // this handles the counter labels, and also fixes up // depth values for follow-on (child) paragraphs - updateCounters(); + updateCounters(cur.buffer(), cur); } @@ -681,9 +684,9 @@ // set the counter of a paragraph. This includes the labels -void LyXText::setCounter(Buffer const & buf, pit_type pit) +void setCounter(Buffer const & buf, ParIterator & it) { - Paragraph & par = pars_[pit]; + Paragraph & par = *it; BufferParams const & bufparams = buf.params(); LyXTextClass const & textclass = bufparams.getLyXTextClass(); LyXLayout_ptr const & layout = par.layout(); @@ -692,10 +695,10 @@ // Always reset par.itemdepth = 0; - if (pit == 0) { + if (it.pit() == 0) { par.params().appendix(par.params().startOfAppendix()); } else { - par.params().appendix(pars_[pit - 1].params().appendix()); + par.params().appendix(it.plist()[it.pit() - 1].params().appendix()); if (!par.params().appendix() && par.params().startOfAppendix()) { par.params().appendix(true); @@ -703,7 +706,7 @@ } // Maybe we have to increment the item depth. - incrementItemDepth(pars_, pit, 0); + incrementItemDepth(it.plist(), it.pit(), 0); } // erase what was there before @@ -718,8 +721,6 @@ // is it a layout that has an automatic label? if (layout->labeltype == LABEL_COUNTER) { - BufferParams const & bufparams = buf.params(); - LyXTextClass const & textclass = bufparams.getLyXTextClass(); counters.step(layout->counter); string label = expandLabel(textclass, layout, par.params().appendix()); par.params().labelString(label); @@ -748,7 +749,7 @@ par.params().labelString(itemlabel); } else if (layout->labeltype == LABEL_ENUMERATE) { // Maybe we have to reset the enumeration counter. - resetEnumCounterIfNeeded(pars_, pit, 0, counters); + resetEnumCounterIfNeeded(it.plist(), it.pit(), 0, counters); // FIXME // Yes I know this is a really, really! bad solution @@ -782,101 +783,73 @@ par.params().labelString(layout->labelstring()); } // In biblio should't be following counters but... - } else { - string s = buf.B_(layout->labelstring()); - - // the caption hack: - if (layout->labeltype == LABEL_SENSITIVE) { - pit_type end = paragraphs().size(); - pit_type tmppit = pit; - InsetBase * in = 0; - bool isOK = false; - while (tmppit != end) { - in = pars_[tmppit].inInset(); - // FIXME: in should be always valid. - if (in && - (in->lyxCode() == InsetBase::FLOAT_CODE || - in->lyxCode() == InsetBase::WRAP_CODE)) { - isOK = true; - break; - } -#ifdef WITH_WARNINGS -#warning replace this code by something that works -// This code does not work because we have currently no way to move up -// in the hierarchy of insets (JMarc 16/08/2004) -#endif -#if 0 -/* I think this code is supposed to be useful when one has a caption - * in a minipage in a figure inset. We need to go up to be able to see - * that the caption should use "Figure" as label - */ - else { - Paragraph const * owner = &ownerPar(buf, in); - tmppit = 0; - for ( ; tmppit != end; ++tmppit) - if (&pars_[tmppit] == owner) - break; - } -#else - ++tmppit; -#endif + } else if (layout->labeltype == LABEL_SENSITIVE) { + // Search for the first float or wrap inset in the iterator + string type; + size_t i = it.depth(); + while (i > 0) { + --i; + InsetBase * const in = &it[i].inset(); + if (in->lyxCode() == InsetBase::FLOAT_CODE) { + type = static_cast<InsetFloat*>(in)->params().type; + break; + } else if (in->lyxCode() == InsetBase::WRAP_CODE) { + type = static_cast<InsetWrap*>(in)->params().type; + break; } + } - if (isOK) { - string type; - - if (in->lyxCode() == InsetBase::FLOAT_CODE) - type = static_cast<InsetFloat*>(in)->params().type; - else if (in->lyxCode() == InsetBase::WRAP_CODE) - type = static_cast<InsetWrap*>(in)->params().type; - else - BOOST_ASSERT(false); - - Floating const & fl = textclass.floats().getType(type); - - counters.step(fl.type()); - - // Doesn't work... yet. - s = bformat(_("%1$s #:"), buf.B_(fl.name())); - } else { - // par->SetLayout(0); - // s = layout->labelstring; - s = _("Senseless: "); - } + string s; + if (!type.empty()) { + Floating const & fl = textclass.floats().getType(type); + + counters.step(fl.type()); + + // Doesn't work... yet. + s = bformat(_("%1$s #:"), buf.B_(fl.name())); + } else { + // par->SetLayout(0); + s = buf.B_(layout->labelstring()); } - par.params().labelString(s); - } + par.params().labelString(s); + } else + par.params().labelString(buf.B_(layout->labelstring())); } // Updates all counters. -void LyXText::updateCounters() +void updateCounters(Buffer const & buf, DocIterator const & dit) { // start over - bv()->buffer()->params().getLyXTextClass().counters().reset(); + buf.params().getLyXTextClass().counters().reset(); - bool update_pos = false; +#if 0 + size_t maxdepth = 0; + ParIterator it(dit); + it.top().pit() = 0; + pit_type const end = it.plist().size(); + for ( ; it.pit() != end; ++it.top().pit()) { + if (it->params().depth() > maxdepth) + it->params().depth(maxdepth); + maxdepth = it->getMaxDepthAfter(); + + setCounter(buf, it); + } +#else + for (ParIterator it = par_iterator_begin(buf.inset()); it; ++it) { + // reduce depth if necessary + if (it.pit()) { + Paragraph const & prevpar = it.plist()[it.pit() - 1]; + it->params().depth(min(it->params().depth(), + prevpar.getMaxDepthAfter())); + } else + it->params().depth(0); - pit_type end = paragraphs().size(); - for (pit_type pit = 0; pit != end; ++pit) { - string const oldLabel = pars_[pit].params().labelString(); - size_t maxdepth = 0; - if (pit != 0) - maxdepth = pars_[pit - 1].getMaxDepthAfter(); - - if (pars_[pit].params().depth() > maxdepth) - pars_[pit].params().depth(maxdepth); - - // setCounter can potentially change the labelString. - setCounter(*bv()->buffer(), pit); - string const & newLabel = pars_[pit].params().labelString(); - if (oldLabel != newLabel) { - //lyxerr[Debug::DEBUG] << "changing labels: old: " << oldLabel << " new: " - // << newLabel << endl; - update_pos = true; - } + // set the counter for this paragraph + setCounter(buf, it); } +#endif } Index: src/text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.283 diff -u -r1.283 text3.C --- src/text3.C 8 Feb 2005 13:18:02 -0000 1.283 +++ src/text3.C 20 Feb 2005 22:50:12 -0000 @@ -370,6 +370,10 @@ Paragraph & par = cur.paragraph(); bool start = !par.params().startOfAppendix(); +#ifdef WITH_WARNINGS +#warning The code below only makes sense a top level. +// Should LFUN_APPENDIX be restricted to top-level paragraphs? +#endif // ensure that we have only one start_of_appendix in this document for (pit_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) { if (pars_[tmp].params().startOfAppendix()) { @@ -383,7 +387,7 @@ par.params().startOfAppendix(start); // we can set the refreshing parameters now - updateCounters(); + updateCounters(cur.buffer(), cur); break; } Index: src/CutAndPaste.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/CutAndPaste.C,v retrieving revision 1.148 diff -u -r1.148 CutAndPaste.C --- src/CutAndPaste.C 8 Feb 2005 13:17:56 -0000 1.148 +++ src/CutAndPaste.C 20 Feb 2005 22:50:15 -0000 @@ -503,7 +503,7 @@ // need a valid cursor. (Lgb) cur.clearSelection(); - text->updateCounters(); + updateCounters(cur.buffer(), cur); } if (cur.inMathed()) { @@ -596,7 +596,7 @@ cur.resetAnchor(); text->setCursor(cur, ppp.first, ppp.second); cur.setSelection(); - text->updateCounters(); + updateCounters(cur.buffer(), cur); } if (cur.inMathed()) { Index: src/cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v retrieving revision 1.122 diff -u -r1.122 cursor.C --- src/cursor.C 15 Feb 2005 17:34:53 -0000 1.122 +++ src/cursor.C 20 Feb 2005 22:50:15 -0000 @@ -123,8 +123,6 @@ { BOOST_ASSERT(!cursor.empty()); CursorSlice bottom = cursor[0]; - LyXText * text = bottom.text(); - BOOST_ASSERT(text); DocIterator it = doc_iterator_begin(bottom.inset()); DocIterator const et = doc_iterator_end(bottom.inset());