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()) {

Reply via email to