The following patch fixes the infamous 'caption hack'. What it does is to add an infrastructure that insures that setCounter gets passed a full iterator from which enclosing figure floats can be found at any level.
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...
Comments very welcome...
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 19:33:23 -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 19:33:23 -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 19:34:22 -0000 @@ -1,5 +1,20 @@ 2005-02-20 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + * 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 19:34:26 -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 19:34:33 -0000 @@ -45,6 +45,7 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" +#include "pariterator.h" #include "undo.h" #include "vspace.h" @@ -93,7 +94,8 @@ pars_[pit].rows().clear(); current_font = getFont(pars_[0], 0); - updateCounters(); + updateCounters(*bv->buffer(), + doc_iterator_begin(bv->buffer()->inset())); } @@ -337,7 +339,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 +400,7 @@ } // this handles the counter labels, and also fixes up // depth values for follow-on (child) paragraphs - updateCounters(); + updateCounters(cur.buffer(), cur); } @@ -681,9 +683,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 +694,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 +705,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 +720,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 +748,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,100 +782,57 @@ 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(); - - bool update_pos = false; + buf.params().getLyXTextClass().counters().reset(); - 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; - } + 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); } } 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 19:34:36 -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 19:34:36 -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()) {