Attached is a slightly updated version of this patch. OK to commit?

A proper clean-up of this will have to wait a bit.

Richard

-- 
==================================================================
Richard G Heck, Jr
Professor of Philosophy
Brown University
http://frege.brown.edu/heck/
==================================================================
Get my public key from http://sks.keyserver.penguin.de
Hash: 0x1DE91F1E66FFBDEC
Learn how to sign your email using Thunderbird and GnuPG at:
http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto


Index: Paragraph.h
===================================================================
--- Paragraph.h	(revision 18422)
+++ Paragraph.h	(working copy)
@@ -359,9 +359,14 @@
 	///
 	bool hfillExpansion(Row const & row, pos_type pos) const;
 
-	/// Check if we are in a Biblio environment.
-	/// \retval true if the cursor needs to be moved right.
-	bool checkBiblio(bool track_changes);
+	/// Check if we are in a Biblio environment and insert or
+	/// delete InsetBibitems as necessary.
+	/// \retval int 1, if we had to add an inset, in which case
+	/// the cursor will need to move cursor forward; -pos, if we deleted
+	/// an inset, in which case pos is the position from which the inset
+	/// was deleted, and the cursor will need to be moved back one if it
+	/// was previously past that position. Return 0 otherwise.
+	int checkBiblio(bool track_changes);
 
 public:
 	///
Index: Paragraph.cpp
===================================================================
--- Paragraph.cpp	(revision 18422)
+++ Paragraph.cpp	(working copy)
@@ -2592,11 +2592,15 @@
 }
 
 
-bool Paragraph::checkBiblio(bool track_changes)
+int Paragraph::checkBiblio(bool track_changes)
 {
+	//FIXME From JS:
+	//This is getting more and more a mess. ...We really should clean 
+	//up this bibitem issue for 1.6. See also bug 2743.
+
 	// Add bibitem insets if necessary
 	if (layout()->labeltype != LABEL_BIBLIO)
-		return false;
+		return 0;
 
 	bool hasbibitem = !insetlist.empty()
 		// Insist on it being in pos 0
@@ -2606,33 +2610,52 @@
 	docstring oldkey;
 	docstring oldlabel;
 
-	// remove bibitems in pos != 0
-	// restore them later in pos 0 if necessary
+	// remove a bibitem in pos != 0
+	// restore it later in pos 0 if necessary
 	// (e.g. if a user inserts contents _before_ the item)
-	InsetList::const_iterator it = insetlist.begin();
-	InsetList::const_iterator end = insetlist.end();
+	// we're assuming there's only one of these, which there
+	// should be.
+	int erasedInsetPosition = -1;
+	InsetList::iterator it = insetlist.begin();
+	InsetList::iterator end = insetlist.end();
 	for (; it != end; ++it)
 		if (it->inset->lyxCode() == Inset::BIBITEM_CODE
 		    && it->pos > 0) {
 			InsetBibitem * olditem = static_cast<InsetBibitem *>(it->inset);
 			oldkey = olditem->getParam("key");
 			oldlabel = olditem->getParam("label");
-			eraseChar(it->pos, track_changes);
+			erasedInsetPosition = it->pos;
+			eraseChar(erasedInsetPosition, track_changes);
+			break;
 	}
 
-	if (hasbibitem)
-		return false;
-
+	//There was an InsetBibitem at the beginning, and we didn't
+	//have to erase one.
+	if (hasbibitem && erasedInsetPosition < 0)
+			return 0;
+	
+	//There was an InsetBibitem at the beginning and we did have to 
+	//erase one. So we give its properties to the beginning inset.
+	if (hasbibitem) {
+		InsetBibitem * inset = 
+			static_cast<InsetBibitem *>(insetlist.begin()->inset);
+		if (!oldkey.empty())
+			inset->setParam("key", oldkey);
+		inset->setParam("label", oldlabel);
+		return -erasedInsetPosition;
+	}
+	
+	//There was no inset at the beginning, so we need to create one with
+	//the key and label of the one we erased.
 	InsetBibitem * inset(new InsetBibitem(InsetCommandParams("bibitem")));
 	// restore values of previously deleted item in this par.
 	if (!oldkey.empty())
 		inset->setParam("key", oldkey);
-	if (!oldlabel.empty())
-		inset->setParam("label", oldlabel);
+	inset->setParam("label", oldlabel);
 	insertInset(0, static_cast<Inset *>(inset),
 		    Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
 
-	return true;
+	return 1;
 }
 
 } // namespace lyx
Index: TextMetrics.cpp
===================================================================
--- TextMetrics.cpp	(revision 18422)
+++ TextMetrics.cpp	(working copy)
@@ -190,10 +190,20 @@
 	main_text_ = (text_ == &buffer.text());
 	bool changed = false;
 
-	// FIXME: this has nothing to do here and is the reason why text_ is not
-	// const.
-	if (par.checkBiblio(buffer.params().trackChanges))
+	// FIXME This check ought to be done somewhere else. It is the reason 
+	// why text_ is not	const. But then, where else to do it?
+	// Well, how can you end up with either (a) a biblio environment that
+	// has no InsetBibitem or (b) a biblio environment with more than one
+	// InsetBibitem? I think the answer is: when paragraphs are merged;
+	// when layout is set; when material is pasted.
+	int const moveCursor = par.checkBiblio(buffer.params().trackChanges);
+	if (moveCursor > 0)
 		const_cast<Cursor &>(bv_->cursor()).posRight();
+	else if (moveCursor < 0) {
+		Cursor & cursor = const_cast<Cursor &>(bv_->cursor());
+		if (cursor.pos() >= -moveCursor)
+			cursor.posLeft();
+	}
 
 	// Optimisation: this is used in the next two loops
 	// so better to calculate that once here.

Reply via email to