>>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes:

Martin> I agree, but with the attached mod. It essentially removes the
Martin> cursor from inside the inset if it chances to go there from a
Martin> deletable empty paragraph; so it is a workaround, not a fix.

Martin, you pointed me to the right direction! What happens is that,
if you delete a paragraph from a ParagraphList, all the paragraphs
after it will be cloned and reinserted at the right place. This is
because ParagraphList is a vector<Paragraph>. This means that all the
inset() parts of cur are now wrong. The updated patch fixes these
values.

It works for me. Does it work for you?

JMarc

Index: src/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v
retrieving revision 1.2308
diff -u -p -r1.2308 ChangeLog
--- src/ChangeLog	24 Oct 2005 09:42:18 -0000	1.2308
+++ src/ChangeLog	24 Oct 2005 15:57:05 -0000
@@ -1,3 +1,14 @@
+2005-10-24  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
+	* dociterator.C (updateInsets): new method. Updates the inset_
+	cache of all the slices of the iterator.
+
+	* text2.C (deleteEmptyParagraphMechanism): compare also containing
+	insets when comparing pit/pos; pass the right cursor to
+	recordUndo; when a paragraph has been deleted, compare `old.top()' to
+	the right cursor slice of `cur'; use updateInsets on cur to make
+	sure that the inset caches are correct; general cleanup.
+
 2005-10-21  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
 	* text3.C (dispatch): LFUN_NEXT_INSET_TOGGLE: first try to
Index: src/dociterator.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/dociterator.C,v
retrieving revision 1.31
diff -u -p -r1.31 dociterator.C
--- src/dociterator.C	17 Jul 2005 12:25:59 -0000	1.31
+++ src/dociterator.C	24 Oct 2005 15:57:05 -0000
@@ -490,6 +490,25 @@ bool DocIterator::hasPart(DocIterator co
 }
 
 
+void DocIterator::updateInsets(InsetBase * inset) 
+{
+	// this function re-creates the cache of inset pointers.
+	// code taken in part from StableDocIterator::asDocIterator.
+	//lyxerr << "converting:\n" << *this << endl;
+	DocIterator dit = DocIterator(*inset);
+	size_t const n = slices_.size();
+	for (size_t i = 0 ; i < n; ++i) {
+		BOOST_ASSERT(inset);
+		dit.push_back(slices_[i]);
+		dit.top().inset_ = inset;
+		if (i + 1 != n)
+			inset = dit.nextInset();
+	}
+	//lyxerr << "converted:\n" << *this << endl;
+	operator=(dit);
+}
+
+
 std::ostream & operator<<(std::ostream & os, DocIterator const & dit)
 {
 	for (size_t i = 0, n = dit.depth(); i != n; ++i)
Index: src/dociterator.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/dociterator.h,v
retrieving revision 1.23
diff -u -p -r1.23 dociterator.h
--- src/dociterator.h	13 Oct 2005 17:20:30 -0000	1.23
+++ src/dociterator.h	24 Oct 2005 15:57:05 -0000
@@ -214,6 +214,9 @@ public:
 	void push_back(CursorSlice const & sl) { slices_.push_back(sl); }
 	///
 	void pop_back() { slices_.pop_back(); }
+	/// recompute the inset parts of the cursor from the document data
+	void updateInsets(InsetBase * inset);
+
 private:
 	/**
 	 * When the cursor position is i, is the cursor after the i-th char
Index: src/lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.328
diff -u -p -r1.328 lyxtext.h
--- src/lyxtext.h	13 Oct 2005 14:48:24 -0000	1.328
+++ src/lyxtext.h	24 Oct 2005 15:57:05 -0000
@@ -373,7 +373,7 @@ private:
 	void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
 
 	/// delete double space or empty paragraphs around old cursor
-	bool deleteEmptyParagraphMechanism(LCursor & cur, LCursor const & old);
+	bool deleteEmptyParagraphMechanism(LCursor & cur, LCursor & old);
 
 	///
 	void deleteWordForward(LCursor & cur);
Index: src/text2.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v
retrieving revision 1.633
diff -u -p -r1.633 text2.C
--- src/text2.C	13 Oct 2005 14:48:26 -0000	1.633
+++ src/text2.C	24 Oct 2005 15:57:05 -0000
@@ -1119,7 +1119,6 @@ bool LyXText::cursorDown(LCursor & cur)
 			cur = dummy;
 
 		return changed;
-
 	}
 
 	bool updateNeeded = false;
@@ -1181,32 +1180,29 @@ void LyXText::fixCursorAfterDelete(Curso
 }
 
 
-bool LyXText::deleteEmptyParagraphMechanism(LCursor & cur, LCursor const & old)
+bool LyXText::deleteEmptyParagraphMechanism(LCursor & cur, LCursor & old)
 {
 	// Would be wrong to delete anything if we have a selection.
 	if (cur.selection())
 		return false;
 
 	//lyxerr[Debug::DEBUG] << "DEPM: cur:\n" << cur << "old:\n" << old << endl;
-	Paragraph const & oldpar = pars_[old.pit()];
+	// old should point to us
+	BOOST_ASSERT(old.text() == this);
+
+	Paragraph & oldpar = old.paragraph();
 
 	// We allow all kinds of "mumbo-jumbo" when freespacing.
 	if (oldpar.isFreeSpacing())
 		return false;
 
 	/* Ok I'll put some comments here about what is missing.
-	   I have fixed BackSpace (and thus Delete) to not delete
-	   double-spaces automagically. I have also changed Cut,
-	   Copy and Paste to hopefully do some sensible things.
 	   There are still some small problems that can lead to
 	   double spaces stored in the document file or space at
 	   the beginning of paragraphs(). This happens if you have
 	   the cursor between to spaces and then save. Or if you
 	   cut and paste and the selection have a space at the
-	   beginning and then save right after the paste. I am
-	   sure none of these are very hard to fix, but I will
-	   put out 1.1.4pre2 with FIX_DOUBLE_SPACE defined so
-	   that I can get some feedback. (Lgb)
+	   beginning and then save right after the paste. (Lgb)
 	*/
 
 	// If old.pos() == 0 and old.pos()(1) == LineSeparator
@@ -1217,9 +1213,12 @@ bool LyXText::deleteEmptyParagraphMechan
 	// delete the LineSeparator.
 	// MISSING
 
-	// If the chars around the old cursor were spaces, delete one of them.
-	if (old.pit() != cur.pit() || old.pos() != cur.pos()) {
+	bool const same_inset = &old.inset() == &cur.inset();
+	bool const same_par = same_inset && old.pit() == cur.pit();
+	bool const same_par_pos = same_par && old.pos() == cur.pos();
 
+	// If the chars around the old cursor were spaces, delete one of them.
+	if (!same_par_pos) {
 		// Only if the cursor has really moved.
 		if (old.pos() > 0
 		    && old.pos() < oldpar.size()
@@ -1228,9 +1227,8 @@ bool LyXText::deleteEmptyParagraphMechan
 		    && oldpar.lookupChange(old.pos() - 1) != Change::DELETED) {
 			// We need to set the text to Change::INSERTED to
 			// get it erased properly
-			pars_[old.pit()].setChange(old.pos() -1,
-						   Change::INSERTED);
-			pars_[old.pit()].erase(old.pos() - 1);
+			oldpar.setChange(old.pos() -1, Change::INSERTED);
+			oldpar.erase(old.pos() - 1);
 #ifdef WITH_WARNINGS
 #warning This will not work anymore when we have multiple views of the same buffer
 // In this case, we will have to correct also the cursors held by
@@ -1238,68 +1236,51 @@ bool LyXText::deleteEmptyParagraphMechan
 // automated way in CursorSlice code. (JMarc 26/09/2001)
 #endif
 			// correct all cursor parts
-			fixCursorAfterDelete(cur.top(), old.top());
-#ifdef WITH_WARNINGS
-#warning DEPM, look here
-#endif
-			//fixCursorAfterDelete(cur.anchor(), old.top());
+			if (same_par) {
+				fixCursorAfterDelete(cur.top(), old.top());
+				cur.resetAnchor();
+			}
 			return true;
 		}
 	}
 
 	// only do our magic if we changed paragraph
-	if (old.pit() == cur.pit())
+	if (same_par)
 		return false;
 
 	// don't delete anything if this is the ONLY paragraph!
-	if (pars_.size() == 1)
+	if (old.lastpit() == 0)
 		return false;
 
 	// Do not delete empty paragraphs with keepempty set.
 	if (oldpar.allowEmpty())
 		return false;
 
-	// record if we have deleted a paragraph
-	// we can't possibly have deleted a paragraph before this point
-	bool deleted = false;
-
 	if (oldpar.empty() || (oldpar.size() == 1 && oldpar.isLineSeparator(0))) {
-		// ok, we will delete something
-		deleted = true;
-
-		bool selection_position_was_oldcursor_position =
-			cur.anchor().pit() == old.pit() && cur.anchor().pos() == old.pos();
-
-		// This is a bit of a overkill. We change the old and the cur par
-		// at max, certainly not everything in between...
-		recUndo(old.pit(), cur.pit());
-
 		// Delete old par.
-		pars_.erase(pars_.begin() + old.pit());
-
-		// Update cursor par offset if necessary.
-		// Some 'iterator registration' would be nice that takes care of
-		// such events. Maybe even signal/slot?
-		if (cur.pit() > old.pit())
-			--cur.pit();
-#ifdef WITH_WARNINGS
-#warning DEPM, look here
-#endif
-//		if (cur.anchor().pit() > old.pit())
-//			--cur.anchor().pit();
-
-		if (selection_position_was_oldcursor_position) {
-			// correct selection
-			cur.resetAnchor();
+		recordUndo(old, Undo::ATOMIC, old.pit());
+		ParagraphList & plist = old.text()->paragraphs();
+		plist.erase(plist.begin() + old.pit());
+
+		// see #warning above
+		if (cur.depth() >= old.depth()) {
+			CursorSlice & curslice = cur[old.depth() - 1];
+			if (&curslice.inset() == &old.inset() 
+			    && curslice.pit() > old.pit()) {
+				--curslice.pit();
+				// since a paragraph has been deleted, all the
+				// insets after `old' have been copied and
+				// their address has changed. Therefore we
+				// need to `regenerate' cur. (JMarc)
+				cur.updateInsets(&(cur.bottom().inset()));
+				cur.resetAnchor();
+			}
 		}
-	}
-
-	if (deleted) {
-		updateCounters(cur.buffer());
+		updateCounters(old.buffer());
 		return true;
 	}
 
-	if (pars_[old.pit()].stripLeadingSpaces())
+	if (oldpar.stripLeadingSpaces())
 		cur.resetAnchor();
 
 	return false;

Reply via email to