From 3468a572708d10aecbaeced77534f891638b97bd Mon Sep 17 00:00:00 2001 From: Perry Rapp Date: Sun, 7 Aug 2005 20:27:57 +0000 Subject: [PATCH] PATCH: [ 1248259 ] Preserve trivial diffs in diff chain Src: DiffList.cpp DiffList.h DiffWrapper.cpp LocationView.cpp LocationView.h MergeDiffDetailView.cpp MergeDiffDetailView.h MergeDoc.cpp MergeEditView.cpp MergeEditView.h --- Src/DiffList.cpp | 122 +++++++++++++++++++++++++++++++++++--------- Src/DiffList.h | 33 ++++++++++-- Src/DiffWrapper.cpp | 4 +- Src/LocationView.cpp | 77 ++++++++++++++++------------ Src/LocationView.h | 1 + Src/MergeDiffDetailView.cpp | 14 ++++- Src/MergeDiffDetailView.h | 2 + Src/MergeDoc.cpp | 41 ++++----------- Src/MergeEditView.cpp | 87 ++++++++++++++++++++++--------- Src/MergeEditView.h | 2 + Src/readme.txt | 6 +++ 11 files changed, 269 insertions(+), 120 deletions(-) diff --git a/Src/DiffList.cpp b/Src/DiffList.cpp index f9ad95b89..2f39e8ea8 100644 --- a/Src/DiffList.cpp +++ b/Src/DiffList.cpp @@ -32,6 +32,8 @@ DiffList::DiffList() { m_diffs.SetSize(64); + m_firstSignificant = -1; + m_lastSignificant = -1; } /** @@ -40,6 +42,8 @@ DiffList::DiffList() void DiffList::Clear() { m_diffs.RemoveAll(); + m_firstSignificant = -1; + m_lastSignificant = -1; } /** @@ -63,28 +67,42 @@ void DiffList::SetSize(UINT nSize) */ void DiffList::AddDiff(DIFFRANGE di) { - m_diffs.Add(di); + DiffRangeInfo dri(di); + m_diffs.Add(dri); } /** - * @brief Returns copy of DIFFITEM from diff-list. + * @brief Returns copy of DIFFRANGE from diff-list. * @param [in] nDiff Index of DIFFITEM to return. * @param [out] di DIFFITEM returned (empty if error) * @return TRUE if DIFFITEM found from given index. */ BOOL DiffList::GetDiff(int nDiff, DIFFRANGE &di) const { - ASSERT(nDiff < m_diffs.GetSize()); - DIFFRANGE diff = {0}; - if (nDiff >= 0 && nDiff < m_diffs.GetSize()) + const DIFFRANGE * dfi = DiffRangeAt(nDiff); + if (!dfi) { - di = m_diffs[nDiff]; - return TRUE; + DIFFRANGE empty; + di = empty; + return FALSE; + } + di = *dfi; + return TRUE; +} + +/** + * @brief Return (const) pointer to DIFFRANGE entry requested + */ +const DIFFRANGE * DiffList::DiffRangeAt(int nDiff) const +{ + if (nDiff>=0 && nDiff < m_diffs.GetSize()) + { + return &m_diffs[nDiff].diffrange; } else { - di = diff; - return FALSE; + ASSERT(0); + return NULL; } } @@ -114,10 +132,10 @@ BOOL DiffList::SetDiff(int nDiff, DIFFRANGE di) */ int DiffList::LineRelDiff(UINT nLine, UINT nDiff) const { - ASSERT((int)nDiff < m_diffs.GetSize()); - if (nLine < m_diffs[nDiff].dbegin0) + const DIFFRANGE * dfi = DiffRangeAt(nDiff); + if (nLine < dfi->dbegin0) return -1; - else if (nLine > m_diffs[nDiff].dend0) + else if (nLine > dfi->dend0) return 1; else return 0; @@ -130,9 +148,8 @@ int DiffList::LineRelDiff(UINT nLine, UINT nDiff) const */ BOOL DiffList::LineInDiff(UINT nLine, UINT nDiff) const { - ASSERT((int)nDiff < m_diffs.GetSize()); - if (nLine >= m_diffs[nDiff].dbegin0 && - nLine <= m_diffs[nDiff].dend0) + const DIFFRANGE * dfi = DiffRangeAt(nDiff); + if (nLine >= dfi->dbegin0 && nLine <= dfi->dend0) return TRUE; else return FALSE; @@ -150,9 +167,9 @@ int DiffList::LineToDiff(UINT nLine) const return -1; // First check line is not before first or after last diff - if (nLine < m_diffs[0].dbegin0) + if (nLine < DiffRangeAt(0)->dbegin0) return -1; - if (nLine > m_diffs[nDiffCount-1].dend0) + if (nLine > DiffRangeAt(nDiffCount-1)->dend0) return -1; // Use binary search to search for a diff. @@ -201,7 +218,7 @@ BOOL DiffList::GetPrevDiff(int nLine, int &nDiff) const bInDiff = FALSE; for (int i = m_diffs.GetSize() - 1; i >= 0 ; i--) { - if ((int)m_diffs[i].dend0 <= nLine) + if ((int)DiffRangeAt(i)->dend0 <= nLine) { numDiff = i; break; @@ -230,7 +247,7 @@ BOOL DiffList::GetNextDiff(int nLine, int &nDiff) const const int nDiffCount = m_diffs.GetSize(); for (int i = 0; i < nDiffCount; i++) { - if ((int)m_diffs[i].dbegin0 >= nLine) + if ((int)DiffRangeAt(i)->dbegin0 >= nLine) { numDiff = i; break; @@ -246,13 +263,14 @@ BOOL DiffList::GetNextDiff(int nLine, int &nDiff) const * @param [in] nLine First line searched. * @return Index for next difference. */ -int DiffList::PrevDiffFromLine(UINT nLine) const +int DiffList::PrevSignificantDiffFromLine(UINT nLine) const { int nDiff = -1; for (int i = m_diffs.GetSize() - 1; i >= 0 ; i--) { - if (m_diffs[i].dend0 <= nLine) + const DIFFRANGE * dfi = DiffRangeAt(i); + if (dfi->op != OP_TRIVIAL && dfi->dend0 <= nLine) { nDiff = i; break; @@ -266,14 +284,15 @@ int DiffList::PrevDiffFromLine(UINT nLine) const * @param [in] nLine First line searched. * @return Index for previous difference. */ -int DiffList::NextDiffFromLine(UINT nLine) const +int DiffList::NextSignificantDiffFromLine(UINT nLine) const { int nDiff = -1; const int nDiffCount = m_diffs.GetSize(); for (int i = 0; i < nDiffCount; i++) { - if (m_diffs[i].dbegin0 >= nLine) + const DIFFRANGE * dfi = DiffRangeAt(i); + if (dfi->op != OP_TRIVIAL && dfi->dbegin0 >= nLine) { nDiff = i; break; @@ -281,3 +300,60 @@ int DiffList::NextDiffFromLine(UINT nLine) const } return nDiff; } + +/** + * @brief Construct the doubly-linked chain of significant differences + */ +void DiffList::ConstructSignificantChain() +{ + m_firstSignificant = -1; + m_lastSignificant = -1; + int prev = -1; + // must be called after diff list is entirely populated + for (int i = 0; i < m_diffs.GetSize(); ++i) + { + if (m_diffs[i].diffrange.op == OP_TRIVIAL) + { + m_diffs[i].prev = -1; + m_diffs[i].next = -1; + } + else + { + m_diffs[i].prev = prev; + if (prev != -1) + m_diffs[prev].next = i; + prev = i; + if (m_firstSignificant == -1) + m_firstSignificant = i; + m_lastSignificant = i; + } + } +} + +int DiffList::NextSignificantDiff(int nDiff) const +{ + return m_diffs[nDiff].next; +} + +int DiffList::PrevSignificantDiff(int nDiff) const +{ + return m_diffs[nDiff].prev; +} + +/** + * @brief Return pointer to first significant diff range + */ +const DIFFRANGE * DiffList::FirstSignificantDiffRange() const +{ + if (m_firstSignificant == -1) return NULL; + return DiffRangeAt(m_firstSignificant); +} + +/** + * @brief Return pointer to last significant diff range + */ +const DIFFRANGE * DiffList::LastSignificantDiffRange() const +{ + if (m_lastSignificant == -1) return NULL; + return DiffRangeAt(m_lastSignificant); +} diff --git a/Src/DiffList.h b/Src/DiffList.h index 64926a67c..8181ad469 100644 --- a/Src/DiffList.h +++ b/Src/DiffList.h @@ -49,6 +49,23 @@ struct DIFFRANGE int blank0; /**< Number of blank lines in file1 */ int blank1; /**< Number of blank lines in file2 */ BYTE op; /**< Operation done with this diff */ + DIFFRANGE() { memset(this, 0, sizeof(*this)); } +}; + +/** + * @brief DIFFRANGE with links for chain of non-trivial entries + * + * Next and prev are array indices used by the owner (DiffList) + */ +struct DiffRangeInfo +{ + DIFFRANGE diffrange; + int next; /**< link (array index) for doubly-linked chain of non-trivial DIFFRANGEs */ + int prev; /**< link (array index) for doubly-linked chain of non-trivial DIFFRANGEs */ + + DiffRangeInfo() { InitLinks(); } + DiffRangeInfo(const DIFFRANGE & di) : diffrange(di) { InitLinks(); } + void InitLinks() { next = prev = -1; } }; /** @@ -85,11 +102,21 @@ public: int LineToDiff(UINT nLine) const; BOOL GetPrevDiff(int nLine, int &nDiff) const; BOOL GetNextDiff(int nLine, int &nDiff) const; - int PrevDiffFromLine(UINT nLine) const; - int NextDiffFromLine(UINT nLine) const; + int PrevSignificantDiffFromLine(UINT nLine) const; + int NextSignificantDiffFromLine(UINT nLine) const; + int NextSignificantDiff(int nDiff) const; + int PrevSignificantDiff(int nDiff) const; + const DIFFRANGE * FirstSignificantDiffRange() const; + const DIFFRANGE * LastSignificantDiffRange() const; + + const DIFFRANGE * DiffRangeAt(int nDiff) const; + + void ConstructSignificantChain(); // must be called after diff list is entirely populated private: - CArray m_diffs; /**< Difference list */ + CArray m_diffs; /**< Difference list */ + int m_firstSignificant; /**< Index of first significant diff in m_diffs */ + int m_lastSignificant; /**< Index of last significant diff in m_diffs */ }; #endif // _DIFFLIST_H_ diff --git a/Src/DiffWrapper.cpp b/Src/DiffWrapper.cpp index faab43faa..414a77a48 100644 --- a/Src/DiffWrapper.cpp +++ b/Src/DiffWrapper.cpp @@ -624,7 +624,7 @@ void CDiffWrapper::SwapToGlobalSettings() void CDiffWrapper::AddDiffRange(UINT begin0, UINT end0, UINT begin1, UINT end1, BYTE op) { TRY { - DIFFRANGE dr = {0}; + DIFFRANGE dr; dr.begin0 = begin0; dr.end0 = end0; dr.begin1 = begin1; @@ -648,7 +648,7 @@ void CDiffWrapper::AddDiffRange(UINT begin0, UINT end0, UINT begin1, UINT end1, */ void CDiffWrapper::FixLastDiffRange(int leftBufferLines, int rightBufferLines, BOOL left) { - DIFFRANGE dr = {0}; + DIFFRANGE dr; const int count = m_pDiffList->GetSize(); if (count > 0) { diff --git a/Src/LocationView.cpp b/Src/LocationView.cpp index 486d5008c..43a10c903 100644 --- a/Src/LocationView.cpp +++ b/Src/LocationView.cpp @@ -60,7 +60,12 @@ CLocationView::CLocationView() , m_view1(0) , m_visibleTop(-1) , m_visibleBottom(-1) +// MOVEDLINE_LIST m_movedLines; //*< List of moved block connecting lines */ + , m_bIgnoreTrivials(true) { + // NB: set m_bIgnoreTrivials to false to see trivial diffs in the LocationView + // There is no GUI to do this + SetConnectMovedBlocks(mf->m_options.GetInt(OPT_CONNECT_MOVED_BLOCKS)); } @@ -167,6 +172,9 @@ void CLocationView::OnDraw(CDC* pDC) DrawVisibleAreaRect(); m_movedLines.RemoveAll(); + // Adjust line coloring if ignoring trivials + DWORD ignoreFlags = (m_bIgnoreTrivials ? LF_TRIVIAL : 0); + while (true) { // here nstart0 = last line before block @@ -184,12 +192,12 @@ void CLocationView::OnDraw(CDC* pDC) BOOL bInsideDiff = ((CMergeEditView*)m_view0)->IsLineInCurrentDiff(nstart0); // Draw left side block - m_view0->GetLineColors(nstart0, cr0, crt, bwh); + m_view0->GetLineColors2(nstart0, ignoreFlags, cr0, crt, bwh); CRect r0(m_nLeftBarLeft, nBeginY, m_nLeftBarRight, nEndY); DrawRect(pDC, r0, cr0, bInsideDiff); // Draw right side block - m_view1->GetLineColors(nstart0, cr1, crt, bwh); + m_view1->GetLineColors2(nstart0, ignoreFlags, cr1, crt, bwh); CRect r1(m_nRightBarLeft, nBeginY, m_nRightBarRight, nEndY); DrawRect(pDC, r1, cr1, bInsideDiff); @@ -286,44 +294,47 @@ void CLocationView::OnDraw(CDC* pDC) BOOL CLocationView::GetNextRect(int &nLineIndex) { CMergeDoc *pDoc = GetDocument(); - BOOL bInDiff = FALSE; - int nextDiff = -1; const int nbLines = min(m_view0->GetLineCount(), m_view1->GetLineCount()); - - ++nLineIndex; - if (nLineIndex >= nbLines) - return FALSE; - bInDiff = pDoc->m_diffList.GetNextDiff(nLineIndex, nextDiff); - - // No diffs left, return last line of file. - if (nextDiff == -1) + while(1) { - nLineIndex = nbLines - 1; - return TRUE; - } - DIFFRANGE di = {0}; - if (!pDoc->m_diffList.GetDiff(nextDiff, di)) - return FALSE; + ++nLineIndex; + if (nLineIndex >= nbLines) + return FALSE; - // Line not in diff. Return last non-diff line. - if (bInDiff == FALSE) - { - nLineIndex = di.dbegin0 - 1; - return TRUE; - } + int nextDiff = -1; + BOOL bInDiff = pDoc->m_diffList.GetNextDiff(nLineIndex, nextDiff); + + // No diffs left, return last line of file. + if (nextDiff == -1) + { + nLineIndex = nbLines - 1; + return TRUE; + } - // Line is in diff. Get last line from side where all lines are present. - if (di.op == OP_LEFTONLY || di.op == OP_RIGHTONLY || di.op == OP_DIFF) - { - if (di.blank0 == -1) - nLineIndex = di.dend1; - else - nLineIndex = di.dend0; - } + const DIFFRANGE * dfi = pDoc->m_diffList.DiffRangeAt(nextDiff); + if (!dfi) + return FALSE; - return TRUE; + bool ignoreDiff = (m_bIgnoreTrivials && dfi->op == OP_TRIVIAL); + + if (!ignoreDiff && !bInDiff) + { + // Line not in diff. Return last non-diff line. + nLineIndex = dfi->dbegin0 - 1; + return TRUE; + } + + // find end of diff + int nLineEndDiff = (dfi->blank0 == -1) ? dfi->dend1 : dfi->dend0; + + nLineIndex = nLineEndDiff; + + if (!ignoreDiff) + return TRUE; + // Fall through loop & look for next diff (we ignored this one) + } } /** diff --git a/Src/LocationView.h b/Src/LocationView.h index 7df6bc677..524a68cca 100644 --- a/Src/LocationView.h +++ b/Src/LocationView.h @@ -77,6 +77,7 @@ private: int m_visibleTop; //*< Top visible line for visible area indicator */ int m_visibleBottom; //*< Bottom visible line for visible area indicator */ MOVEDLINE_LIST m_movedLines; //*< List of moved block connecting lines */ + bool m_bIgnoreTrivials; //*< Whether to paint trivial blocks */ // Generated message map functions protected: diff --git a/Src/MergeDiffDetailView.cpp b/Src/MergeDiffDetailView.cpp index 74aa00977..22430d297 100644 --- a/Src/MergeDiffDetailView.cpp +++ b/Src/MergeDiffDetailView.cpp @@ -225,8 +225,18 @@ COLORREF CMergeDiffDetailView::GetColor(int nColorIndex) void CMergeDiffDetailView::GetLineColors(int nLineIndex, COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace) { + DWORD ignoreFlags = 0; + GetLineColors2(nLineIndex, ignoreFlags, crBkgnd, crText, bDrawWhitespace); +} +/// virtual, avoid coloring the whole diff with diff color +void CMergeDiffDetailView::GetLineColors2(int nLineIndex, DWORD ignoreFlags, + COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace) +{ DWORD dwLineFlags = GetLineFlags(nLineIndex); - + + if (dwLineFlags & ignoreFlags) + dwLineFlags &= (~ignoreFlags); + // Line with WinMerge flag, // Lines with only the LF_DIFF/LF_TRIVIAL flags are not colored with Winmerge colors if (dwLineFlags & (LF_WINMERGE_FLAGS & ~LF_DIFF & ~LF_TRIVIAL & ~LF_MOVED)) @@ -273,7 +283,7 @@ void CMergeDiffDetailView::OnDisplayDiff(int nDiff /*=0*/) } else { - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; VERIFY(pd->m_diffList.GetDiff(nDiff, curDiff)); newlineBegin = curDiff.dbegin0; diff --git a/Src/MergeDiffDetailView.h b/Src/MergeDiffDetailView.h index 020a03d9d..137c5cc99 100644 --- a/Src/MergeDiffDetailView.h +++ b/Src/MergeDiffDetailView.h @@ -111,6 +111,8 @@ protected: virtual COLORREF GetColor(int nColorIndex); virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace); + virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags, COLORREF & crBkgnd, + COLORREF & crText, BOOL & bDrawWhitespace); virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, BOOL bHorz); // Generated message map functions diff --git a/Src/MergeDoc.cpp b/Src/MergeDoc.cpp index ac22ee6ce..884efd2de 100644 --- a/Src/MergeDoc.cpp +++ b/Src/MergeDoc.cpp @@ -758,7 +758,7 @@ void CMergeDoc::ListCopy(bool bSrcLeft, bool bCurrentLeft, int curDiff = GetCurrentDiff(); if (curDiff!=-1) { - DIFFRANGE cd = {0}; + DIFFRANGE cd; VERIFY(m_diffList.GetDiff(curDiff, cd)); CDiffTextBuffer& sbuf = bSrcLeft? m_ltBuf:m_rtBuf; CDiffTextBuffer& dbuf = bSrcLeft? m_rtBuf:m_ltBuf; @@ -2065,7 +2065,7 @@ void CMergeDoc::PrimeTextBuffers() UINT RightExtras=0; // extra lines added to right view for (nDiff = 0; nDiff < nDiffCount; ++ nDiff) { - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; VERIFY(m_diffList.GetDiff(nDiff, curDiff)); // this guarantees that all the diffs are synchronized @@ -2094,7 +2094,7 @@ void CMergeDoc::PrimeTextBuffers() // add ghost lines, and set flags for (nDiff = nDiffCount - 1; nDiff >= 0; nDiff --) { - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; VERIFY(m_diffList.GetDiff(nDiff, curDiff)); // move matched lines after curDiff @@ -2252,36 +2252,13 @@ void CMergeDoc::PrimeTextBuffers() VERIFY(m_diffList.SetDiff(nDiff, curDiff)); } // for (nDiff = nDiffCount; nDiff-- > 0; ) - if (m_nTrivialDiffs) - { - // The following code deletes all trivial changes - // - // #1) Copy nontrivial diffs into new array - CArray newdiffs; - newdiffs.SetSize(nDiffCount - m_nTrivialDiffs); - UINT i,j; - for (i=0,j=0; j < nDiffCount; ++j) - { - // j is index into difflist - // i is index into newdiffs - // i grows more slowly than j, as i skips trivials + m_diffList.ConstructSignificantChain(); + + // Used to strip trivial diffs out of the diff chain + // if m_nTrivialDiffs + // via copying them all to a new chain, then copying only non-trivials back + // but now we keep all diffs, including trivial diffs - DIFFRANGE curDiff = {0}; - VERIFY(m_diffList.GetDiff(j, curDiff)); - if (curDiff.op != OP_TRIVIAL) - { - newdiffs[i] = curDiff; - ++i; - } - } - // #2) Now copy from new array back into master array - m_diffList.SetSize(newdiffs.GetSize()); - nDiffCount = m_diffList.GetSize(); - for (i=0; i < nDiffCount; ++i) - { - VERIFY(m_diffList.SetDiff(i, newdiffs[i])); - } - } m_ltBuf.FinishLoading(); m_rtBuf.FinishLoading(); diff --git a/Src/MergeEditView.cpp b/Src/MergeEditView.cpp index 1618f9898..f95e56ed2 100644 --- a/Src/MergeEditView.cpp +++ b/Src/MergeEditView.cpp @@ -278,7 +278,7 @@ void CMergeEditView::GetFullySelectedDiffs(int & firstDiff, int & lastDiff) for (UINT i = 0; i < nDiffs; i++) { - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; VERIFY(pd->m_diffList.GetDiff(i, curDiff)); if ((int)curDiff.dbegin0 >= firstLine) { @@ -292,7 +292,7 @@ void CMergeEditView::GetFullySelectedDiffs(int & firstDiff, int & lastDiff) lastDiff = nDiffs - 1; for (i = firstDiff; i < nDiffs; i++) { - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; VERIFY(pd->m_diffList.GetDiff(i, curDiff)); if ((int)curDiff.dend0 > lastLine) { @@ -402,8 +402,27 @@ COLORREF CMergeEditView::GetColor(int nColorIndex) void CMergeEditView::GetLineColors(int nLineIndex, COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace) { + DWORD ignoreFlags = 0; + GetLineColors2(nLineIndex, ignoreFlags, crBkgnd, crText, bDrawWhitespace); +} + +/** + * @brief Determine text and background color for line + * @param [in] nLineIndex Index of line in view (NOT line in file) + * @param [in] ignoreFlags Flags that caller wishes ignored + * @param [out] crBkgnd Backround color for line + * @param [out] crText Text color for line + * + * This version allows caller to suppress particular flags + */ +void CMergeEditView::GetLineColors2(int nLineIndex, DWORD ignoreFlags, COLORREF & crBkgnd, + COLORREF & crText, BOOL & bDrawWhitespace) +{ DWORD dwLineFlags = GetLineFlags(nLineIndex); + if (dwLineFlags & ignoreFlags) + dwLineFlags &= (~ignoreFlags); + // Line inside diff if (dwLineFlags & LF_WINMERGE_FLAGS) { @@ -863,12 +882,17 @@ void CMergeEditView::OnNextdiff() int curDiff = pd->GetCurrentDiff(); if (curDiff != -1) { - if (curDiff == pd->m_diffList.GetSize() - 1) - // We're on a last diff, so select that - SelectDiff(curDiff, TRUE, FALSE); - else - // We're on a diff, so select the next one - SelectDiff(curDiff + 1, TRUE, FALSE); + // We're on a diff + // Find out if there is a following significant diff + int nextDiff = curDiff; + if (curDiff < pd->m_diffList.GetSize() - 1) + { + nextDiff = pd->m_diffList.NextSignificantDiff(curDiff); + if (nextDiff == -1) + nextDiff = curDiff; + } + // nextDiff is the next one if there is one, else it is the one we're on + SelectDiff(nextDiff, TRUE, FALSE); } else { @@ -876,7 +900,7 @@ void CMergeEditView::OnNextdiff() int line = GetCursorPos().y; if (!IsValidTextPosY(CPoint(0, line))) line = m_nTopLine; - curDiff = pd->m_diffList.NextDiffFromLine(line); + curDiff = pd->m_diffList.NextSignificantDiffFromLine(line); if (curDiff >= 0) SelectDiff(curDiff, TRUE, FALSE); } @@ -888,14 +912,18 @@ void CMergeEditView::OnNextdiff() void CMergeEditView::OnUpdateNextdiff(CCmdUI* pCmdUI) { CMergeDoc *pd = GetDocument(); - if (pd->m_diffList.GetSize() == 0) + const DIFFRANGE * dfi = pd->m_diffList.LastSignificantDiffRange(); + + if (!dfi) + { + // There aren't any significant differences pCmdUI->Enable(FALSE); + } else { + // Enable if the beginning of the last significant difference is after caret CPoint pos = GetCursorPos(); - DIFFRANGE diff; - pd->m_diffList.GetDiff(pd->m_diffList.GetSize() - 1, diff); - pCmdUI->Enable(pos.y < (long)diff.dbegin0); + pCmdUI->Enable(pos.y < (long)dfi->dbegin0); } } @@ -919,12 +947,17 @@ void CMergeEditView::OnPrevdiff() if (curDiff != -1) { - if (curDiff == 0) - // We're on a first diff, select it - SelectDiff(curDiff, TRUE, FALSE); - else - // We're on a diff, so select the previous one - SelectDiff(curDiff - 1, TRUE, FALSE); + // We're on a diff + // Find out if there is a preceding significant diff + int prevDiff = curDiff; + if (curDiff > 0) + { + prevDiff = pd->m_diffList.PrevSignificantDiff(curDiff); + if (prevDiff == -1) + prevDiff = curDiff; + } + // prevDiff is the preceding one if there is one, else it is the one we're on + SelectDiff(prevDiff, TRUE, FALSE); } else { @@ -932,7 +965,7 @@ void CMergeEditView::OnPrevdiff() int line = GetCursorPos().y; if (!IsValidTextPosY(CPoint(0, line))) line = m_nTopLine; - curDiff = pd->m_diffList.PrevDiffFromLine(line); + curDiff = pd->m_diffList.PrevSignificantDiffFromLine(line); if (curDiff >= 0) SelectDiff(curDiff, TRUE, FALSE); } @@ -944,14 +977,18 @@ void CMergeEditView::OnPrevdiff() void CMergeEditView::OnUpdatePrevdiff(CCmdUI* pCmdUI) { CMergeDoc *pd = GetDocument(); - if (pd->m_diffList.GetSize() == 0) + const DIFFRANGE * dfi = pd->m_diffList.FirstSignificantDiffRange(); + + if (!dfi) + { + // There aren't any significant differences pCmdUI->Enable(FALSE); + } else { + // Enable if the end of the first significant difference is before caret CPoint pos = GetCursorPos(); - DIFFRANGE diff; - pd->m_diffList.GetDiff(0, diff); - pCmdUI->Enable(pos.y > (long)diff.dend0); + pCmdUI->Enable(pos.y > (long)dfi->dend0); } } @@ -1346,7 +1383,7 @@ void CMergeEditView::ShowDiff(BOOL bScroll, BOOL bSelectText) if (nDiff >= 0 && nDiff < pd->m_diffList.GetSize()) { CPoint ptStart, ptEnd; - DIFFRANGE curDiff = {0}; + DIFFRANGE curDiff; pd->m_diffList.GetDiff(nDiff, curDiff); ptStart.x = 0; diff --git a/Src/MergeEditView.h b/Src/MergeEditView.h index 83effccd5..ebd9a1333 100644 --- a/Src/MergeEditView.h +++ b/Src/MergeEditView.h @@ -174,6 +174,8 @@ public: virtual COLORREF GetColor(int nColorIndex); virtual void GetLineColors (int nLineIndex, COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace); + virtual void GetLineColors2 (int nLineIndex, DWORD ignoreFlags + , COLORREF & crBkgnd, COLORREF & crText, BOOL & bDrawWhitespace); void WMGoto() { OnWMGoto(); }; void GotoLine(UINT nLine, BOOL bRealLine, BOOL bLeft); int GetTopLine() { return m_nTopLine; }; diff --git a/Src/readme.txt b/Src/readme.txt index 5c8f83177..c047c00ab 100644 --- a/Src/readme.txt +++ b/Src/readme.txt @@ -1,3 +1,9 @@ +2005-08-07 Perry + PATCH: [ 1248259 ] Preserve trivial diffs in diff chain + Src: DiffList.cpp DiffList.h DiffWrapper.cpp LocationView.cpp + LocationView.h MergeDiffDetailView.cpp MergeDiffDetailView.h + MergeDoc.cpp MergeEditView.cpp MergeEditView.h + 2005-08-07 Kimmo PATCH: [ 1253100 ] Shorter paths in captions Src: DirDoc.cpp MergeDoc.cpp paths.cpp paths.h -- 2.11.0