>>>>> "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());
}