Fix crash introduced in my previous commit f6b1c24b

Cursor::fixIfBroken does not do what I thought it did. Lift some code
from StableDocIterator::asDocIterator instead.
This commit is contained in:
Jean-Marc Lasgouttes 2012-07-17 22:26:44 +02:00
parent e2b42b1726
commit 6ec1683aee
4 changed files with 48 additions and 25 deletions

View File

@ -2313,6 +2313,14 @@ bool Cursor::fixIfBroken()
} }
void Cursor::sanitize()
{
setBuffer(&bv_->buffer());
DocIterator::sanitize();
anchor_.sanitize();
}
bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur) bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur)
{ {
// find inset in common // find inset in common
@ -2400,7 +2408,7 @@ bool Cursor::textUndo()
{ {
if (!buffer()->undo().textUndo(*this)) if (!buffer()->undo().textUndo(*this))
return false; return false;
fixIfBroken(); sanitize();
return true; return true;
} }
@ -2409,7 +2417,7 @@ bool Cursor::textRedo()
{ {
if (!buffer()->undo().textRedo(*this)) if (!buffer()->undo().textRedo(*this))
return false; return false;
fixIfBroken(); sanitize();
return true; return true;
} }

View File

@ -306,6 +306,9 @@ public:
/// fix cursor in circumstances that should never happen. /// fix cursor in circumstances that should never happen.
/// \retval true if a fix occured. /// \retval true if a fix occured.
bool fixIfBroken(); bool fixIfBroken();
/// Repopulate the slices insets from bottom to top. Useful
/// for stable iterators or Undo data.
void sanitize();
/// output /// output
friend std::ostream & operator<<(std::ostream & os, Cursor const & cur); friend std::ostream & operator<<(std::ostream & os, Cursor const & cur);

View File

@ -530,6 +530,35 @@ bool DocIterator::fixIfBroken()
} }
void DocIterator::sanitize()
{
// this function re-creates the cache of inset pointers
//lyxerr << "converting:\n" << *this << endl;
if (buffer_)
inset_ = &buffer_->inset();
Inset * inset = inset_;
for (size_t i = 0, n = slices_.size(); i != n; ++i) {
if (inset == 0) {
// FIXME
LYXERR0(" Should not happen, but does e.g. after "
"C-n C-l C-z S-C-z\n"
<< " or when a Buffer has been concurrently edited by two views"
<< '\n' << "dit: " << *this << '\n'
<< " lastpos: " << slices_[i].lastpos());
fixIfBroken();
break;
}
slices_[i].inset_ = inset;
if (fixIfBroken())
break;
if (i + 1 != n)
inset = slices_[i].inset().inMathed() ? slices_[i].cell()[slices_[i].pos()].nucleus()
: slices_[i].paragraph().getInset(pos());
}
//lyxerr << "convert:\n" << *this << " to:\n" << dit << endl;
}
int DocIterator::find(MathData const & cell) const int DocIterator::find(MathData const & cell) const
{ {
for (size_t l = 0; l != slices_.size(); ++l) { for (size_t l = 0; l != slices_.size(); ++l) {
@ -597,29 +626,9 @@ StableDocIterator::StableDocIterator(DocIterator const & dit)
DocIterator StableDocIterator::asDocIterator(Buffer * buf) const DocIterator StableDocIterator::asDocIterator(Buffer * buf) const
{ {
// this function re-creates the cache of inset pointers DocIterator dit = DocIterator(buf);
//lyxerr << "converting:\n" << *this << endl; dit.slices_ = data_;
Inset * inset = &buf->inset(); dit.sanitize();
DocIterator dit = DocIterator(buf, inset);
for (size_t i = 0, n = data_.size(); i != n; ++i) {
if (inset == 0) {
// FIXME
LYXERR0(" Should not happen, but does e.g. after "
"C-n C-l C-z S-C-z\n"
<< " or when a Buffer has been concurrently edited by two views"
<< '\n' << "dit: " << dit << '\n'
<< " lastpos: " << dit.lastpos());
dit.fixIfBroken();
break;
}
dit.push_back(data_[i]);
dit.top().inset_ = inset;
if (dit.fixIfBroken())
break;
if (i + 1 != n)
inset = dit.nextInset();
}
//lyxerr << "convert:\n" << *this << " to:\n" << dit << endl;
return dit; return dit;
} }

View File

@ -231,6 +231,9 @@ public:
/// fix DocIterator in circumstances that should never happen. /// fix DocIterator in circumstances that should never happen.
/// \return true if the DocIterator was fixed. /// \return true if the DocIterator was fixed.
bool fixIfBroken(); bool fixIfBroken();
/// Repopulate the slices insets from bottom to top. Useful
/// for stable iterators or Undo data.
void sanitize();
/// find index of CursorSlice with &cell() == &cell (or -1 if not found) /// find index of CursorSlice with &cell() == &cell (or -1 if not found)
int find(MathData const & cell) const; int find(MathData const & cell) const;