>>>>> "Jean-Marc" == Jean-Marc Lasgouttes <[EMAIL PROTECTED]> writes:

Jean-Marc> Basically, dEPM compares the tips of cursors without caring
Jean-Marc> whether they are at same depth (insert apples and oranges
Jean-Marc> comment here). Here undo is called between two cursors at
Jean-Marc> different depth :(

Jean-Marc> This is a real mess.

I can confirm that last sentence.

The following patch does a cleanup of dEPM in the following respects:

1/ call recordUndo with the right cursor, and only for the pit
contains `old' (this is the only paragraph we change)

2/ when comparing cursors, do not compare pit:s without first checking
that they are relative to the same inset

3/ when a paragraph has been removed,try to update the right slice of
`cur', which might not be the top.

4/ simplify the code to the point where I understand it.

The result of this patch is that I do not get a crash in dEPM any more
with the following (description courtesy of Bennett):

> Type some arbitrary text. Below this, create an inset in a paragraph  
> all by itself; set this paragraph to have no indentation. Place the  
> cursor at the end of the line immediately above the inset. Press  
> return to create a new paragraph, and then down-arrow: crash.

However, I still get a crash in fitCursor() :(

The relevant backtrace is:

0x0819ee76 in LCursor::getFont (this=0x883ee74) at cursor_slice.h:103
103             LyXText const * text() const { return inset_->getText(idx_); }
(gdb) bt
#0  0x0819ee76 in LCursor::getFont (this=0x883ee74) at cursor_slice.h:103
#1  0x0806d5c1 in BufferView::Pimpl::fitCursor (this=0x883ed60)
    at ../../lyx-devel/src/BufferView_pimpl.C:634
#2  0x0806d852 in BufferView::Pimpl::update (this=0x883ed60, flags=143432372)
    at BufferView.h:52
#3  0x08066a7b in BufferView::update (this=0x88c9ab4, flags=3)
    at ../../lyx-devel/src/BufferView.C:146
#4  0x0821aa33 in LyXFunc::dispatch (this=0x883a028, [EMAIL PROTECTED])
    at BufferView.h:47
#5  0x08215271 in LyXFunc::processKeySym (this=0x883a028, keysym=
        {px = 0x8843778, pn = {pi_ = 0x88daa20}}, state=key_modifier::none)
    at ../../lyx-devel/src/lyxfunc.C:326
#6  0x0806d288 in BufferView::Pimpl::workAreaKeyPress (this=0x883ed60, 
key=Cannot access memory at address 0x1
)
    at LyXView.h:83


I really cannot make sense of it.

Martin, Help!!! 

Here is the patch FWIW. I still think it would be worth committing it.

JMarc

Index: src/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v
retrieving revision 1.2306
diff -u -p -r1.2306 ChangeLog
--- src/ChangeLog	18 Oct 2005 13:34:50 -0000	1.2306
+++ src/ChangeLog	19 Oct 2005 15:43:59 -0000
@@ -1,5 +1,12 @@
 2005-10-18  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
+	* 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'; general cleanup.
+
+2005-10-18  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
+
 	* messages.C: do not forget to include <cerrno>.
 
 2005-10-12  Jürgen Spitzmüller  <[EMAIL PROTECTED]>
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	19 Oct 2005 15:43:59 -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	19 Oct 2005 15:43:59 -0000
@@ -1119,7 +1119,6 @@ bool LyXText::cursorDown(LCursor & cur)
 			cur = dummy;
 
 		return changed;
-
 	}
 
 	bool updateNeeded = false;
@@ -1181,14 +1180,17 @@ 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())
@@ -1217,9 +1219,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 +1233,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 +1242,46 @@ 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();
+				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