ccrystaltextbuffer.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 1,533 行 · 第 1/3 页

CPP
1,533
字号
#endif
    _tcscpy (szTempFileDir, drive);
    _tcscat (szTempFileDir, dir);
    _tcscpy (szBackupFileName, pszFileName);
    _tcscat (szBackupFileName, _T (".bak"));

    if (::GetTempFileName (szTempFileDir, _T ("CRE"), 0, szTempFileName) == 0)
      __leave;

      hTempFile =::CreateFile (szTempFileName, GENERIC_WRITE, 0, NULL,
                               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
      if (hTempFile == INVALID_HANDLE_VALUE)
        __leave;

        if (nCrlfStyle == CRLF_STYLE_AUTOMATIC)
          nCrlfStyle = m_nCRLFMode;

          ASSERT (nCrlfStyle >= 0 && nCrlfStyle <= 2);
          LPCTSTR pszCRLF = crlfs[nCrlfStyle];
          int nCRLFLength = _tcslen (pszCRLF);

          int nLineCount = m_aLines.GetSize ();
          for (int nLine = 0; nLine < nLineCount; nLine++)
            {
              int nLength = m_aLines[nLine]->m_nLength;
              DWORD dwWrittenBytes;
              if (nLength > 0)
                {
                  LPCTSTR pszLine = m_aLines[nLine]->m_pcLine;
                  if (m_nSourceEncoding >= 0)
                    {
                      LPTSTR pszBuf;
                      iconvert_new (m_aLines[nLine]->m_pcLine, &pszBuf, 1, m_nSourceEncoding, m_nSourceEncoding == 15);
                      if (!::WriteFile (hTempFile, pszBuf, nLength, &dwWrittenBytes, NULL))
                        {
                          free (pszBuf);
                          __leave;
                        }
                      free (pszBuf);
                    }
                  else
                    if (!::WriteFile (hTempFile, pszLine, nLength, &dwWrittenBytes, NULL))
                      __leave;
                  if (nLength != (int) dwWrittenBytes)
                    __leave;
                }
              if (nLine < nLineCount - 1)     //  Last line must not end with CRLF

                {
                  if (!::WriteFile (hTempFile, pszCRLF, nCRLFLength, &dwWrittenBytes, NULL))
                    __leave;
                  if (nCRLFLength != (int) dwWrittenBytes)
                    __leave;
                }
            }
    ::CloseHandle (hTempFile);
    hTempFile = INVALID_HANDLE_VALUE;

    if (m_bCreateBackupFile)
      {
        WIN32_FIND_DATA wfd;
        hSearch =::FindFirstFile (pszFileName, &wfd);
        if (hSearch != INVALID_HANDLE_VALUE)
          {
            //  File exist - create backup file
            ::DeleteFile (szBackupFileName);
            if (!::MoveFile (pszFileName, szBackupFileName))
              __leave;
            ::FindClose (hSearch);
            hSearch = INVALID_HANDLE_VALUE;
          }
      }
    else
      {
        ::DeleteFile (pszFileName);
      }

    //  Move temporary file to target name
    if (!::MoveFile (szTempFileName, pszFileName))
      __leave;

      if (bClearModifiedFlag)
        {
          SetModified (FALSE);
          m_nSyncPosition = m_nUndoPosition;
        }
    bSuccess = TRUE;
  }
  __finally
  {
    if (hSearch != INVALID_HANDLE_VALUE)
      ::FindClose (hSearch);
      if (hTempFile != INVALID_HANDLE_VALUE)
        ::CloseHandle (hTempFile);
        ::DeleteFile (szTempFileName);
      }
      return bSuccess;
}

int CCrystalTextBuffer::GetCRLFMode()
{
  return m_nCRLFMode;
}

void CCrystalTextBuffer::SetCRLFMode(int nCRLFMode)
{
  /*ASSERT (nCRLFMode == CRLF_STYLE_DOS ||
          nCRLFMode == CRLF_STYLE_UNIX ||
          nCRLFMode == CRLF_STYLE_MAC);*/
  if (nCRLFMode >= 0)
    {
      m_nCRLFMode = nCRLFMode;
    }
}

int CCrystalTextBuffer::GetLineCount()
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  return m_aLines.GetSize ();
}

int CCrystalTextBuffer::GetLineLength(int nLine)
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  return m_aLines[nLine]->m_nLength;
}

LPTSTR CCrystalTextBuffer::GetLineChars(int nLine)
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  return m_aLines[nLine]->m_pcLine;
}

DWORD CCrystalTextBuffer::GetLineFlags(int nLine)
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  return m_aLines[nLine]->m_dwFlags;
}

static int FlagToIndex(DWORD dwFlag)
{
  int nIndex = 0;
  while ((dwFlag & 1) == 0)
    {
      dwFlag = dwFlag >> 1;
      nIndex++;
      if (nIndex == 32)
        return -1;
    }
  dwFlag = dwFlag & 0xFFFFFFFE;
  if (dwFlag != 0)
    return -1;
  return nIndex;

}

int CCrystalTextBuffer::FindLineWithFlag(DWORD dwFlag)
{
  int nSize = m_aLines.GetSize ();
  for (int L = 0; L < nSize; L++)
    {
      if ((m_aLines[L]->m_dwFlags & dwFlag) != 0)
        return L;
    }
  return -1;
}

int CCrystalTextBuffer::GetLineWithFlag(DWORD dwFlag)
{
  int nFlagIndex =::FlagToIndex (dwFlag);
  if (nFlagIndex < 0)
    {
      ASSERT (FALSE);           //  Invalid flag passed in

      return -1;
    }
  return FindLineWithFlag (dwFlag);
}

void CCrystalTextBuffer::SetLineFlag(int nLine, DWORD dwFlag, BOOL bSet,
									 BOOL bRemoveFromPreviousLine /*= TRUE*/ )
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  int nFlagIndex =::FlagToIndex (dwFlag);
  if (nFlagIndex < 0)
    {
      ASSERT (FALSE);           //  Invalid flag passed in

      return;
    }

  if (nLine == -1)
    {
      ASSERT (!bSet);
      nLine = FindLineWithFlag (dwFlag);
      if (nLine == -1)
        return;
      bRemoveFromPreviousLine = FALSE;
    }

  DWORD dwNewFlags = m_aLines[nLine]->m_dwFlags;
  if (bSet)
    dwNewFlags = dwNewFlags | dwFlag;
  else
    dwNewFlags = dwNewFlags & ~dwFlag;

  if (m_aLines[nLine]->m_dwFlags != dwNewFlags)
    {
      if (bRemoveFromPreviousLine)
        {
          int nPrevLine = FindLineWithFlag (dwFlag);
          if (bSet)
            {
              if (nPrevLine >= 0)
                {
                  ASSERT ((m_aLines[nPrevLine]->m_dwFlags & dwFlag) != 0);
                  m_aLines[nPrevLine]->m_dwFlags &= ~dwFlag;
                  UpdateViews (NULL, NULL, UPDATE_SINGLELINE | UPDATE_FLAGSONLY, nPrevLine);
                }
            }
          else
            {
              ASSERT (nPrevLine == nLine);
            }
        }

      m_aLines[nLine]->m_dwFlags = dwNewFlags;
      UpdateViews (NULL, NULL, UPDATE_SINGLELINE | UPDATE_FLAGSONLY, nLine);
    }
}

void CCrystalTextBuffer::GetText(int nStartLine, int nStartChar, 
								  int nEndLine, int nEndChar, CString & text,
								  LPCTSTR pszCRLF /*= NULL*/ )
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  ASSERT (nStartLine >= 0 && nStartLine < m_aLines.GetSize ());
  ASSERT (nStartChar >= 0 && nStartChar <= m_aLines[nStartLine]->m_nLength);
  ASSERT (nEndLine >= 0 && nEndLine < m_aLines.GetSize ());
  ASSERT (nEndChar >= 0 && nEndChar <= m_aLines[nEndLine]->m_nLength);
  ASSERT (nStartLine < nEndLine || nStartLine == nEndLine && nStartChar < nEndChar);

  if (pszCRLF == NULL)
    pszCRLF = crlf;
  int nCRLFLength = _tcslen (pszCRLF);
  ASSERT (nCRLFLength > 0);

  int nBufSize = 0;
  for (int L = nStartLine; L <= nEndLine; L++)
    {
      nBufSize += m_aLines[L]->m_nLength;
      nBufSize += nCRLFLength;
    }

  LPTSTR pszBuf = text.GetBuffer (nBufSize);

  if (nStartLine < nEndLine)
    {
      int nCount = m_aLines[nStartLine]->m_nLength - nStartChar;
      if (nCount > 0)
        {
          memcpy (pszBuf, m_aLines[nStartLine]->m_pcLine + nStartChar, sizeof (TCHAR) * nCount);
          pszBuf += nCount;
        }
      memcpy (pszBuf, pszCRLF, sizeof (TCHAR) * nCRLFLength);
      pszBuf += nCRLFLength;
      for (int I = nStartLine + 1; I < nEndLine; I++)
        {
          nCount = m_aLines[I]->m_nLength;
          if (nCount > 0)
            {
              memcpy (pszBuf, m_aLines[I]->m_pcLine, sizeof (TCHAR) * nCount);
              pszBuf += nCount;
            }
          memcpy (pszBuf, pszCRLF, sizeof (TCHAR) * nCRLFLength);
          pszBuf += nCRLFLength;
        }
      if (nEndChar > 0)
        {
          memcpy (pszBuf, m_aLines[nEndLine]->m_pcLine, sizeof (TCHAR) * nEndChar);
          pszBuf += nEndChar;
        }
    }
  else
    {
      int nCount = nEndChar - nStartChar;
      memcpy (pszBuf, m_aLines[nStartLine]->m_pcLine + nStartChar, sizeof (TCHAR) * nCount);
      pszBuf += nCount;
    }
  pszBuf[0] = 0;
  text.ReleaseBuffer ();
  text.FreeExtra ();
}

void CCrystalTextBuffer::AddView(CCrystalTextView * pView)
{
  m_lpViews.AddTail (pView);
}

void CCrystalTextBuffer::RemoveView(CCrystalTextView * pView)
{
  POSITION pos = m_lpViews.GetHeadPosition ();
  while (pos != NULL)
    {
      POSITION thispos = pos;
      CCrystalTextView *pvw = m_lpViews.GetNext (pos);
      if (pvw == pView)
        {
          m_lpViews.RemoveAt (thispos);
          return;
        }
    }
  ASSERT (FALSE);
}

CCrystalTextView::TextDefinition *CCrystalTextBuffer::RetypeViews(LPCTSTR lpszFileName)
{
  POSITION pos = m_lpViews.GetHeadPosition ();
  CString sNew = GetExt (lpszFileName);
  CCrystalTextView::TextDefinition *def = CCrystalTextView::GetTextType (sNew);
  while (pos != NULL)
  {
      CCrystalTextView *pView = m_lpViews.GetNext (pos);
      pView->SetTextType (def);
  }
  return def;
}

void CCrystalTextBuffer::UpdateViews (CCrystalTextView * pSource, 
									  CUpdateContext * pContext, 
									  DWORD dwUpdateFlags, int nLineIndex /*= -1*/ )
{
  POSITION pos = m_lpViews.GetHeadPosition ();
  while (pos != NULL)
  {
      CCrystalTextView *pView = m_lpViews.GetNext (pos);
      pView->UpdateView (pSource, pContext, dwUpdateFlags, nLineIndex);
  }
}


BOOL CCrystalTextBuffer::InternalInsertTextExt(CCrystalTextView * pSource, int nLine, 
						int nPos, LPCTSTR pszText, int &nEndLine, int &nEndChar)
{
	return InternalInsertText(pSource,nLine,nPos,pszText,nEndLine,nEndChar);

}

BOOL CCrystalTextBuffer::InternalDeleteTextExt(CCrystalTextView * pSource, int nStartLine, 
						int nStartPos, int nEndLine, int nEndPos)
{
	return InternalDeleteText(pSource,nStartLine,nStartPos,nEndLine,nEndPos);
}






BOOL CCrystalTextBuffer::InternalDeleteText (CCrystalTextView * pSource,
											 int nStartLine, int nStartChar,
											 int nEndLine, int nEndChar)
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!

  ASSERT (nStartLine >= 0 && nStartLine < m_aLines.GetSize ());
  ASSERT (nStartChar >= 0 && nStartChar <= m_aLines[nStartLine]->m_nLength);
  ASSERT (nEndLine >= 0 && nEndLine < m_aLines.GetSize ());
  ASSERT (nEndChar >= 0 && nEndChar <= m_aLines[nEndLine]->m_nLength);
  ASSERT (nStartLine < nEndLine || nStartLine == nEndLine && nStartChar < nEndChar);
  
  if(m_bReadOnly)
    return FALSE;

  CDeleteContext context;
  context.m_ptStart.y = nStartLine;
  context.m_ptStart.x = nStartChar;
  context.m_ptEnd.y = nEndLine;
  context.m_ptEnd.x = nEndChar;

  if(nStartLine == nEndLine)
  {
      SLineInfo * li = m_aLines[nStartLine];
      if(nEndChar < li->m_nLength)
	  {
          memcpy (li->m_pcLine + nStartChar, li->m_pcLine + nEndChar,
                  sizeof (TCHAR) * (li->m_nLength - nEndChar));
	  }
      li->m_nLength -= (nEndChar - nStartChar);

      UpdateViews (pSource, &context, UPDATE_SINGLELINE | UPDATE_HORZRANGE, nStartLine);
  }
  else
  {
      int nRestCount = m_aLines[nEndLine]->m_nLength - nEndChar;
      LPTSTR pszRestChars = NULL;
      if(nRestCount > 0)
	  {
         pszRestChars = new TCHAR[nRestCount];
         memcpy (pszRestChars, m_aLines[nEndLine]->m_pcLine + nEndChar, nRestCount * sizeof (TCHAR));
	  }

      int nDelCount = nEndLine - nStartLine;

      for(int L = nStartLine + 1; L <= nEndLine; L++)
	  {
        delete m_aLines[L]->m_pcLine;
		delete m_aLines[L];
	  }
      m_aLines.RemoveAt(nStartLine + 1, nDelCount);


      //  nEndLine is no more valid
      m_aLines[nStartLine]->m_nLength = nStartChar;
      if(nRestCount > 0)
	  {
         AppendLine (nStartLine, pszRestChars, nRestCount);
         delete pszRestChars;
	  }

      UpdateViews (pSource, &context, UPDATE_HORZRANGE | UPDATE_VERTRANGE, nStartLine);
  }

  if (!m_bModified)
    SetModified (TRUE);
	//BEGIN SW
	// remember current cursor position as last editing position
	m_ptLastChange = context.m_ptStart;
	//END SW
  return TRUE;
}

BOOL CCrystalTextBuffer::InternalInsertText (CCrystalTextView * pSource,
											 int nLine, int nPos, LPCTSTR pszText,
											 int &nEndLine, int &nEndChar)
{
  ASSERT (m_bInit);             //  Text buffer not yet initialized.
  //  You must call InitNew() or LoadFromFile() first!
  ASSERT (nLine >= 0 && nLine < m_aLines.GetSize ());
  ASSERT (nPos >= 0 && nPos <= m_aLines[nLine]->m_nLength);
  if (m_bReadOnly)
    return FALSE;

  CInsertContext context;
  context.m_ptStart.x = nPos;
  context.m_ptStart.y = nLine;

  int nRestCount = m_aLines[nLine]->m_nLength - nPos;
  LPTSTR pszRestChars = NULL;

  if(nRestCount > 0)
  {
	
    pszRestChars = new TCHAR[nRestCount];
    memcpy (pszRestChars, m_aLines[nLine]->m_pcLine + nPos, nRestCount * sizeof (TCHAR));
    m_aLines[nLine]->m_nLength = nPos;
  }

  int nCurrentLine = nLine;
  BOOL bNewLines = FALSE;
  int nTextPos;
  for(;;)
  {
      nTextPos = 0;
      while (pszText[nTextPos] != 0 && pszText[nTextPos] != _T ('\r'))
        nTextPos++;

      if (nCurrentLine == nLine)
        {
          AppendLine (nLine, pszText, nTextPos);
        }
      else
        {
          InsertLine (pszText, nTextPos, nCurrentLine);
          bNewLines = TRUE;
        }

      if (pszText[nTextPos] == 0)
        {
          nEndLine = nCurrentLine;
          nEndChar = m_aLines[nCurrentLine]->m_nLength;
          AppendLine (nCurrentLine, pszRestChars, nRestCount);
          break;
        }

      nCurrentLine++;
      nTextPos++;

      if (pszText[nTextPos] == _T ('\n'))
        {
          nTextPos++;
        }
      else
        {
          ASSERT (FALSE);       //  Invalid line-end format passed

        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?