>>>>> "Enrico" == Enrico Forestieri <[EMAIL PROTECTED]> writes:

Enrico> On Mon, Aug 14, 2006 at 05:21:49PM +0200, Jean-Marc Lasgouttes
Enrico> wrote:
>> The following patch fixes this bug for me.

Enrico> Indeed, the crash is gone. However, after applying this patch
Enrico> I still observe a weird behavior which may be reproduced by
Enrico> the following steps:

Enrico> 1) Ctrl-N (new document) 2) Shift-Ctrl-M (math display) 3) x^2
Enrico> 4) Backspace (delete the "2") 5) Cursor down (cursor is to the
Enrico> left of x but outside the scriptinset) 6) Cursor right (cursor
Enrico> is to the left of x but inside the scriptinset) 7) Undo 8)
Enrico> Redo

OK, I see it indeed. What happens is that, when the script inset
deletes its superscript, all that remains is a script inset with only
one cell. Any undo concerning this inset will contain only the script
"x", which is parsed as a single character, not a scriptinset.

Actually, when it does not have any script, the script inset should
commit suicide and replace itself with its contents. This is what this
updated patch does. I checked that it works and valgrind does not
complain. 

Please test. I am unsure of the unintended consequences of this patch
(recordUndoInset semantics changes, scriptinset suicide,
scriptinset::write changes). Only the addition of the recordUndoInset
calls is trivially correct.

JMarc

Index: src/mathed/math_scriptinset.C
===================================================================
--- src/mathed/math_scriptinset.C	(revision 14774)
+++ src/mathed/math_scriptinset.C	(working copy)
@@ -19,6 +19,7 @@
 #include "cursor.h"
 #include "debug.h"
 #include "funcrequest.h"
+#include "undo.h"
 
 #include <boost/assert.hpp>
 
@@ -432,10 +433,10 @@ void MathScriptInset::write(WriteStream 
 			os << "{}";
 	}
 
-	if (hasDown() && down().size())
+	if (hasDown() /*&& down().size()*/)
 		os << "_{" << down() << '}';
 
-	if (hasUp() && up().size())
+	if (hasUp() /*&& up().size()*/)
 		os << "^{" << up() << '}';
 
 	if (lock_ && !os.latex())
@@ -563,15 +564,28 @@ void MathScriptInset::notifyCursorLeaves
 		// Case of two scripts. In this case, 1 = super, 2 = sub
 		if (cur.idx() == 2 && cell(2).empty()) {
 			// must be a subscript...
+			recordUndoInset(cur);
 			removeScript(false);
 		} else if (cur.idx() == 1 && cell(1).empty()) {
 			// must be a superscript...
+			recordUndoInset(cur);
 			removeScript(true);
 		}
 	} else if (nargs() > 1 && cur.idx() == 1 && cell(1).empty()) {
 		// could be either subscript or super script
+		recordUndoInset(cur);
 		removeScript(cell_1_is_up_);
-}
+		// Let the script inset commit suicide. This is
+		// modelled on LCursor.pullArg(), but tries not to
+		// invoke notifyCursorLeaves again and does not touch
+		// cur (since the top slice will be deleted
+		// afterwards))
+		MathArray ar = cell(0);
+		LCursor tmpcur = cur;
+		tmpcur.pop();
+		tmpcur.cell().erase(tmpcur.pos());
+		tmpcur.cell().insert(tmpcur.pos(), ar);
+	}
 
 	//lyxerr << "MathScriptInset::notifyCursorLeaves: 2 " << cur << endl;
 }
Index: src/mathed/math_inset.C
===================================================================
--- src/mathed/math_inset.C	(revision 14774)
+++ src/mathed/math_inset.C	(working copy)
@@ -18,6 +18,8 @@
 
 #include "support/lstrings.h"
 
+#include <boost/current_function.hpp>
+
 using std::string;
 using std::ostream;
 using std::endl;
@@ -26,7 +28,7 @@ using std::endl;
 MathArray & MathInset::cell(idx_type)
 {
 	static MathArray dummyCell;
-	lyxerr << "I don't have a cell 1" << endl;
+	lyxerr << BOOST_CURRENT_FUNCTION << ": I don't have any cell" << endl;
 	return dummyCell;
 }
 
@@ -34,7 +36,7 @@ MathArray & MathInset::cell(idx_type)
 MathArray const & MathInset::cell(idx_type) const
 {
 	static MathArray dummyCell;
-	lyxerr << "I don't have a cell 2" << endl;
+	lyxerr << BOOST_CURRENT_FUNCTION << ": I don't have any cell" << endl;
 	return dummyCell;
 }
 
Index: src/undo.C
===================================================================
--- src/undo.C	(revision 14774)
+++ src/undo.C	(working copy)
@@ -168,6 +168,7 @@ bool textUndoOrRedo(BufferView & bv,
 		// We stored the full cell here as there is not much to be
 		// gained by storing just 'a few' paragraphs (most if not
 		// all math inset cells have just one paragraph!)
+		//lyxerr << "undo.array=" << undo.array <<endl;
 		asArray(undo.array, dit.cell());
 	} else {
 		// Some finer machinery is needed here.
@@ -251,7 +252,9 @@ void recordUndoInset(LCursor & cur, Undo
 {
 	LCursor c = cur;
 	c.pop();
-	recordUndo(c, kind);
+	Buffer * buf = cur.bv().buffer();
+	doRecordUndo(kind, c, c.pit(), c.pit(),	cur.bv().cursor(),
+		     buf->params(), false, buf->undostack());
 }
 
 

Reply via email to