X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCompare.cpp;h=c2a01a64df8a189b0e85ed73a7877a6cf1823500;hb=c9609fe56a2deb40f001503c2fd707c990a2e0e2;hp=06730e1b59be6d127b36052a0b4d1ea67961859e;hpb=aa2fac50eb2669d92fbcc8b0cc5af68656088fe0;p=lyx.git diff --git a/src/Compare.cpp b/src/Compare.cpp index 06730e1b59..c2a01a64df 100644 --- a/src/Compare.cpp +++ b/src/Compare.cpp @@ -12,8 +12,10 @@ #include "Compare.h" +#include "Author.h" #include "BufferParams.h" #include "Changes.h" +#include "Font.h" #include "insets/InsetText.h" @@ -22,8 +24,6 @@ #include -#include - using namespace std; using namespace lyx::support; @@ -98,13 +98,15 @@ size_t DocRange::length() const class DocPair { public: - DocPair() {} + DocPair() + {} DocPair(DocIterator o_, DocIterator n_) : o(o_), n(n_) {} - bool operator!=(DocPair const & rhs) { + bool operator!=(DocPair const & rhs) + { // this might not be intuitive but correct for our purpose return o != rhs.o && n != rhs.n; } @@ -147,10 +149,16 @@ public: {} /// Returns the from pair - DocPair from() const { return DocPair(o.from, n.from); } + DocPair from() const + { + return DocPair(o.from, n.from); + } /// Returns the to pair - DocPair to() const { return DocPair(o.to, n.to); } + DocPair to() const + { + return DocPair(o.to, n.to); + } DocRange o; DocRange n; @@ -182,7 +190,8 @@ static DocRangePair stepIntoInset(DocPair const & inset_location) template class compl_vector { public: - compl_vector() {} + compl_vector() + {} void reset(T const & def) { @@ -224,7 +233,8 @@ public: {} /// - ~Impl() {} + ~Impl() + {} // Algorithm to find the shortest edit string. This algorithm // only needs a linear amount of memory (linear with the sum @@ -236,7 +246,8 @@ public: bool abort_; /// - QString status() { + QString status() + { QString status; status += toqstr("recursion level:") + " " + QString::number(recursion_level_) + " " + toqstr("differences:") + " " + QString::number(D_); @@ -259,7 +270,7 @@ private: SnakeResult retrieveMiddleSnake(int k, int D, Direction direction, DocPair & middle_snake); - /// Find the the furthest reaching D-path (number of horizontal + /// Find the furthest reaching D-path (number of horizontal /// and vertical steps; differences between the old and new /// document) in the k-diagonal (vertical minus horizontal steps). void furthestDpathKdiagonal(int D, int k, @@ -273,7 +284,7 @@ private: /// around the middle snake. void diff_i(DocRangePair const & rp); - /// Processes the splitted chunks. It either adds them as deleted, + /// Processes the split chunks. It either adds them as deleted, /// as added, or call diff_i for further processing. void diffPart(DocRangePair const & rp); @@ -365,10 +376,17 @@ void Compare::run() if (!dest_buffer || !new_buffer || !old_buffer) return; - // Copy the buffer params to the new buffer + // Copy the buffer params to the destination buffer dest_buffer->params() = options_.settings_from_new ? new_buffer->params() : old_buffer->params(); + // Copy extra authors to the destination buffer + AuthorList const & extra_authors = options_.settings_from_new ? + old_buffer->params().authors() : new_buffer->params().authors(); + AuthorList::Authors::const_iterator it = extra_authors.begin(); + for (; it != extra_authors.end(); ++it) + dest_buffer->params().authors().record(*it); + doStatusMessage(); // do the real work @@ -445,7 +463,15 @@ static bool equal(Inset const * i_o, Inset const * i_n) } -static bool equal(DocIterator & o, DocIterator & n) { +static bool equal(DocIterator & o, DocIterator & n) +{ + // Explicitly check for this, so we won't call + // Paragraph::getChar for the last pos. + bool const o_lastpos = o.pos() == o.lastpos(); + bool const n_lastpos = n.pos() == n.lastpos(); + if (o_lastpos || n_lastpos) + return o_lastpos && n_lastpos; + Paragraph const & old_par = o.text()->getPar(o.pit()); Paragraph const & new_par = n.text()->getPar(n.pit()); @@ -520,6 +546,7 @@ void Compare::Impl::furthestDpathKdiagonal(int D, int k, // Where do we take the step from ? int const kk = vertical_step ? k + 1 : k - 1; DocPair p(op[kk], np[kk]); + DocPair const s(os[kk], ns[kk]); // If D==0 we simulate a vertical step from (0,-1) by doing nothing. if (D != 0) { @@ -541,8 +568,8 @@ void Compare::Impl::furthestDpathKdiagonal(int D, int k, ns[k] = p.n; } else { // Copy last snake from the previous step - os[k] = os[kk]; - ns[k] = ns[kk]; + os[k] = s.o; + ns[k] = s.n; } //Record new position @@ -583,7 +610,7 @@ Compare::Impl::SnakeResult Compare::Impl::retrieveMiddleSnake( if (os[k].empty() && os_r[kk].empty()) { // No, there is no snake at all, in which case // the length of the shortest edit script is M+N. - LASSERT(2 * D - odd_offset_ == M_ + N_, /**/); + LATTEST(2 * D - odd_offset_ == M_ + N_); return NoSnake; } @@ -625,9 +652,10 @@ int Compare::Impl::findMiddleSnake(DocRangePair const & rp, ors.reset(DocIterator()); nrs.reset(DocIterator()); + // In the formula below, the "+ 1" ensures we round like ceil() + int const D_max = (M_ + N_ + 1)/2; // D is the number of horizontal and vertical steps, i.e. // different characters in the old and new chunk. - int const D_max = ceil(((double)M_ + N_)/2); for (int D = 0; D <= D_max; ++D) { // to be used in the status messages D_ = D; @@ -684,7 +712,9 @@ bool Compare::Impl::diff(Buffer const * new_buf, Buffer const * old_buf, processSnake(snake); // Start the recursive algorithm - diff_i(rp); + DocRangePair rp_new(from, rp.to()); + if (!rp_new.o.empty() || !rp_new.n.empty()) + diff_i(rp_new); for (pit_type p = 0; p < (pit_type)dest_pars_->size(); ++p) { (*dest_pars_)[p].setBuffer(const_cast(*dest_buf)); @@ -800,7 +830,7 @@ void Compare::Impl::processSnake(DocRangePair const & rp) pit_type const pit = it.o.pit() - rp.o.from.pit(); pos_type const pos = pit ? it.o.pos() : it.o.pos() - rp.o.from.pos(); inset = pars[pit].getInset(pos); - LASSERT(inset, /**/); + LASSERT(inset, continue); diffInset(inset, it); } }