bgfeditview.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 553 行

CPP
553
字号
// BGFEditView.cpp: implementation of the CBGFEditView class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BGFEditView.h"
#include "editcmd.h"
#include "BaseTextBuffer.h"
#include "browser.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define REAL_MARGIN_WIDTH 20
#define GetColapseWidth() m_bEnableColapsingCode?GetLineHeight():0
#define RealMarginWidth() m_bSelMargin?REAL_MARGIN_WIDTH:0
#define COOKIE_SLOT 0x0
#define DATA_SLOT   0x1
#define COOKIE_COLAPSED         0x0100


static LPTSTR s_apszKeywordList[] =
{
    _T ("abstract"),
    _T ("default"),
    _T ("goto"),
    _T ("null"),
    _T ("synchronized"),
    _T ("boolean"),
    _T ("do"),
    _T ("if"),
    _T ("package"),
    _T ("this"),
    _T ("break"),
    _T ("double"),
    _T ("implements"),
    _T ("private"),
    _T ("threadsafe"),
    _T ("byte"),
    _T ("else"),
    _T ("import"),
    _T ("protected"),
    _T ("throw"),
    _T ("byvalue"),
    _T ("extends"),
    _T ("instanceof"),
    _T ("public"),
    _T ("transient"),
    _T ("case"),
    _T ("false"),
    _T ("int"),
    _T ("return"),
    _T ("true"),
    _T ("catch"),
    _T ("final"),
    _T ("interface"),
    _T ("short"),
    _T ("try"),
    _T ("char"),
    _T ("finally"),
    _T ("long"),
    _T ("static"),
    _T ("void"),
    _T ("class"),
    _T ("float"),
    _T ("native"),
    _T ("super"),
    _T ("while"),
    _T ("const"),
    _T ("for"),
    _T ("new"),
    _T ("switch"),
    _T ("continue"),
    NULL
};

static BOOL IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength)
{
  for (int L = 0; apszKeywords[L] != NULL; L++)
    {
      if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0
            && apszKeywords[L][nLength] == 0)
        return TRUE;
    }
  return FALSE;
}

static BOOL IsKeyword (LPCTSTR pszChars, int nLength)
{
  return IsXKeyword (s_apszKeywordList, pszChars, nLength);
}

static BOOL IsNumber (LPCTSTR pszChars, int nLength)
{
  if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x')
    {
      for (int I = 2; I < nLength; I++)
        {
          if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') ||
                (pszChars[I] >= 'a' && pszChars[I] <= 'f'))
            continue;
          return FALSE;
        }
      return TRUE;
    }
  if (!_istdigit (pszChars[0]))
    return FALSE;
  for (int I = 1; I < nLength; I++)
    {
      if (!_istdigit (pszChars[I]) && pszChars[I] != '+' &&
            pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' &&
            pszChars[I] != 'E')
        return FALSE;
    }
  return TRUE;
}

#define DEFINE_BLOCK(pos, colorindex)   \
ASSERT((pos) >= 0 && (pos) <= nLength);\
if (pBuf != NULL)\
  {\
    if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\
        pBuf[nActualItems].m_nCharPos = (pos);\
        pBuf[nActualItems].m_nColorIndex = (colorindex);\
        nActualItems ++;}\
  }

#define COOKIE_COMMENT          0x0001
#define COOKIE_PREPROCESSOR     0x0002
#define COOKIE_EXT_COMMENT      0x0004
#define COOKIE_STRING           0x0008
#define COOKIE_CHAR             0x0010
#define COOKIE_WIZARD_CODE      0x0020
#define COOKIE_COLAPSIBLE       0x0040
#define COOKIE_ROOTNODE         0x0080
#define COOKIE_COLAPSED         0x0100




bool isopenbrace (TCHAR c)
{
  return c == _T ('{') || c == _T ('(') || c == _T ('[') || c == _T ('<');
}

bool isclosebrace (TCHAR c)
{
  return c == _T ('}') || c == _T ('}') || c == _T (']') || c == _T ('>');
}

bool isopenbrace (LPCTSTR s)
{
  return s[1] == _T ('\0') && isopenbrace (*s);
}

bool isclosebrace (LPCTSTR s)
{
  return s[1] == _T ('\0') && isclosebrace (*s);
}

int bracetype (TCHAR c)
{
  static LPCTSTR braces = _T("{}()[]<>");
  LPCTSTR pos = _tcschr (braces, c);
  return pos ? pos - braces + 1 : 0;
}

int bracetype (LPCTSTR s)
{
  if (s[1])
    return 0;
  return bracetype (*s);
}


IMPLEMENT_DYNCREATE(CBGFEditView,CCrystalEditViewEx)

BEGIN_MESSAGE_MAP (CBGFEditView,CCrystalEditViewEx)
     ON_WM_SETCURSOR()
     ON_WM_LBUTTONDOWN()
     ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()

CBGFEditView::CBGFEditView()
{
  m_bEnableColapsingCode = FALSE;
}

CBGFEditView::~CBGFEditView()
{

}


void CBGFEditView::DrawColapseIndentImpl(CDC * pdc, const CRect & rect,
		                       int nLineIndex,int nChar,BOOL bNode,BOOL bRootNode)
{
   CRect rcFill(rect);

   if(bNode)
   {
	  int nOffSet    = 0;
	  CRect rcRect(rect);
      if(!bRootNode)
	  {
        nOffSet = nChar*GetCharWidth();
		rcFill.OffsetRect(nOffSet,0);
		rcRect.OffsetRect(nOffSet,0);
	  }

	 int nShrink = (GetLineHeight()/2)-5;
	 rcFill.DeflateRect(nShrink,nShrink,nShrink,nShrink);
	 pdc->Draw3dRect(rcFill,GetSysColor(COLOR_BTNSHADOW),
		                                              GetSysColor(COLOR_BTNSHADOW));



	 CPen nPen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW));
	 int nMid = GetLineHeight()/2;

	 
	 CPen* pOldPen = pdc->SelectObject(&nPen);
	 
     CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;

	 //************
	 //draw plus
	 if(pTemp->isColapsed(nLineIndex,nChar))
	 {
	   pdc->MoveTo(rcRect.left+nMid,rcRect.top+nShrink+3);
	   pdc->LineTo(rcRect.left+nMid,rcRect.bottom-nShrink-3);
	 }
	 //************/
	 pdc->MoveTo(rcRect.left+nShrink+3,rcRect.top+nMid);
	 pdc->LineTo(rcRect.right-nShrink-3,rcRect.top+nMid);

     //fill gap up and down for shrink
	 rcRect.OffsetRect(-nOffSet,0);//reverse

	 BOOL bRt = bRootNode;
	 pdc->MoveTo(rcRect.left+nMid,rcRect.top);
	 pdc->LineTo(rcRect.left+nMid,bRt?rcRect.top+nShrink:rcRect.top+nMid+1);

	 pdc->MoveTo(rcRect.left+nMid,bRt?rcRect.bottom-nShrink:rcRect.bottom-nMid);
	 pdc->LineTo(rcRect.left+nMid,rcRect.bottom);

	 pdc->SelectObject(pOldPen);

	 if(bRootNode)//draw line from node to '{' or 
	 {
        LPCTSTR lszpChar = GetLineChars(nLineIndex);
		int nLength = GetLineLength(nLineIndex);

		for(int I=0; I<nLength; I++)
		{
           if(iswspace(lszpChar[I]))
			  continue;
		   else break;
		}
		int nOffSet = I*GetCharWidth();

        CPen nPen_1(PS_DASH,1,GetSysColor(COLOR_BTNSHADOW));
		CPen *pOldPen = pdc->SelectObject(&nPen_1);

		pdc->MoveTo(rcFill.right,rcRect.top+nMid);
		pdc->LineTo(rcFill.right+nOffSet,rcRect.top+nMid);

		pdc->SelectObject(pOldPen);
	 }
   }
   else
   {
     int nShrink = (GetLineHeight()/2);
	 rcFill.DeflateRect(nShrink,0,nShrink,0);
     pdc->FillSolidRect(rcFill,GetSysColor(COLOR_BTNSHADOW));
   }
}


void CBGFEditView::DrawColapseIndent(CDC * pdc, const CRect & rect,
					                                int nLineIndex)
{
  if(!m_bEnableColapsingCode||nLineIndex == -1)
  {
     pdc->FillSolidRect(rect,GetColor(COLORINDEX_BKGND));

	 if(m_bEnableColapsingCode)
		   DrawColapseIndentImpl(pdc,rect,nLineIndex,-1,FALSE,FALSE);
     return;
  }

  pdc->FillSolidRect(rect,GetColor(COLORINDEX_BKGND));


  LPCTSTR lszpChar = GetLineChars(nLineIndex);
  bool bChecked4RootNode   = false;

  CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;

  int nodeCount = pTemp->nodeCount(nLineIndex);
  for(int I=0; I<nodeCount; I++)
  {
	 int nCurIndex = pTemp->nodeIndexAt(nLineIndex,I);

     if(!bChecked4RootNode&&(pTemp->nodeDeclAt(nLineIndex,I)->getParent() == NULL))
	 {
		 bChecked4RootNode = true;
		if((nCurIndex>0&&iswspace(lszpChar[nCurIndex-1]))||nCurIndex==0)//only draw box if there is space
         DrawColapseIndentImpl(pdc,rect,nLineIndex,nCurIndex,TRUE,TRUE);
	 }
	 else
	 if(m_bEnableColapsingAllBlocks)
	 {
         if((nCurIndex>0&&iswspace(lszpChar[nCurIndex-1]))||nCurIndex==0)//only draw box if there is space
            DrawColapseIndentImpl(pdc,rect,nLineIndex,nCurIndex,TRUE,FALSE);
	 }
	 else return;
  }
  
	 if(nodeCount == 0)
  DrawColapseIndentImpl(pdc,rect,nLineIndex,-1,FALSE,FALSE);
}

void CBGFEditView::GetLineRect(int nLineIndex,CRect &rcLine)
{
  int nScreenLine = nLineIndex-m_nTopLine;
	
  CRect rcClient;
  GetClientRect (rcClient);


  int nLineHeight = GetLineHeight();
  int nOffSet = nScreenLine* nLineHeight;

  rcLine.top    = rcClient.top+nOffSet;
  rcLine.bottom = rcLine.top+nLineHeight;
  rcLine.left   = GetMarginWidth();
  rcLine.right  = rcClient.right;
}

CRect CBGFEditView::GetExpandNode(CPoint pt,int &nNodeIndex)
{
//	/**
   CPoint ptText  = ClientToText(pt);
   int nLineIndex = ptText.y;

   CRect rcRect;
   GetLineRect(nLineIndex,rcRect);
   CRect rcColapseIndent((RealMarginWidth()),0,(RealMarginWidth())+(GetColapseWidth()),rcRect.bottom);


   rcRect          = rcColapseIndent;
   BOOL bRootNode  = FALSE;

   int nShrink = (GetLineHeight()/2)-5;
   rcRect.DeflateRect(nShrink,nShrink,nShrink,nShrink);
   
   CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;

   int nNodeCount = pTemp->nodeCount(nLineIndex);
   for(int xI=0; xI<nNodeCount; xI++)
   {
      int nCurIndex    = pTemp->nodeIndexAt(nLineIndex,xI);
   
      if(xI==0&&pTemp->m_pDeclManager->PointInBlockDecl
	                                  (nCurIndex,nLineIndex,bRootNode)&&bRootNode)
      {
	    if(bRootNode)//test at the margin
		{
          if(rcRect.PtInRect(pt))
		  {
			 nNodeIndex = nCurIndex;
		     return rcRect;
		  }
		}
		else
        goto non_root;
      }
      else
      {
non_root:        
        int nOffSet = nCurIndex*GetCharWidth();
	    rcRect.OffsetRect(nOffSet,0);

	    if(rcRect.PtInRect(pt))
		{
		   nNodeIndex = nCurIndex;
           return rcRect;
		}
		else 
		   rcRect.OffsetRect(-nOffSet,0);
     }
   }
  // **/
   return CRect(0,0,0,0);
}

int CBGFEditView::GetMarginWidth()
{
  return CCrystalEditViewEx::GetMarginWidth();
  if(m_bSelMargin)
	 return ((REAL_MARGIN_WIDTH)+(GetColapseWidth()));
  else 
	 return GetColapseWidth();
}

void CBGFEditView::OnDraw(CDC * pdc)
{
  CCrystalEditViewEx::OnDraw(pdc);return;
  
  CRect rcClient;
  GetClientRect (rcClient);

  int nLineCount  = GetLineCount();
  int nLineHeight = GetLineHeight();
  PrepareSelBounds();

  CDC cacheDC;
  VERIFY(cacheDC.CreateCompatibleDC(pdc));

  if(m_pCacheBitmap == NULL)
  {
     m_pCacheBitmap = new CBitmap;
	 VERIFY(m_pCacheBitmap->CreateCompatibleBitmap(pdc,rcClient.Width(),rcClient.Height()));
  }
  CBitmap *pOldBitmap = cacheDC.SelectObject(m_pCacheBitmap);

  CRect rcLine;
  rcLine = rcClient;
  rcLine.bottom = rcLine.top + nLineHeight;

  int margin = GetMarginWidth();
  CRect rcCacheMargin(0,0,(RealMarginWidth()),nLineHeight);
  CRect rcColapseIndent((RealMarginWidth()),0,(RealMarginWidth())+(GetColapseWidth()),nLineHeight);
  CRect rcCacheLine(GetMarginWidth(),0,GetMarginWidth()+rcLine.Width(),nLineHeight);
  //rcLine.left =  rcCacheLine.left;
  //rcLine.right = rcCacheLine.right;


  int nBreaks;
  int nMaxLineChars = GetScreenChars();
  int nCurrentLine  = m_nTopLine;

  while(rcLine.top < rcClient.bottom)
  {
	  nBreaks = 0;
	  rcLine.bottom = rcLine.top + (nBreaks + 1) * nLineHeight;
	  rcCacheLine.bottom = rcCacheLine.top + rcLine.Height();
	  rcCacheMargin.bottom = rcCacheMargin.top + rcLine.Height();
      rcColapseIndent.bottom =  rcColapseIndent.top + rcLine.Height();

	  if(rcCacheLine.top < 0 )
			rcLine.bottom+= rcCacheLine.top;

      if(nCurrentLine < nLineCount)
      {
        DrawMargin (&cacheDC, rcCacheMargin, nCurrentLine);		
        DrawSingleLine(&cacheDC, rcCacheLine, nCurrentLine);
		DrawColapseIndent(&cacheDC,rcColapseIndent,nCurrentLine);
      }
      else
      {
        DrawMargin(&cacheDC, rcCacheMargin, -1);
        DrawSingleLine(&cacheDC, rcCacheLine, -1);
		DrawColapseIndent(&cacheDC,rcColapseIndent,-1);		
      }
      VERIFY(pdc->BitBlt(rcLine.left,rcLine.top,rcLine.Width(),rcLine.Height(),&cacheDC, 0, 0, SRCCOPY));

      
	  rcLine.top = rcLine.bottom;
	  rcCacheLine.top = 0;
	  rcCacheMargin.top = 0;
	  rcColapseIndent.top = 0;
	  nCurrentLine++;
    }
  cacheDC.SelectObject (pOldBitmap);
  cacheDC.DeleteDC ();
}



BOOL CBGFEditView::OnSetCursor (CWnd * pWnd, UINT nHitTest, UINT message)
{
  if(!CCrystalTextView::OnSetCursor(pWnd,nHitTest,message))
       return FALSE;

  if(nHitTest == HTCLIENT)
  {
      CPoint pt;
      ::GetCursorPos(&pt);
      ScreenToClient(&pt);

	  int nNodeIndex = -1;
      if(pt.x < GetMarginWidth()||GetExpandNode(pt,nNodeIndex).PtInRect(pt))
      {
        ::SetCursor(::LoadCursor(GetResourceHandle(),MAKEINTRESOURCE(IDR_MARGIN_CURSOR)));
      }
      return TRUE;
  }
  return TRUE;
}

void CBGFEditView::OnLButtonDblClk (UINT nFlags, CPoint point)
{
  CCrystalTextView::OnLButtonDblClk (nFlags, point);

  if(!m_bDragSelection)
  {
	  int nNodeIndex = -1;
	  CRect rcNode = GetExpandNode(point,nNodeIndex);
	  if(rcNode.PtInRect(point))
	  {
		 CPoint ptLine = ClientToText(point);
		 CBaseTextBuffer* pTemp = (CBaseTextBuffer*)m_pTextBuffer;

         pTemp->_toggle(ptLine.y,nNodeIndex,this);
		 //InvalidateRect(&rcNode);
		 //UpdateWindow();
	  }
  }
}

void CBGFEditView::OnLButtonDown (UINT nFlags, CPoint point)
{
  int nNodeIndex = -1;
  CRect rcNode = GetExpandNode(point,nNodeIndex);

  if(rcNode.PtInRect(point))
  {
	CPoint ptLine = ClientToText(point);
    CBaseTextBuffer* pBaseTB = (CBaseTextBuffer*)m_pTextBuffer;
    pBaseTB->_toggle(ptLine.y,nNodeIndex,this);

	/*
	CRect rcClient;
	GetClientRect(rcClient);
         
	rcClient.top = rcNode.top;

	InvalidateRect(&rcClient);
	UpdateWindow();
	*/
  }
  else CCrystalTextView::OnLButtonDown (nFlags, point);
}







⌨️ 快捷键说明

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