X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph_pimpl.C;h=426862c246e3f8d04151b46d8ac03ef240cc1268;hb=946ede62d061aa06c65c16d32d97044090f8e45b;hp=df802cec42a46f2d5433a51107a2553dc0d280f1;hpb=d53d4a5c3528c8dfa06ec55229eacac8f5783150;p=lyx.git diff --git a/src/paragraph_pimpl.C b/src/paragraph_pimpl.C index df802cec42..426862c246 100644 --- a/src/paragraph_pimpl.C +++ b/src/paragraph_pimpl.C @@ -78,15 +78,6 @@ Paragraph::Pimpl::Pimpl(Pimpl const & p, Paragraph * owner) } -void Paragraph::Pimpl::setContentsFromPar(Paragraph const & par) -{ - owner_->text_ = par.text_; - // FIXME: change tracking (MG) - // check whether this method is really needed - changes_ = par.pimpl_->changes_; -} - - bool Paragraph::Pimpl::isChanged(pos_type start, pos_type end) const { BOOST_ASSERT(start >= 0 && start <= size()); @@ -98,14 +89,25 @@ bool Paragraph::Pimpl::isChanged(pos_type start, pos_type end) const void Paragraph::Pimpl::setChange(Change const & change) { - // FIXME: change tracking (MG) - // how about end-of-line? size()+1? - changes_.set(change, 0, size()); - - if (change.type == Change::UNCHANGED) { // only for UNCHANGED ??? - for (pos_type i = 0; i < size(); ++i) { - if (owner_->isInset(i)) { - owner_->getInset(i)->setChange(change); + // beware of the imaginary end-of-par character! + changes_.set(change, 0, size() + 1); + + /* + * Propagate the change recursively - but not in case of DELETED! + * + * Imagine that your co-author makes changes in an existing inset. He + * sends your document to you and you come to the conclusion that the + * inset should go completely. If you erase it, LyX must not delete all + * text within the inset. Otherwise, the change tracked insertions of + * your co-author get lost and there is no way to restore them later. + * + * Conclusion: An inset's content should remain untouched if you delete it + */ + + if (change.type != Change::DELETED) { + for (pos_type pos = 0; pos < size(); ++pos) { + if (owner_->isInset(pos)) { + owner_->getInset(pos)->setChange(change); } } } @@ -118,9 +120,10 @@ void Paragraph::Pimpl::setChange(pos_type pos, Change const & change) changes_.set(change, pos); - // FIXME: change tracking (MG) - // do we have to set the change recursively? - if (pos < size() && owner_->isInset(pos)) { + // see comment in setChange(Change const &) above + + if (change.type != Change::DELETED && + pos < size() && owner_->isInset(pos)) { owner_->getInset(pos)->setChange(change); } } @@ -175,6 +178,10 @@ void Paragraph::Pimpl::rejectChanges(pos_type start, pos_type end) for (pos_type pos = start; pos < end; ++pos) { switch (lookupChange(pos).type) { case Change::UNCHANGED: + // also reject changes inside of insets + if (pos < size() && owner_->isInset(pos)) { + owner_->getInset(pos)->rejectChanges(); + } break; case Change::INSERTED: @@ -189,12 +196,11 @@ void Paragraph::Pimpl::rejectChanges(pos_type start, pos_type end) case Change::DELETED: changes_.set(Change(Change::UNCHANGED), pos); - break; - } - // also reject changes in nested insets - if (pos < size() && owner_->isInset(pos)) { - owner_->getInset(pos)->rejectChanges(); + // Do NOT reject changes within a deleted inset! + // There may be insertions of a co-author inside of it! + + break; } } } @@ -258,21 +264,26 @@ bool Paragraph::Pimpl::eraseChar(pos_type pos, bool trackChanges) BOOST_ASSERT(pos >= 0 && pos <= size()); if (trackChanges) { - Change::Type changetype(changes_.lookup(pos).type); + Change change = changes_.lookup(pos); + + // set the character to DELETED if + // a) it was previously unchanged or + // b) it was inserted by a co-author - if (changetype == Change::UNCHANGED) { + if (change.type == Change::UNCHANGED || + (change.type == Change::INSERTED && change.author != 0)) { setChange(pos, Change(Change::DELETED)); return false; } - if (changetype == Change::DELETED) + if (change.type == Change::DELETED) return false; } - // Don't physically access nonexistent end-of-paragraph char + // Don't physically access the imaginary end-of-paragraph character. + // eraseChar() can only mark it as DELETED. A physical deletion of + // end-of-par must be handled externally. if (pos == size()) { - // FIXME: change tracking (MG) - // how do we handle end-of-pars previously marked inserted? return false; } @@ -326,7 +337,7 @@ bool Paragraph::Pimpl::eraseChar(pos_type pos, bool trackChanges) int Paragraph::Pimpl::eraseChars(pos_type start, pos_type end, bool trackChanges) { BOOST_ASSERT(start >= 0 && start <= size()); - BOOST_ASSERT(end > start && end <= size() + 1); + BOOST_ASSERT(end >= start && end <= size() + 1); pos_type i = start; for (pos_type count = end - start; count; --count) {