From 1991c16548325ce41d247dc8d016b32a2ebf1e2c Mon Sep 17 00:00:00 2001 From: Perry Rapp Date: Sun, 23 Mar 2003 20:30:52 +0000 Subject: [PATCH] PATCH: [ 706006 ] Suppress Rescan during Merge --- Src/Merge.cpp | 42 ++++++++++++++++++++++++++++++---- Src/Merge.h | 27 ++++++++++++++-------- Src/MergeDoc.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ Src/MergeDoc.h | 10 ++++++++ Src/MergeEditView.cpp | 20 +++++++++++++--- Src/readme.txt | 4 ++++ 6 files changed, 150 insertions(+), 16 deletions(-) diff --git a/Src/Merge.cpp b/Src/Merge.cpp index 98d5e90a6..39a883a01 100644 --- a/Src/Merge.cpp +++ b/Src/Merge.cpp @@ -71,11 +71,18 @@ static void AddEnglishResourceHook(); // CMergeApp construction CMergeApp::CMergeApp() -: m_lang(IDR_MAINFRAME, IDR_MAINFRAME), m_clrDiff(RGB(255,255,92)), m_clrSelDiff(RGB(255,0,92)) +: m_bHiliteSyntax(TRUE) +, m_bDisableSplash(FALSE) +, m_clrDiff(RGB(255,255,92)) +, m_clrSelDiff(RGB(255,0,92)) +, m_bNeedIdleTimer(FALSE) +, m_pDiffTemplate(0) +, m_pDirTemplate(0) +, m_lang(IDR_MAINFRAME, IDR_MAINFRAME) +, m_bEscCloses(FALSE) { // TODO: add construction code here, // Place all significant initialization in InitInstance - m_bEscCloses = FALSE; } ///////////////////////////////////////////////////////////////////////////// @@ -532,13 +539,13 @@ void SillyTestCrap() #endif -void CMergeApp::SetDiffColor( COLORREF clrValue ) +void CMergeApp::SetDiffColor(COLORREF clrValue) { m_clrDiff = clrValue; } -void CMergeApp::SetSelDiffColor( COLORREF clrValue ) +void CMergeApp::SetSelDiffColor(COLORREF clrValue) { m_clrSelDiff = clrValue; } @@ -581,3 +588,30 @@ static void AddEnglishResourceHook() new CDynLinkLibrary(FakeEnglishDLL); // hook into MFC extension DLL chain } + +int CMergeApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) +{ + // This is just a convenient point for breakpointing + return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt); +} + +// Set flag so that application will broadcast notification at next +// idle time (via WM_TIMER id=IDLE_TIMER) +void CMergeApp::SetNeedIdleTimer() +{ + m_bNeedIdleTimer = TRUE; +} + +BOOL CMergeApp::OnIdle(LONG lCount) +{ + if (CWinApp::OnIdle(lCount)) + return TRUE; + + // If anyone has requested notification when next idle occurs, send it + if (m_bNeedIdleTimer) + { + m_bNeedIdleTimer = FALSE; + m_pMainWnd->SendMessageToDescendants(WM_TIMER, IDLE_TIMER, lCount, TRUE, FALSE); + } + return FALSE; +} diff --git a/Src/Merge.h b/Src/Merge.h index 0185d0f9a..68c9454f1 100644 --- a/Src/Merge.h +++ b/Src/Merge.h @@ -40,6 +40,8 @@ // See Merge.cpp for the implementation of this class // +enum { IDLE_TIMER = 9754 }; + class CMergeApp : public CWinApp { public: @@ -47,25 +49,32 @@ public: BOOL m_bDisableSplash; COLORREF m_clrDiff; // The difference color COLORREF m_clrSelDiff; // The selected difference color - - virtual BOOL PreTranslateMessage(MSG* pMsg); - CLanguageSelect m_lang; - CMergeApp(); + BOOL m_bNeedIdleTimer; CMultiDocTemplate* m_pDiffTemplate; CMultiDocTemplate* m_pDirTemplate; - COLORREF GetDiffColor ( void ) const { return m_clrDiff; } - COLORREF GetSelDiffColor ( void ) const { return m_clrSelDiff; } - void SetDiffColor ( COLORREF clrValue ); - void SetSelDiffColor ( COLORREF clrValue ); + CLanguageSelect m_lang; + + CMergeApp(); + COLORREF GetDiffColor() const { return m_clrDiff; } + COLORREF GetSelDiffColor() const { return m_clrSelDiff; } + void SetDiffColor(COLORREF clrValue) ; + void SetSelDiffColor(COLORREF clrValue); + void SetNeedIdleTimer(); + +// Implementation +protected: + // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMergeApp) public: virtual BOOL InitInstance(); virtual int ExitInstance(); + virtual int DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt); + virtual BOOL OnIdle(LONG lCount); //}}AFX_VIRTUAL -// Implementation + virtual BOOL PreTranslateMessage(MSG* pMsg); //{{AFX_MSG(CMergeApp) afx_msg void OnAppAbout(); diff --git a/Src/MergeDoc.cpp b/Src/MergeDoc.cpp index 199b9a681..da224e5b1 100644 --- a/Src/MergeDoc.cpp +++ b/Src/MergeDoc.cpp @@ -69,6 +69,9 @@ CMergeDoc::CMergeDoc() : m_ltBuf(this,TRUE), m_rtBuf(this,FALSE) m_nCurDiff=-1; m_strTempLeftFile=_T(""); m_strTempRightFile=_T(""); + m_bEnableRescan = TRUE; + m_bNeedIdleRescan = FALSE; + // COleDateTime m_LastRescan curUndo = undoTgt.begin(); } #pragma warning(default:4355) @@ -214,6 +217,10 @@ static void PrepareBufferForRescan(CMergeDoc::CDiffTextBuffer * buf, DWORD delet BOOL CMergeDoc::Rescan() { + if (!m_bEnableRescan) return TRUE; // What return value ? + m_bNeedIdleRescan = FALSE; + m_LastRescan = COleDateTime::GetCurrentTime(); + // store modified status BOOL ltMod = m_ltBuf.IsModified(); BOOL rtMod = m_rtBuf.IsModified(); @@ -550,9 +557,42 @@ BOOL CMergeDoc::Undo() return FALSE; } +// An instance of RescanSuppress prevents rescan during its lifetime +// (or until its Clear method is called, which ends its effect). +class RescanSuppress +{ +public: + RescanSuppress(CMergeDoc & doc) : m_doc(doc) + { + m_bSuppress = TRUE; + m_bPrev = doc.m_bEnableRescan; + doc.m_bEnableRescan = FALSE; + } + void Clear() + { + if (m_bSuppress) + { + m_bSuppress = FALSE; + m_doc.m_bEnableRescan = m_bPrev; + } + } + ~RescanSuppress() + { + Clear(); + } +private: + CMergeDoc & m_doc; + BOOL m_bPrev; + BOOL m_bSuppress; +}; void CMergeDoc::ListCopy(bool bSrcLeft) { + // suppress Rescan during this method + // (Not only do we not want to rescan a lot of times, but + // it will wreck the line status array to rescan as we merge) + RescanSuppress suppressRescan(*this); + // make sure we're on a diff int curDiff = GetCurrentDiff(); if (curDiff!=-1) @@ -666,6 +706,8 @@ void CMergeDoc::ListCopy(bool bSrcLeft) } // what does this do? // pDestList->AddMod(); + suppressRescan.Clear(); // done suppress Rescan + FlushAndRescan(); } // Return false when saving fails, so we can ask again @@ -1129,6 +1171,8 @@ BOOL CMergeDoc::TempFilesExist() void CMergeDoc::FlushAndRescan() { + if (!m_bEnableRescan) return; + CMDIFrameWnd* mainWnd = dynamic_cast(AfxGetMainWnd()); CMDIChildWnd* diffWnd = dynamic_cast(mainWnd->MDIGetActive()); CCrystalEditView* curView = dynamic_cast(diffWnd->GetActiveView()); @@ -1403,3 +1447,22 @@ BOOL CMergeDoc::SaveHelper() return result; } +// View requests we rescan when convenient +void CMergeDoc::SetNeedRescan() +{ + m_bNeedIdleRescan = TRUE; +} + +void CMergeDoc::RescanIfNeeded() +{ + // Rescan if we were asked for a rescan when convenient + // AND if we've not rescanned in at least a second + if (m_bNeedIdleRescan) + { + m_bNeedIdleRescan = FALSE; + COleDateTimeSpan elapsed = COleDateTime::GetCurrentTime() - m_LastRescan; + if (elapsed.GetTotalSeconds() > 1) + FlushAndRescan(); + } +} + diff --git a/Src/MergeDoc.h b/Src/MergeDoc.h index a2d05e4a9..5fb6acaef 100644 --- a/Src/MergeDoc.h +++ b/Src/MergeDoc.h @@ -113,6 +113,10 @@ public : }; +// End declaration of CMergeDoc::CDiffTextBuffer + +// Begin declaration of CMergeDoc + CDiffTextBuffer m_ltBuf; CDiffTextBuffer m_rtBuf; @@ -130,6 +134,8 @@ public: int m_nCurDiff; CString m_strLeftFile, m_strRightFile; + void SetNeedRescan(); + void RescanIfNeeded(); BOOL Rescan(); void AddDiffRange(UINT begin0, UINT end0, UINT begin1, UINT end1, BYTE op); void AddUndoAction(UINT nBegin, UINT nEnd, UINT nDiff, int nBlanks, BOOL bInsert, CMergeEditView *pList); @@ -177,6 +183,10 @@ protected: protected: CString m_strTempRightFile; CString m_strTempLeftFile; + BOOL m_bEnableRescan; + BOOL m_bNeedIdleRescan; + COleDateTime m_LastRescan; + friend class RescanSuppress; //{{AFX_MSG(CMergeDoc) afx_msg void OnFileSave(); afx_msg void OnUpdateStatusNum(CCmdUI* pCmdUI); diff --git a/Src/MergeEditView.cpp b/Src/MergeEditView.cpp index 4ac7482f8..0f0923755 100644 --- a/Src/MergeEditView.cpp +++ b/Src/MergeEditView.cpp @@ -331,7 +331,6 @@ void CMergeEditView::OnUpdateEditCopy(CCmdUI* pCmdUI) void CMergeEditView::OnEditCut() { CCrystalEditViewEx::Cut(); - GetDocument()->FlushAndRescan(); m_pTextBuffer->SetModified(TRUE); } @@ -343,7 +342,6 @@ void CMergeEditView::OnUpdateEditCut(CCmdUI* pCmdUI) void CMergeEditView::OnEditPaste() { CCrystalEditViewEx::Paste(); - GetDocument()->FlushAndRescan(); m_pTextBuffer->SetModified(TRUE); } @@ -720,8 +718,24 @@ void CMergeEditView::ShowDiff(BOOL bScroll, BOOL bSelectText) void CMergeEditView::OnTimer(UINT nIDEvent) { + // We get two kinds of timers + // IDT_RESCAN means it has been a while since the user last made a change + // so we'd like to do a rescan as soon as feasible + // IDLE_TIMER means the application is idling, so now it is feasible to rescan + // If we get the idle timer, we pass the buck to the document (ie, it may + // still skip the rescan if it just did one recently). + if (nIDEvent == IDT_RESCAN) - GetDocument()->FlushAndRescan(); + { + KillTimer(IDT_RESCAN); + GetDocument()->SetNeedRescan(); + theApp.SetNeedIdleTimer(); + } + else if (nIDEvent == IDLE_TIMER) + { + GetDocument()->RescanIfNeeded(); + } CWnd::OnTimer(nIDEvent); } + diff --git a/Src/readme.txt b/Src/readme.txt index a964192c2..0a862bfeb 100644 --- a/Src/readme.txt +++ b/Src/readme.txt @@ -1,3 +1,7 @@ +2003-03-23 Perry + PATCH: [ 706006 ] Suppress Rescan during Merge + Merge.cpp Merge.h MergeDoc.cpp MergeDoc.h MergeEditView.cpp + 2003-03-23 Kimmo PATCH: [ 707753 ] Delayed rescan - fix WinMerge: MergeEditView.cpp -- 2.11.0