diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 663bc7552f..b0f7b7074e 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -2313,6 +2313,14 @@ bool Cursor::fixIfBroken() } +void Cursor::sanitize() +{ + setBuffer(&bv_->buffer()); + DocIterator::sanitize(); + anchor_.sanitize(); +} + + bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur) { // find inset in common @@ -2400,7 +2408,7 @@ bool Cursor::textUndo() { if (!buffer()->undo().textUndo(*this)) return false; - fixIfBroken(); + sanitize(); return true; } @@ -2409,7 +2417,7 @@ bool Cursor::textRedo() { if (!buffer()->undo().textRedo(*this)) return false; - fixIfBroken(); + sanitize(); return true; } diff --git a/src/Cursor.h b/src/Cursor.h index 318c5d9a6d..31debbf9c4 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -306,6 +306,9 @@ public: /// fix cursor in circumstances that should never happen. /// \retval true if a fix occured. bool fixIfBroken(); + /// Repopulate the slices insets from bottom to top. Useful + /// for stable iterators or Undo data. + void sanitize(); /// output friend std::ostream & operator<<(std::ostream & os, Cursor const & cur); diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index 310b85131b..5cd1c0eac3 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -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 { for (size_t l = 0; l != slices_.size(); ++l) { @@ -597,29 +626,9 @@ StableDocIterator::StableDocIterator(DocIterator const & dit) DocIterator StableDocIterator::asDocIterator(Buffer * buf) const { - // this function re-creates the cache of inset pointers - //lyxerr << "converting:\n" << *this << endl; - Inset * inset = &buf->inset(); - 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; + DocIterator dit = DocIterator(buf); + dit.slices_ = data_; + dit.sanitize(); return dit; } diff --git a/src/DocIterator.h b/src/DocIterator.h index 2aeff8fca1..3d5647c893 100644 --- a/src/DocIterator.h +++ b/src/DocIterator.h @@ -231,6 +231,9 @@ public: /// fix DocIterator in circumstances that should never happen. /// \return true if the DocIterator was fixed. 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) int find(MathData const & cell) const;