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

Jean-Marc> If I click outside of the math inset LyX crashes :) I'll
Jean-Marc> have a look.

This update patch fixes the problem by making notifyCursorLeaves
return true if cursor is not invalid. I also changed recordUndoInset
to use cur instead of bv().cursor() as cursor (this is what the other
code does; should be equivalent though).

I have applied a small part (fix debug messages) which is independent
from the rest.

I guess I should split the patch more... Is the recordUndoInset part
OK? 

JMarc

Index: src/insets/insetbase.h
===================================================================
--- src/insets/insetbase.h	(revision 14774)
+++ src/insets/insetbase.h	(working copy)
@@ -170,7 +170,8 @@ public:
 	/// number of columns in gridlike structures
 	virtual size_t ncols() const { return 0; }
 	/// is called when the cursor leaves this inset
-	virtual void notifyCursorLeaves(LCursor &) {}
+	//  returns true if cursor is now invalid.
+	virtual bool notifyCursorLeaves(LCursor &) { return false; }
 
 	/// request "external features"
 	virtual void validate(LaTeXFeatures &) const {}
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())
@@ -552,7 +553,7 @@ void MathScriptInset::infoize2(std::ostr
 }
 
 
-void MathScriptInset::notifyCursorLeaves(LCursor & cur)
+bool MathScriptInset::notifyCursorLeaves(LCursor & cur)
 {
 	MathNestInset::notifyCursorLeaves(cur);
 
@@ -563,17 +564,34 @@ 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);
+			return true;
 		} else if (cur.idx() == 1 && cell(1).empty()) {
 			// must be a superscript...
+			recordUndoInset(cur);
 			removeScript(true);
+			return 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);
+		return true;
+	}
 
 	//lyxerr << "MathScriptInset::notifyCursorLeaves: 2 " << cur << endl;
+	return false;
 }
 
 
Index: src/mathed/math_scriptinset.h
===================================================================
--- src/mathed/math_scriptinset.h	(revision 14774)
+++ src/mathed/math_scriptinset.h	(working copy)
@@ -121,8 +121,8 @@ private:
 	int ndes() const;
 	/// where do we have to draw the scripts?
 	bool hasLimits() const;
-	/// clean up empty cells
-	void notifyCursorLeaves(LCursor & cur);
+	/// clean up empty cells and return true if a cell has been deleted.
+	bool notifyCursorLeaves(LCursor & cur);
 
 	/// possible subscript (index 0) and superscript (index 1)
 	bool cell_1_is_up_;
Index: src/mathed/math_hullinset.C
===================================================================
--- src/mathed/math_hullinset.C	(revision 14774)
+++ src/mathed/math_hullinset.C	(working copy)
@@ -383,7 +383,7 @@ void MathHullInset::addPreview(lyx::grap
 }
 
 
-void MathHullInset::notifyCursorLeaves(LCursor & cur)
+bool MathHullInset::notifyCursorLeaves(LCursor & cur)
 {
 	if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
 		Buffer const & buffer = cur.buffer();
@@ -391,6 +391,7 @@ void MathHullInset::notifyCursorLeaves(L
 		preview_->addPreview(snippet, buffer);
 		preview_->startLoading(buffer);
 	}
+	return false;
 }
 
 
Index: src/mathed/math_hullinset.h
===================================================================
--- src/mathed/math_hullinset.h	(revision 14774)
+++ src/mathed/math_hullinset.h	(working copy)
@@ -113,7 +113,7 @@ public:
 		OutputParams const &) const;
 
 	/// get notification when the cursor leaves this inset
-	void notifyCursorLeaves(LCursor & cur);
+	bool notifyCursorLeaves(LCursor & cur);
 	///
 	//bool insetAllowed(Code code) const;
 	///
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C	(revision 14774)
+++ src/mathed/math_nestinset.C	(working copy)
@@ -344,7 +344,7 @@ int MathNestInset::latex(Buffer const &,
 }
 
 
-void MathNestInset::notifyCursorLeaves(LCursor & cur)
+bool MathNestInset::notifyCursorLeaves(LCursor & cur)
 {
 #ifdef WITH_WARNINGS
 #warning look here
@@ -373,6 +373,7 @@ void MathNestInset::notifyCursorLeaves(L
 		}
 	}
 #endif
+	return false;
 }
 
 
Index: src/mathed/math_nestinset.h
===================================================================
--- src/mathed/math_nestinset.h	(revision 14774)
+++ src/mathed/math_nestinset.h	(working copy)
@@ -65,7 +65,7 @@ public:
 	/// access to the lock
 	void lock(bool);
 	/// get notification when the cursor leaves this inset
-	void notifyCursorLeaves(LCursor & cur);
+	bool notifyCursorLeaves(LCursor & cur);
 
 	/// direct access to the cell
 	MathArray & cell(idx_type);
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,
+		     buf->params(), false, buf->undostack());
 }
 
 
Index: src/BufferView.C
===================================================================
--- src/BufferView.C	(revision 14774)
+++ src/BufferView.C	(working copy)
@@ -327,11 +327,13 @@ void BufferView::mouseSetCursor(LCursor 
 	BOOST_ASSERT(&cur.bv() == this);
 
 	// Has the cursor just left the inset?
+	bool badcursor = false;
 	if (&cursor().inset() != &cur.inset())
-		cursor().inset().notifyCursorLeaves(cursor());
+		badcursor = cursor().inset().notifyCursorLeaves(cursor());
 
 	// do the dEPM magic if needed
-	if (cursor().inTexted())
+	// FIXME: move this to InsetText::notifyCursorLeaves?
+	if (!badcursor && cursor().inTexted())
 		cursor().text()->deleteEmptyParagraphMechanism(cur, cursor());
 
 	cursor() = cur;

Reply via email to