OSDN Git Service

[ 769535 ] Preserve cursor during Rescan
authorLaurent Ganier <laoran@users.sourceforge.net>
Thu, 17 Jul 2003 09:12:28 +0000 (09:12 +0000)
committerLaurent Ganier <laoran@users.sourceforge.net>
Thu, 17 Jul 2003 09:12:28 +0000 (09:12 +0000)
Src/MergeDoc.cpp
Src/editlib/ccrystaltextbuffer.cpp
Src/editlib/ccrystaltextbuffer.h
Src/editlib/ccrystaltextview.cpp
Src/editlib/ccrystaltextview.h
Src/readme.txt

index 9d9c726..57fca50 100644 (file)
@@ -1386,26 +1386,23 @@ void CMergeDoc::FlushAndRescan(BOOL bForced /* =FALSE */)
        CCrystalEditView* curView = dynamic_cast<CCrystalEditView*>(diffWnd->GetActiveView());
 
        int nRescanResult = RESCAN_OK;
-       if(curView)
-       {
-               curView->PushCursor();
-               nRescanResult = Rescan(bForced);
-               UpdateAllViews(NULL);
-               curView->PopCursor();
-               // Show possible error after updating screen
-               if (nRescanResult != RESCAN_OK &&
-                               nRescanResult != RESCAN_SUPPRESSED)
-                       ShowRescanError(nRescanResult);
-       }
-       else
-       {
-               nRescanResult = Rescan(bForced);
-               UpdateAllViews(NULL);
+
+       m_pLeftView->PushCursor();
+       m_pRightView->PushCursor();
+
+       nRescanResult = Rescan(bForced);
+       UpdateAllViews(NULL);
+
+       m_pLeftView->PopCursor();
+       m_pRightView->PopCursor();
+
+       if (curView)
+               curView->EnsureVisible(curView->GetCursorPos());
+
                // Show possible error after updating screen
                if (nRescanResult != RESCAN_OK &&
                                nRescanResult != RESCAN_SUPPRESSED)
                        ShowRescanError(nRescanResult);
-       }
 }
 
 void CMergeDoc::OnFileSave() 
index 1db2e16..16e263b 100644 (file)
@@ -1974,6 +1974,129 @@ int CCrystalTextBuffer::ComputeApparentLine(int nRealLine)
 }
 
 
+
+// return underlying real line and ghost adjustment as
+// nApparentLine = apparent(nRealLine) - nGhostAdjustment 
+// nRealLine for ghost lines is the NEXT HIGHER real line (for trailing ghost line, last real line + 1)
+// if nApparentLine is greater than the last valid apparent line, ASSERT
+// ie, lines 0->0, 1->2, 2->4,
+// for argument of 3, return 2, and decToReal = 1
+int CCrystalTextBuffer::ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal)
+{
+  int bmax = m_RealityBlocks.GetUpperBound();
+  // first get the degenerate cases out of the way
+  // empty file ?
+  if (bmax<0) 
+  {
+    decToReal = 0;
+    return 0;
+  }
+
+  // after last apparent line ?
+  ASSERT(nApparentLine < GetLineCount());
+
+  // after last block ?
+  RealityBlock & maxblock = m_RealityBlocks[bmax];
+  if (nApparentLine >= maxblock.nStartApparent + maxblock.nCount)
+  {
+    decToReal = GetLineCount() - nApparentLine;
+    return maxblock.nStartReal + maxblock.nCount;
+  }
+
+  // binary search to find correct (or nearest block)
+  int blo=0, bhi=bmax;
+  int i;
+  while (blo<=bhi)
+    {
+      i = (blo+bhi)/2;
+      RealityBlock & block = m_RealityBlocks[i];
+      if (nApparentLine < block.nStartApparent)
+        bhi = i-1;
+      else if (nApparentLine >= block.nStartApparent + block.nCount)
+        blo = i+1;
+      else // found it inside this block
+      {
+        decToReal = 0;
+        return (nApparentLine - block.nStartApparent) + block.nStartReal;
+      }
+    }
+  // it is a ghost line just before block blo
+  decToReal = m_RealityBlocks[blo].nStartApparent - nApparentLine;
+  return m_RealityBlocks[blo].nStartReal;
+}
+
+
+
+// return apparent line for this underlying real line, with adjustment
+// returns nApparent = apparent(nReal) - decToReal
+// if the previous real line has apparent number   apparent(nReal) - dec, with dec < decToReal,
+//   return apparent(nReal) - dec + 1
+int CCrystalTextBuffer::ComputeApparentLine(int nRealLine, int decToReal)
+{
+  int blo, bhi;
+  int nPreviousBlock;
+  int nApparent;
+  int bmax = m_RealityBlocks.GetUpperBound();
+  // first get the degenerate cases out of the way
+  // empty file ?
+  if (bmax<0)
+    return 0;
+  // after last block ?
+  RealityBlock & maxblock = m_RealityBlocks[bmax];
+  if (nRealLine >= maxblock.nStartReal + maxblock.nCount)
+  {
+    nPreviousBlock = bmax;
+    nApparent = GetLineCount();
+    goto limitWithPreviousBlock;
+  }
+
+  // binary search to find correct (or nearest block)
+  blo=0;
+  bhi=bmax;
+  int i;
+  while (blo<=bhi)
+    {
+      i = (blo+bhi)/2;
+      RealityBlock & block = m_RealityBlocks[i];
+      if (nRealLine < block.nStartReal)
+        bhi = i-1;
+      else if (nRealLine >= block.nStartReal + block.nCount)
+        blo = i+1;
+      else
+      {
+        if (nRealLine > block.nStartReal)
+          // limited by the previous line in this block
+          return (nRealLine - block.nStartReal) + block.nStartApparent;
+        nPreviousBlock = blo - 1;
+        nApparent = (nRealLine - block.nStartReal) + block.nStartApparent;
+        goto limitWithPreviousBlock;
+      }
+    }
+  // Should have found it; all real lines should be in a block
+  ASSERT(0);
+  return -1;
+
+limitWithPreviousBlock:
+  // we must keep above the value lastApparentInPreviousBlock
+  int lastApparentInPreviousBlock;
+  if (nPreviousBlock == -1)
+    lastApparentInPreviousBlock = -1;
+  else
+  {
+    RealityBlock & previousBlock = m_RealityBlocks[nPreviousBlock];
+    lastApparentInPreviousBlock = previousBlock.nStartApparent + previousBlock.nCount - 1;
+  }
+
+  while (decToReal --) 
+  {
+    nApparent --;
+    if (nApparent == lastApparentInPreviousBlock)
+      return nApparent+1;
+  }
+  return nApparent;
+}
+
+
 // Do what we need to do just after we've been reloaded
 void CCrystalTextBuffer::FinishLoading()
 {
@@ -2025,8 +2148,6 @@ inReality:
   ++reality;
   ++i;
   goto inReality;
-
-
 }
 
 
index c861883..ed8af64 100644 (file)
@@ -382,6 +382,9 @@ public:
     int ApparentLastRealLine() const;
     int ComputeRealLine(int nApparentLine);
     int ComputeApparentLine(int nRealLine);
+    // richer position information   yApparent = apparent(yReal) - yGhost
+    int ComputeRealLineAndGhostAdjustment(int nApparentLine, int& decToReal);
+    int ComputeApparentLine(int nRealLine, int decToReal);
 
 
     void RecomputeRealityMapping();
index 2097a7a..f513506 100644 (file)
@@ -3800,23 +3800,24 @@ HideCursor ()
 void CCrystalTextView::
 PopCursor ()
 {
-  if (IsValidTextPosY (m_ptCursorLast))
-    {
-      if (!IsValidTextPosX (m_ptCursorLast))
-        m_ptCursorLast.x = 0;
-      ASSERT_VALIDTEXTPOS (m_ptCursorLast);
-      CPoint ptCursorPos = m_ptCursorLast;
-      SetCursorPos (ptCursorPos);
-      SetSelection (ptCursorPos, ptCursorPos);
-      SetAnchor (ptCursorPos);
-      EnsureVisible (ptCursorPos);
-    }
+  CPoint ptCursorLast = m_ptCursorLast;
+  ptCursorLast.y = m_pTextBuffer->ComputeApparentLine(m_ptCursorLast.y, m_ptCursorLast_nGhost);
+  if (ptCursorLast.y >= GetLineCount())
+  {
+    ptCursorLast.y = GetLineCount()-1;
+    ptCursorLast.x = GetLineLength(ptCursorLast.y);
+  }
+  ASSERT_VALIDTEXTPOS (ptCursorLast);
+  SetCursorPos (ptCursorLast);
+  SetSelection (ptCursorLast, ptCursorLast);
+  SetAnchor (ptCursorLast);
 }
 
 void CCrystalTextView::
 PushCursor ()
 {
-  m_ptCursorLast = m_ptCursorPos;
+  m_ptCursorLast.x = m_ptCursorPos.x;
+  m_ptCursorLast.y = m_pTextBuffer->ComputeRealLineAndGhostAdjustment(m_ptCursorPos.y, m_ptCursorLast_nGhost);
 }
 
 DROPEFFECT CCrystalTextView::
index b5fc039..1343ba1 100644 (file)
@@ -135,6 +135,7 @@ private :
 
     CPoint m_ptDrawSelStart, m_ptDrawSelEnd;
     CPoint m_ptCursorPos, m_ptCursorLast;
+    int    m_ptCursorLast_nGhost;
     CPoint m_ptSelStart, m_ptSelEnd;
     void PrepareSelBounds ();
 
index e2c2b92..70954bb 100644 (file)
@@ -1,4 +1,9 @@
 2003-07-17 Laoran
+ PATCH : [ 769535 ] Preserve cursor during Rescan
+  WinMerge: MergeDoc.cpp 
+  editlib: ccrystaltextbuffer.cpp ccrystaltextbuffer.h ccrystaltextview.cpp ccrystaltextview.h
+
+2003-07-17 Laoran
  PATCH: [ 767878 ] Better handling of ghost flag and EOL
   WinMerge: MergeDoc.cpp MergeEditView.cpp
   editlib: ccrystaleditview.cpp ccrystaltextbuffer.cpp ccrystaltextbuffer.h