X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FDocIterator.cpp;h=a29f364aa3deab5f974dc6adcb64f25a646bca12;hb=0362c6aae73c293d1c20277c12d362acfe0b2ef6;hp=d898ff0608c456e55ae47394bb267903480a9718;hpb=09b0a337ca8c82813a9cd938961a51bc9e49b22b;p=lyx.git diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index d898ff0608..a29f364aa3 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -14,20 +14,22 @@ #include "DocIterator.h" -#include "debug.h" -#include "Text.h" +#include "InsetList.h" #include "Paragraph.h" +#include "Text.h" #include "mathed/MathData.h" #include "mathed/InsetMath.h" #include "insets/InsetTabular.h" +#include "support/debug.h" + #include -#include -using std::endl; +#include +using namespace std; namespace lyx { @@ -58,18 +60,25 @@ DocIterator doc_iterator_end(Inset & inset) } +LyXErr & operator<<(LyXErr & os, DocIterator const & it) +{ + os.stream() << it; + return os; +} + + Inset * DocIterator::nextInset() const { BOOST_ASSERT(!empty()); if (pos() == lastpos()) return 0; if (pos() > lastpos()) { - lyxerr << "Should not happen, but it does. " << endl; + LYXERR0("Should not happen, but it does. "); return 0; } if (inMathed()) return nextAtom().nucleus(); - return paragraph().isInset(pos()) ? paragraph().getInset(pos()) : 0; + return paragraph().getInset(pos()); } @@ -78,7 +87,7 @@ Inset * DocIterator::prevInset() const BOOST_ASSERT(!empty()); if (pos() == 0) return 0; - if (inMathed()) + if (inMathed()) { if (cell().empty()) // FIXME: this should not happen but it does. // See bug 3189 @@ -86,7 +95,8 @@ Inset * DocIterator::prevInset() const return 0; else return prevAtom().nucleus(); - return paragraph().isInset(pos() - 1) ? paragraph().getInset(pos() - 1) : 0; + } + return paragraph().getInset(pos() - 1); } @@ -94,7 +104,7 @@ Inset * DocIterator::realInset() const { BOOST_ASSERT(inTexted()); // if we are in a tabular, we need the cell - if (inset().lyxCode() == Inset::TABULAR_CODE) { + if (inset().lyxCode() == TABULAR_CODE) { InsetTabular & tabular = static_cast(inset()); return tabular.cell(idx()).get(); } @@ -129,25 +139,33 @@ Text * DocIterator::text() const Paragraph & DocIterator::paragraph() const { if (!inTexted()) - lyxerr << *this << endl; + LYXERR0(*this); BOOST_ASSERT(inTexted()); return top().paragraph(); } Paragraph & DocIterator::innerParagraph() const +{ + BOOST_ASSERT(!empty()); + return innerTextSlice().paragraph(); +} + + +CursorSlice const & DocIterator::innerTextSlice() const { BOOST_ASSERT(!empty()); // go up until first non-0 text is hit // (innermost text is 0 in mathed) for (int i = depth() - 1; i >= 0; --i) if (slices_[i].text()) - return slices_[i].paragraph(); + return slices_[i]; // This case is in principe not possible. We _must_ - // be inside a Paragraph. + // be inside a Text. BOOST_ASSERT(false); - return paragraph(); + static CursorSlice dummy; + return dummy; } @@ -230,24 +248,16 @@ Inset * DocIterator::innerInsetOfType(int code) const } -void DocIterator::forwardPos(bool ignorecollapsed) +// This duplicates code above, but is in the critical path. +// So please think twice before adding stuff +void DocIterator::forwardPos() { - //this dog bites his tail + // this dog bites his tail if (empty()) { push_back(CursorSlice(*inset_)); return; } - Inset * const nextinset = nextInset(); - // jump over collapsables if they are collapsed - // FIXME: the check for asInsetMath() shouldn't be necessary - // but math insets do not return a sensible editable() state yet. - if (ignorecollapsed && nextinset && (!nextinset->asInsetMath() - && nextinset->editable() != Inset::HIGHLY_EDITABLE)) { - ++top().pos(); - return; - } - CursorSlice & tip = top(); //lyxerr << "XXX\n" << *this << endl; @@ -259,12 +269,10 @@ void DocIterator::forwardPos(bool ignorecollapsed) if (tip.pos() != lastp) { // this is impossible for pos() == size() - if (inMathed()) { + if (inMathed()) n = (tip.cell().begin() + tip.pos())->nucleus(); - } else { - if (paragraph().isInset(tip.pos())) - n = paragraph().getInset(tip.pos()); - } + else + n = paragraph().getInset(tip.pos()); } if (n && n->isActive()) { @@ -285,6 +293,20 @@ void DocIterator::forwardPos(bool ignorecollapsed) } +void DocIterator::forwardPosIgnoreCollapsed() +{ + Inset * const nextinset = nextInset(); + // FIXME: the check for asInsetMath() shouldn't be necessary + // but math insets do not return a sensible editable() state yet. + if (nextinset && !nextinset->asInsetMath() + && nextinset->editable() != Inset::HIGHLY_EDITABLE) { + ++top().pos(); + return; + } + forwardPos(); +} + + void DocIterator::forwardPar() { forwardPos(); @@ -294,7 +316,7 @@ void DocIterator::forwardPar() pos_type const lastp = lastpos(); Paragraph const & par = paragraph(); pos_type & pos = top().pos(); - if (par.insetlist.empty()) + if (par.insetList().empty()) pos = lastp; else while (pos < lastp && !par.isInset(pos)) @@ -361,12 +383,10 @@ void DocIterator::backwardPos() // move into an inset to the left if possible Inset * n = 0; - if (inMathed()) { + if (inMathed()) n = (top().cell().begin() + top().pos())->nucleus(); - } else { - if (paragraph().isInset(top().pos())) - n = paragraph().getInset(top().pos()); - } + else + n = paragraph().getInset(top().pos()); if (n && n->isActive()) { push_back(CursorSlice(*n)); @@ -391,24 +411,26 @@ bool DocIterator::hasPart(DocIterator const & it) const void DocIterator::updateInsets(Inset * inset) { // this function re-creates the cache of inset pointers. - // code taken in part from StableDocIterator::asDocIterator. //lyxerr << "converting:\n" << *this << endl; - DocIterator dit = DocIterator(*inset); + DocIterator dit = *this; size_t const n = slices_.size(); + slices_.resize(0); for (size_t i = 0 ; i < n; ++i) { BOOST_ASSERT(inset); - dit.push_back(slices_[i]); - dit.top().inset_ = inset; + push_back(dit[i]); + top().inset_ = inset; if (i + 1 != n) - inset = dit.nextInset(); + inset = nextInset(); } //lyxerr << "converted:\n" << *this << endl; - operator=(dit); } bool DocIterator::fixIfBroken() { + if (empty()) + return false; + // 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 @@ -420,29 +442,29 @@ bool DocIterator::fixIfBroken() if (&cs.inset() != inset) { // the whole slice is wrong, chop off this as well --i; - LYXERR(Debug::DEBUG) << "fixIfBroken(): inset changed" << endl; + LYXERR(Debug::DEBUG, "fixIfBroken(): inset changed"); 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; + LYXERR(Debug::DEBUG, "fixIfBroken(): idx fixed"); break; } else if (cs.pit() > cs.lastpit()) { cs.pit() = cs.lastpit(); cs.pos() = cs.lastpos(); - LYXERR(Debug::DEBUG) << "fixIfBroken(): pit fixed" << endl; + LYXERR(Debug::DEBUG, "fixIfBroken(): pit fixed"); break; } else if (cs.pos() > cs.lastpos()) { cs.pos() = cs.lastpos(); - LYXERR(Debug::DEBUG) << "fixIfBroken(): pos fixed" << endl; + LYXERR(Debug::DEBUG, "fixIfBroken(): pos fixed"); 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 if (Inset * csInset = cs.paragraph().getInset(cs.pos())) + inset = csInset; else { // there are slices left, so there must be another inset break; @@ -453,7 +475,7 @@ bool DocIterator::fixIfBroken() // 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; + LYXERR(Debug::DEBUG, "fixIfBroken(): cursor chopped at " << i); resize(i + 1); return true; } else @@ -461,34 +483,58 @@ bool DocIterator::fixIfBroken() } -std::ostream & operator<<(std::ostream & os, DocIterator const & dit) +int DocIterator::find(MathData const & cell) const { - for (size_t i = 0, n = dit.depth(); i != n; ++i) - os << " " << dit[i] << "\n"; - return os; + for (size_t l = 0; l != slices_.size(); ++l) { + if (slices_[l].asInsetMath() && &slices_[l].cell() == &cell) + return l; + } + return -1; } -bool operator<(DocIterator const & p, DocIterator const & q) +int DocIterator::find(InsetMath const * inset) const { - 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]; + for (size_t l = 0; l != slices_.size(); ++l) { + if (slices_[l].asInsetMath() == inset) + return l; } - return p.depth() < q.depth(); + return -1; +} + + +void DocIterator::cutOff(int above, vector & cut) +{ + cut = vector(slices_.begin() + above + 1, slices_.end()); + slices_.resize(above + 1); +} + + +void DocIterator::cutOff(int above) +{ + slices_.resize(above + 1); +} + + +void DocIterator::append(vector const & x) +{ + slices_.insert(slices_.end(), x.begin(), x.end()); } -bool operator>(DocIterator const & p, DocIterator const & q) +void DocIterator::append(DocIterator::idx_type idx, pos_type pos) { - return q < p; + slices_.push_back(CursorSlice()); + top().idx() = idx; + top().pos() = pos; } -bool operator<=(DocIterator const & p, DocIterator const & q) +ostream & operator<<(ostream & os, DocIterator const & dit) { - return !(q < p); + for (size_t i = 0, n = dit.depth(); i != n; ++i) + os << " " << dit[i] << "\n"; + return os; } @@ -510,11 +556,11 @@ DocIterator StableDocIterator::asDocIterator(Inset * inset) const for (size_t i = 0, n = data_.size(); i != n; ++i) { 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\n" - << " or when a Buffer has been concurently edited by two views" + 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() << endl; + << " lastpos: " << dit.lastpos()); dit.fixIfBroken(); break; } @@ -530,7 +576,7 @@ DocIterator StableDocIterator::asDocIterator(Inset * inset) const } -std::ostream & operator<<(std::ostream & os, StableDocIterator const & dit) +ostream & operator<<(ostream & os, StableDocIterator const & dit) { for (size_t i = 0, n = dit.data_.size(); i != n; ++i) os << " " << dit.data_[i] << "\n";