X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FDocIterator.cpp;h=2764952b08b2f58588f198eeae6f9ac9b7b48667;hb=e54ae72e5fac6f750c3f7972c74bb42b57f3a049;hp=f6b3b87293eed7509a020c3ad955fa477dc0d3a9;hpb=7b06307cc66b3b956890b9c736ee8304d4206fea;p=lyx.git diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index f6b3b87293..2764952b08 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author André Pönitz + * \author Alfredo Braunstein * * Full author contact details are available in file CREDITS. */ @@ -25,10 +26,10 @@ #include #include +using std::endl; -namespace lyx { -using std::endl; +namespace lyx { // We could be able to get rid of this if only every BufferView were @@ -191,7 +192,7 @@ Paragraph const & DocIterator::innerParagraph() const return slices_[i].paragraph(); // This case is in principe not possible. We _must_ - // we inside a Paragraph. + // be inside a Paragraph. BOOST_ASSERT(false); return paragraph(); } @@ -432,6 +433,19 @@ void DocIterator::forwardPar() } +void DocIterator::forwardIdx() +{ + CursorSlice & tip = top(); + + //prevent endless loops + BOOST_ASSERT(tip.idx() < lastidx()); + + ++tip.idx(); + tip.pit() = 0; + tip.pos() = 0; +} + + void DocIterator::forwardChar() { forwardPos(); @@ -545,6 +559,60 @@ void DocIterator::updateInsets(Inset * inset) } +bool DocIterator::fixIfBroken() +{ + // Go through the slice stack from the bottom. + // Check that all coordinates (idx, pit, pos) are correct and + // that the inset is the one which is claimed to be there + Inset * inset = &slices_[0].inset(); + size_t i = 0; + size_t n = slices_.size(); + for (; i != n; ++i) { + CursorSlice & cs = slices_[i]; + if (&cs.inset() != inset) { + // the whole slice is wrong, chop off this as well + --i; + LYXERR(Debug::DEBUG) << "fixIfBroken(): inset changed" << endl; + break; + } else if (cs.idx() > cs.lastidx()) { + cs.idx() = cs.lastidx(); + cs.pit() = cs.lastpit(); + cs.pos() = cs.lastpos(); + LYXERR(Debug::DEBUG) << "fixIfBroken(): idx fixed" << endl; + break; + } else if (cs.pit() > cs.lastpit()) { + cs.pit() = cs.lastpit(); + cs.pos() = cs.lastpos(); + LYXERR(Debug::DEBUG) << "fixIfBroken(): pit fixed" << endl; + break; + } else if (cs.pos() > cs.lastpos()) { + cs.pos() = cs.lastpos(); + LYXERR(Debug::DEBUG) << "fixIfBroken(): pos fixed" << endl; + break; + } else if (i != n - 1 && cs.pos() != cs.lastpos()) { + // get inset which is supposed to be in the next slice + if (cs.inset().inMathed()) + inset = (cs.cell().begin() + cs.pos())->nucleus(); + else if (cs.paragraph().isInset(cs.pos())) + inset = cs.paragraph().getInset(cs.pos()); + else { + // there are slices left, so there must be another inset + break; + } + } + } + + // Did we make it through the whole slice stack? Otherwise there + // was a problem at slice i, and we have to chop off above + if (i < n) { + LYXERR(Debug::DEBUG) << "fixIfBroken(): cursor chopped at " << i << endl; + resize(i + 1); + return true; + } else + return false; +} + + std::ostream & operator<<(std::ostream & os, DocIterator const & dit) { for (size_t i = 0, n = dit.depth(); i != n; ++i) @@ -553,6 +621,28 @@ std::ostream & operator<<(std::ostream & os, DocIterator const & dit) } +bool operator<(DocIterator const & p, DocIterator const & q) +{ + size_t depth = std::min(p.depth(), q.depth()); + for (size_t i = 0 ; i < depth ; ++i) { + if (p[i] != q[i]) + return p[i] < q[i]; + } + return p.depth() < q.depth(); +} + + +bool operator>(DocIterator const & p, DocIterator const & q) +{ + return q < p; +} + + +bool operator<=(DocIterator const & p, DocIterator const & q) +{ + return !(q < p); +} + /////////////////////////////////////////////////////// @@ -573,14 +663,17 @@ DocIterator StableDocIterator::asDocIterator(Inset * inset) const if (inset == 0) { // FIXME lyxerr << BOOST_CURRENT_FUNCTION - << " Should not happen, but does e.g. after C-n C-l C-z S-C-z" + << " Should not happen, but does e.g. after C-n C-l C-z S-C-z\n" + << " or when a Buffer has been concurently edited by two views" << '\n' << "dit: " << dit << '\n' << " lastpos: " << dit.lastpos() << endl; - //break; - BOOST_ASSERT(false); + dit.fixIfBroken(); + break; } dit.push_back(data_[i]); dit.top().inset_ = inset; + if (dit.fixIfBroken()) + break; if (i + 1 != n) inset = dit.nextInset(); }