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.