XTPSyntaxEditCtrl.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:195k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPSyntaxEditCtrl.cpp
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. // common includes
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPImageManager.h"
  25. #include "Common/XTPNotifyConnection.h"
  26. #include "Common/XTPSmartPtrInternalT.h"
  27. #include "Common/XTPVC80Helpers.h"
  28. #include "Common/XTPVC50Helpers.h"
  29. #include "Common/XTPResourceManager.h"
  30. // syntax editor includes
  31. #include "XTPSyntaxEditDefines.h"
  32. #include "XTPSyntaxEditStruct.h"
  33. #include "XTPSyntaxEditUndoManager.h"
  34. #include "XTPSyntaxEditLineMarksManager.h"
  35. #include "XTPSyntaxEditLexPtrs.h"
  36. #include "XTPSyntaxEditLexClassSubObjT.h"
  37. #include "XTPSyntaxEditTextIterator.h"
  38. #include "XTPSyntaxEditSectionManager.h"
  39. #include "XTPSyntaxEditLexCfgFileReader.h"
  40. #include "XTPSyntaxEditLexClassSubObjDef.h"
  41. #include "XTPSyntaxEditLexClass.h"
  42. #include "XTPSyntaxEditLexParser.h"
  43. #include "XTPSyntaxEditLexColorFileReader.h"
  44. #include "XTPSyntaxEditBufferManager.h"
  45. #include "XTPSyntaxEditToolTipCtrl.h"
  46. #include "XTPSyntaxEditAutoCompleteWnd.h"
  47. #include "XTPSyntaxEditFindReplaceDlg.h"
  48. #include "XTPSyntaxEditCtrl.h"
  49. #include "XTPSyntaxEditDoc.h"
  50. #include "XTPSyntaxEditView.h"
  51. #include "XTPSyntaxEditPaintManager.h"
  52. #include <math.h>
  53. #define XTP_IDC_EDIT_DRAG_MOVE 0xE12D
  54. #define XTP_IDC_EDIT_DRAG_COPY 0xE12E
  55. #ifdef _DEBUG
  56. #define new DEBUG_NEW
  57. #undef THIS_FILE
  58. static char THIS_FILE[] = __FILE__;
  59. #endif
  60. /////////////////////////////////////////////////////////////////////////////
  61. namespace XTPSyntaxEditLexAnalyser
  62. {
  63. CString DBG_TraceTB_StartEndCls(CXTPSyntaxEditLexTextBlock* pTB);
  64. }
  65. const int MARGIN_LENGTH             = 20;
  66. const int NODES_WIDTH               = 10;
  67. const int TEXT_LEFT_OFFSET          = 4;
  68. const UINT TIMER_SELECTION_ID       = 100;
  69. const UINT TIMER_SELECTION_TIME     = 50;
  70. const UINT TIMER_REDRAW_WHEN_PARSE  = 200;
  71. const UINT TIMER_AUTOSCROLL_ID      = 110;
  72. const UINT TIMER_AUTOSCROLL_TIME    = 120;
  73. enum XTPSyntaxEditFlags
  74. {
  75. xtpEditRedraw       = 0x0001,
  76. xtpEditForceRedraw  = 0x0002,
  77. xtpEditTextAsBlock  = 0x0004,
  78. xtpEditDispCol      = 0x0008,
  79. };
  80. /////////////////////////////////////////////////////////////////////////////
  81. // CXTPSyntaxEditCtrl
  82. CXTPSyntaxEditCtrl::CXTPSyntaxEditCtrl()
  83. : m_bVertScrollBar(TRUE)
  84. , m_bHorzScrollBar(TRUE)
  85. , m_bSyntaxColor(TRUE)
  86. , m_bAutoIndent(TRUE)
  87. , m_bSelMargin(TRUE)
  88. , m_bLineNumbers(TRUE)
  89. , m_bWideCaret(TRUE)
  90. , m_bTabWithSpace(FALSE)
  91. , m_bDragging(FALSE)
  92. , m_bDroppable(FALSE)
  93. , m_bTokensLoaded(FALSE)
  94. , m_bIsScrollingEndRow(FALSE)
  95. , m_bRightButtonDrag(FALSE)
  96. , m_bIsSmartIndent(TRUE)
  97. , m_bEnableOleDrag(FALSE)
  98. , m_bEnableWhiteSpace(FALSE)
  99. , m_bCaseSensitive(TRUE)
  100. , m_bScrolling(FALSE)
  101. , m_bDrawNodes(TRUE)
  102. , m_bFocused(FALSE)
  103. , m_bIsActive(FALSE)
  104. , m_nTopCalculatedRow(-1)
  105. , m_nBottomCalculatedRow(-1)
  106. , m_nTopRow(1)
  107. , m_nCurrentCol(1)
  108. , m_nCurrentDocumentRow(1)
  109. , m_nDispCol(1)
  110. , m_nAutoIndentCol(0)
  111. , m_nMarginLength(MARGIN_LENGTH)
  112. , m_nLineNumLength(0)
  113. , m_nNodesWidth(NODES_WIDTH)
  114. , m_nEditbarLength(MARGIN_LENGTH + NODES_WIDTH)
  115. , m_nCollapsedTextRowsCount(0)
  116. , m_nWheelScroll(4)
  117. , m_nAverageLineLen(XTP_EDIT_AVELINELEN)
  118. , m_dwInsertPos(0)
  119. , m_dwLastRedrawTime(0)
  120. , m_ptPrevMouse(CPoint(0,0))
  121. , m_pBuffer(NULL)
  122. , m_pParentWnd(NULL)
  123. {
  124. m_Selection.m_pOwnerCtrl = this;
  125. m_bCreateScrollbarOnParent = TRUE;
  126. m_bVirtualSpace = FALSE;
  127. m_bReadOnly = FALSE;
  128. m_bHideCaret = FALSE;
  129. m_bEnableEditAccelerators = FALSE;
  130. #ifndef _UNICODE
  131. m_chPrevLeadByte = 0;
  132. #endif
  133. m_bIMEsupported = FALSE;
  134. m_pPaintManeger = new CXTPSyntaxEditPaintManager();
  135. GetRegValues();
  136. RegisterWindowClass();
  137. m_strDefaultCfgFilePath = GetModulePath() + XTP_EDIT_LEXPARSER_CFG_FILENAME;
  138. m_nHScrollMaxWidth = 0;
  139. m_bWndCreateInProgress = FALSE;
  140. m_dwAutoScrollDirection = 0;
  141. m_bDisableRedraw = FALSE;
  142. m_bDeleteOnFinalRelease = FALSE;
  143. // Set editor fonts.
  144. SetFontIndirect(NULL);
  145. m_pToolTip = new CXTPSyntaxEditToolTipCtrl();
  146. m_pAutoComplete = new CXTPSyntaxEditAutoCompleteWnd();
  147. }
  148. CXTPSyntaxEditCtrl::~CXTPSyntaxEditCtrl()
  149. {
  150. if (m_pBuffer && m_pBuffer->GetLexParser())
  151. m_pBuffer->GetLexParser()->CloseParseThread();
  152. m_Sink.UnadviseAll();
  153. m_arOnScreenSchCache.RemoveAll();
  154. CMDTARGET_RELEASE(m_pBuffer);
  155. DestroyWindow();
  156. CMDTARGET_RELEASE(m_pPaintManeger);
  157. SAFE_DELETE(m_pToolTip);
  158. SAFE_DELETE(m_pAutoComplete);
  159. }
  160. void CXTPSyntaxEditCtrl::OnFinalRelease()
  161. {
  162. CWnd::OnFinalRelease();
  163. if (m_bDeleteOnFinalRelease)
  164. {
  165. CCmdTarget::OnFinalRelease();
  166. }
  167. }
  168. IMPLEMENT_DYNAMIC(CXTPSyntaxEditCtrl, CWnd)
  169. BEGIN_MESSAGE_MAP(CXTPSyntaxEditCtrl, CWnd)
  170. //{{AFX_MSG_MAP(CXTPSyntaxEditCtrl)
  171. ON_WM_PAINT()
  172. ON_WM_SETCURSOR()
  173. ON_WM_HSCROLL()
  174. ON_WM_VSCROLL()
  175. ON_WM_KEYDOWN()
  176. ON_WM_SYSKEYDOWN()
  177. ON_WM_CHAR()
  178. ON_WM_LBUTTONDOWN()
  179. ON_WM_LBUTTONUP()
  180. ON_WM_MOUSEMOVE()
  181. ON_WM_CREATE()
  182. ON_WM_SIZE()
  183. ON_WM_SETFOCUS()
  184. ON_WM_NCACTIVATE()
  185. ON_WM_MOUSEACTIVATE()
  186. ON_WM_KEYUP()
  187. ON_WM_LBUTTONDBLCLK()
  188. ON_WM_RBUTTONDOWN()
  189. ON_WM_RBUTTONUP()
  190. ON_WM_ERASEBKGND()
  191. ON_WM_CONTEXTMENU()
  192. ON_WM_TIMER()
  193. ON_WM_KILLFOCUS()
  194. ON_WM_SHOWWINDOW()
  195. ON_WM_ACTIVATE()
  196. ON_WM_MOUSEWHEEL()
  197. ON_WM_GETDLGCODE()
  198. ON_WM_DESTROY()
  199. ON_COMMAND(XTP_IDC_EDIT_DRAG_COPY, OnDragCopy)
  200. ON_COMMAND(XTP_IDC_EDIT_DRAG_MOVE, OnDragMove)
  201. //}}AFX_MSG_MAP
  202. ON_MESSAGE(WM_SETTEXT, OnSetText)
  203. ON_MESSAGE(WM_GETTEXT, OnGetText)
  204. ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLen)
  205. ON_MESSAGE(WM_GETFONT, OnGetFont)
  206. ON_MESSAGE(WM_SETFONT, OnSetFont)
  207. ON_MESSAGE(WM_INPUTLANGCHANGE, OnInputLanguage)
  208. END_MESSAGE_MAP()
  209. /////////////////////////////////////////////////////////////////////////////
  210. // CXTPSyntaxEditCtrl message handlers
  211. BOOL CXTPSyntaxEditCtrl::GetRegValues()
  212. {
  213. CWinApp* pWinApp = AfxGetApp();
  214. if (pWinApp != NULL)
  215. {
  216. m_bVertScrollBar = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_VSCROLLBAR,   m_bVertScrollBar);
  217. m_bHorzScrollBar = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_HSCROLLBAR,   m_bHorzScrollBar);
  218. m_bSyntaxColor   = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_SYNTAXCOLOR,  m_bSyntaxColor);
  219. m_bAutoIndent    = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_AUTOINDENT,   m_bAutoIndent);
  220. m_bSelMargin     = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_SELMARGIN,    m_bSelMargin);
  221. m_bLineNumbers   = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_LINENUMBERS,  m_bLineNumbers);
  222. m_bWideCaret     = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_WIDECARET,    m_bWideCaret);
  223. m_bTabWithSpace  = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_TABWITHSPACE, m_bTabWithSpace);
  224. m_bVirtualSpace  = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_VIRTUALSPACE, m_bVirtualSpace);
  225. m_bDrawNodes     = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_COLLAPSIBLENODES, m_bDrawNodes);
  226. return TRUE;
  227. }
  228. return FALSE;
  229. }
  230. BOOL CXTPSyntaxEditCtrl::SetValueInt(LPCTSTR lpszValue, int nNewValue, int& nRefValue, BOOL bUpdateReg)
  231. {
  232. nRefValue = nNewValue;
  233. if (bUpdateReg)
  234. {
  235. CWinApp* pWinApp = AfxGetApp();
  236. if (pWinApp != NULL)
  237. {
  238. if (pWinApp->WriteProfileInt(XTP_EDIT_REG_SETTINGS, lpszValue, nNewValue))
  239. return TRUE;
  240. }
  241. return FALSE;
  242. }
  243. return TRUE;
  244. }
  245. BOOL CXTPSyntaxEditCtrl::SetValueBool(LPCTSTR lpszValue, BOOL bNewValue, BOOL& bRefValue, BOOL bUpdateReg)
  246. {
  247. bRefValue = bNewValue;
  248. if (bUpdateReg)
  249. {
  250. CWinApp* pWinApp = AfxGetApp();
  251. if (pWinApp != NULL)
  252. {
  253. if (pWinApp->WriteProfileInt(XTP_EDIT_REG_SETTINGS, lpszValue, (int)bNewValue))
  254. return TRUE;
  255. }
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }
  260. BOOL CXTPSyntaxEditCtrl::SetAutoIndent(BOOL bAutoIndent, BOOL bUpdateReg/*=FALSE*/)
  261. {
  262. if (!SetValueBool(XTP_EDIT_REG_AUTOINDENT, bAutoIndent, m_bAutoIndent, bUpdateReg))
  263. return FALSE;
  264. return TRUE;
  265. }
  266. void CXTPSyntaxEditCtrl::OnPaint()
  267. {
  268. DWORD dwStartTime = ::GetTickCount();
  269. CPaintDC dc(this); // device context for painting
  270. CXTPClientRect rcClient(this);
  271. //if ((!m_bChanged || m_bDisableRedraw) && m_bmpCache.GetSafeHandle() != 0)
  272. if (m_bDisableRedraw && m_bmpCache.GetSafeHandle() != 0)
  273. {
  274. CXTPCompatibleDC memDC(&dc, &m_bmpCache);
  275. dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY);
  276. }
  277. else
  278. {
  279. CDC memDC;
  280. memDC.CreateCompatibleDC(&dc);
  281. if (!m_bmpCache.m_hObject)
  282. m_bmpCache.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
  283. CXTPBitmapDC autoBitmap(&memDC, &m_bmpCache);
  284. #ifdef _DEBUG
  285. memDC.FillSolidRect(rcClient, 0xFF);
  286. #endif
  287. Draw(&memDC, rcClient);
  288. if (!IsWindowEnabled())
  289. {
  290. XTPImageManager()->DisableBitmap(memDC, rcClient, XTP_EDIT_DISABLED_COLOR_LIGHT, XTP_EDIT_DISABLED_COLOR_DARK);
  291. }
  292. dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY);
  293. //m_bChanged = FALSE;
  294. // Draw caret
  295. CSize szCaret;
  296. szCaret.cx = GetWideCaret() ? m_DrawTextProcessor.GetTextMetrics().tmAveCharWidth : 2;
  297. szCaret.cy = m_DrawTextProcessor.GetRowHeight();
  298. BOOL bVirtSpace = _IsVirtualSpaceActive() || m_nAutoIndentCol;
  299. int nCol = m_nDispCol - 1;
  300. BOOL bHideCaret = m_bHideCaret || !m_bFocused;
  301. CPoint ptCaret = m_DrawTextProcessor.SetCaretPos(this, szCaret, max(0, GetCurrentVisibleRow() - 1), nCol,
  302. bHideCaret, bVirtSpace);
  303. // IME Support
  304. if (m_bIMEsupported)
  305. {
  306. XTP_HIMC hIMC = m_ImmWrapper.ImmGetContext(m_hWnd);
  307. if (hIMC)
  308. {
  309. COMPOSITIONFORM compForm;
  310. ::ZeroMemory(&compForm, sizeof(compForm));
  311. compForm.dwStyle = CFS_POINT; //CFS_FORCE_POSITION
  312. compForm.ptCurrentPos = ptCaret;
  313. VERIFY(m_ImmWrapper.ImmSetCompositionWindow(hIMC, &compForm));
  314. VERIFY(m_ImmWrapper.ImmReleaseContext(m_hWnd, hIMC));
  315. }
  316. }
  317. }
  318. DWORD dwEndTime = ::GetTickCount();
  319. m_aveRedrawScreenTime.AddValue(::labs(dwEndTime - dwStartTime));
  320. //TRACE(_T("aveRedrawScreenTime = %d ms n"), (int)m_aveRedrawScreenTime.GetAverageValue(0));
  321. }
  322. AFX_STATIC void AFX_CDECL XTPSECollapsedBlockDeleteFn(void* pPtr)
  323. {
  324. XTP_EDIT_COLLAPSEDBLOCK* pBlock = (XTP_EDIT_COLLAPSEDBLOCK*)pPtr;
  325. SAFE_DELETE(pBlock);
  326. }
  327. void CXTPSyntaxEditCtrl::Draw(CDC *pDC, const CRect& rcRect)
  328. {
  329. ASSERT(pDC);
  330. if (!pDC)
  331. return;
  332. pDC->SetBkMode(TRANSPARENT);
  333. // calculate rects
  334. CRect rcBookMarks, rcLineNum, rcNodes, rcText;
  335. CalcEditRects(&rcBookMarks, &rcLineNum, &rcNodes, &rcText, &rcRect);
  336. // set text rect
  337. m_DrawTextProcessor.SetTextRect(rcText);
  338. m_DrawTextProcessor.SetTabSize(GetTabSize());
  339. // Set Row Height
  340. m_DrawTextProcessor.RecalcRowHeight(pDC, GetPaintManager()->GetFont());
  341. //--------------------------------------------------
  342. m_fcCollapsable.Update(m_nTopRow);
  343. m_fcRowColors.Update(m_nTopRow);
  344. //-------------------
  345. int nRowHeight = max(1, m_DrawTextProcessor.GetRowHeight());
  346. int nLinesCount = rcRect.Height() / nRowHeight + ((rcRect.Height() % nRowHeight) ? 1 : 0);
  347. int nSkipLines = 0;
  348. m_nCollapsedTextRowsCount = 0;
  349. for (int nLine = 0; nLine < nLinesCount;)
  350. {
  351. int nTextRow = m_nTopRow + nLine + nSkipLines;
  352. int nCollapsedRowsCount = 0;
  353. DWORD dwCollapcedType = ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount);
  354. nSkipLines += nCollapsedRowsCount;
  355. //if (nCollapsedRowsCount)
  356. //  continue;
  357. // save current row colors to restore after drawing (because DrawLineMarks may change it).
  358. COLORREF clrFont = 0, crBack = 0;
  359. clrFont = GetRowColor(nTextRow);
  360. crBack = GetRowBkColor(nTextRow);
  361. // Draw Line attributes (bookmark, number, node)
  362. int nLineY0 = rcRect.top + m_DrawTextProcessor.GetRowHeight() * nLine;
  363. int nLineY1 = nLineY0 + m_DrawTextProcessor.GetRowHeight();
  364. if (GetSelMargin())
  365. {
  366. CRect rcLMark(rcBookMarks);
  367. rcLMark.top = nLineY0;
  368. rcLMark.bottom = nLineY1;
  369. GetPaintManager()->DrawLineMarks(pDC, rcLMark, nTextRow, this);
  370. }
  371. if (GetLineNumbers())
  372. {
  373. CRect rcLNum(rcLineNum);
  374. rcLNum.top = nLineY0;
  375. rcLNum.bottom = nLineY1;
  376. GetPaintManager()->DrawLineNumber(pDC, rcLNum, nTextRow, this);
  377. }
  378. if (m_bDrawNodes)
  379. {
  380. CRect rcNode, rcNodeFull;
  381. GetLineNodeRect(nLine, rcNode, &rcNodeFull);
  382. GetPaintManager()->DrawLineNode(pDC, rcNode, rcNodeFull, dwCollapcedType, nTextRow, this);
  383. }
  384. else
  385. {
  386. CRect rcGap(rcLineNum);
  387. rcGap.top = nLineY0;
  388. rcGap.bottom = nLineY1;
  389. rcGap.left = rcLineNum.right;
  390. rcGap.right = rcText.left;
  391. pDC->FillSolidRect(&rcGap, GetPaintManager()->GetBackColorEx(this));
  392. }
  393. // D R A W    T E X T /////////////////////////////////////////////
  394. CRect rcTextLine(rcText);
  395. rcTextLine.top = nLineY0;
  396. rcTextLine.bottom = nLineY1;
  397. GetPaintManager()->DrawLineTextEx(pDC, rcTextLine, nTextRow, nLine, this);
  398. SetRowColor(nTextRow, clrFont);
  399. SetRowBkColor(nTextRow, crBack);
  400. nLine++;
  401. }
  402. //---------------------------------------------------------------------------
  403. GetPaintManager()->DrawCollapsedTextMarks(this, pDC);
  404. //---------------------------------------------------------------------------
  405. }
  406. int CXTPSyntaxEditCtrl::PrintPage(CDC *pDC, const CRect& rcRect, int nFlags) // returns printed rows count
  407. {
  408. int nPrintedRowsCount = 0;
  409. ASSERT(pDC);
  410. if (!pDC)
  411. return 0;
  412. BOOL bSelMargin_orig = m_bSelMargin;
  413. m_bSelMargin = FALSE;
  414. CalculateEditbarLength(pDC);
  415. pDC->SetBkMode(TRANSPARENT);
  416. // calculate rects
  417. CRect rcBookMarks, rcLineNum, rcNodes, rcText;
  418. CalcEditRects(&rcBookMarks, &rcLineNum, &rcNodes, &rcText, &rcRect);
  419. // set text rect
  420. m_DrawTextProcessor.SetTextRect(rcText);
  421. m_DrawTextProcessor.SetTabSize(GetTabSize());
  422. // Set Row Height
  423. m_DrawTextProcessor.RecalcRowHeight(pDC, GetPaintManager()->GetFont());
  424. //--------------------------------------------------
  425. m_fcCollapsable.Update(m_nTopRow);
  426. m_fcRowColors.Update(m_nTopRow);
  427. //-------------------
  428. int nRowHeight = max(1, m_DrawTextProcessor.GetRowHeight());
  429. int nLinesCount = rcRect.Height() / nRowHeight + ((rcRect.Height() % nRowHeight) ? 1 : 0);
  430. int nSkipLines = 0;
  431. m_nCollapsedTextRowsCount = 0;
  432. int nNextLineY = 0;
  433. for (int nLine = 0;
  434.  nLine < nLinesCount && nNextLineY + nRowHeight < rcText.Height();
  435.  nPrintedRowsCount++)
  436. {
  437. int nTextRow = m_nTopRow + nLine + nSkipLines;
  438. int nCollapsedRowsCount = 0;
  439. ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount);
  440. nSkipLines += nCollapsedRowsCount;
  441. //      if (nCollapsedRowsCount)
  442. //          continue;
  443. // save current row colors to restore after drawing (because DrawLineMarks may change it).
  444. COLORREF clrFont = 0, crBack = 0;
  445. //BOOL bSwitchColor = !pDC->IsPrinting();// && GetSelMargin(); to show breakpoints even if selection margin unchecked
  446. clrFont = GetRowColor(nTextRow);
  447. crBack = GetRowBkColor(nTextRow);
  448. // Draw Line attributes (bookmark, number, node)
  449. int nLineY0 = rcRect.top + nNextLineY; //m_DrawTextProcessor.GetRowHeight() * nLine;
  450. int nLineY1 = nLineY0 + m_DrawTextProcessor.GetRowHeight();
  451. CRect rcTextLine(rcText);
  452. rcTextLine.top = nLineY0;
  453. rcTextLine.bottom = nLineY1;
  454. // calculate is enough vertical space to print all line text
  455. int nLineHeight = GetPaintManager()->PrintLineTextEx(pDC, rcTextLine, nTextRow, nLine,
  456. this, nFlags);
  457. if (nLineHeight < 0)
  458. break;
  459. //      if (GetSelMargin())
  460. //      {
  461. //          CRect rcLMark(rcBookMarks);
  462. //          rcLMark.top = nLineY0;
  463. //          rcLMark.bottom = nLineY1;
  464. //          GetPaintManager()->DrawLineMarks(pDC, rcLMark, nTextRow, this);
  465. //      }
  466. if (GetLineNumbers() && (nFlags & DT_CALCRECT) == 0)
  467. {
  468. CRect rcLNum(rcLineNum);
  469. rcLNum.top = nLineY0;
  470. rcLNum.bottom = nLineY1;
  471. GetPaintManager()->DrawLineNumber(pDC, rcLNum, nTextRow, this);
  472. }
  473. //      if (m_bDrawNodes)
  474. //      {
  475. //          CRect rcNode, rcNodeFull;
  476. //          GetLineNodeRect(nLine, rcNode, &rcNodeFull);
  477. //          GetPaintManager()->DrawLineNode(pDC, rcNode, rcNodeFull, dwCollapcedType, this);
  478. //      }
  479. // D R A W    T E X T /////////////////////////////////////////////
  480. //      if ((nFlags & DT_CALCRECT) == 0)
  481. //          nLineHeight = GetPaintManager()->PrintLineTextEx(pDC, rcTextLine, nTextRow,
  482. //                          nLine, this, nFlags);
  483. nNextLineY += nLineHeight;
  484. SetRowColor(nTextRow, clrFont);
  485. SetRowBkColor(nTextRow, crBack);
  486. nLine++;
  487. }
  488. //---------------------------------------------------------------------------
  489. GetPaintManager()->DrawCollapsedTextMarks(this, pDC);
  490. //---------------------------------------------------------------------------
  491. m_bSelMargin = bSelMargin_orig;
  492. return nPrintedRowsCount;
  493. }
  494. void CXTPSyntaxEditCtrl::UpdateRowInfoInternally(int nTextRow)
  495. {
  496. CClientDC wndDC(this);
  497. CDC memDC;
  498. memDC.CreateCompatibleDC(&wndDC);
  499. int nDispRow = GetVisibleRow(nTextRow) - 1;
  500. if (nDispRow > m_DrawTextProcessor.GetRowsCount(TRUE) + 10)
  501. nDispRow = m_DrawTextProcessor.GetRowsCount(TRUE) + 10;
  502. CRect rcTextLine;
  503. CalcEditRects(NULL, NULL, NULL, &rcTextLine);
  504. int nCollapsedRowsCount = 0;
  505. ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount); // to update collapsed block info.
  506. GetPaintManager()->DrawLineTextEx(&memDC, rcTextLine, nTextRow, nDispRow, this);
  507. }
  508. DWORD CXTPSyntaxEditCtrl::ProcessCollapsedRowsBeroreDraw(int nTextRow, int& rnSkipRowsCount)
  509. {
  510. rnSkipRowsCount = 0;
  511. if (nTextRow > GetRowCount())
  512. return XTP_EDIT_ROWNODE_NOTHING;
  513. XTP_EDIT_LMPARAM LMCoParam;
  514. BOOL bIsRowCollapsed = HasRowMark(nTextRow, xtpEditLMT_Collapsed, &LMCoParam);
  515. // retrieve row nodes
  516. CXTPSyntaxEditRowsBlockArray arCoBlocks;
  517. DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
  518. GetCollapsableBlocksInfo(nTextRow, arCoBlocks);
  519. BOOL bCollapsedProcessed = FALSE;
  520. int nCount = (int)arCoBlocks.GetSize();
  521. //-----------------------------------------
  522. if (bIsRowCollapsed && nCount == 0)
  523. {
  524. GetLineMarksManager()->DeleteLineMark(nTextRow, xtpEditLMT_Collapsed);
  525. }
  526. //-----------------------------------------
  527. for (int i = 0; i < nCount; i++)
  528. {
  529. XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
  530. if (coBlk.lcStart.nLine == nTextRow)
  531. {
  532. if (bIsRowCollapsed && !bCollapsedProcessed)
  533. {
  534. XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk;
  535. pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
  536. if (!pCoDrawBlk)
  537. {
  538. pCoDrawBlk = new XTP_EDIT_COLLAPSEDBLOCK;
  539. LMCoParam.SetPtr(pCoDrawBlk, XTPSECollapsedBlockDeleteFn);
  540. }
  541. pCoDrawBlk->collBlock = coBlk;
  542. GetLineMarksManager()->SetLineMark(nTextRow,
  543. xtpEditLMT_Collapsed, &LMCoParam);
  544. m_arCollapsedTextRows.SetAtGrow(m_nCollapsedTextRowsCount, nTextRow);
  545. m_nCollapsedTextRowsCount++;
  546. bCollapsedProcessed = TRUE;
  547. rnSkipRowsCount = max(1, coBlk.lcEnd.nLine - coBlk.lcStart.nLine);
  548. dwType |= XTP_EDIT_ROWNODE_COLLAPSED;
  549. }
  550. else
  551. {
  552. dwType |= XTP_EDIT_ROWNODE_EXPANDED;
  553. }
  554. }
  555. BOOL bLastLineEnd = coBlk.lcEnd.nLine > nTextRow && nTextRow == GetRowCount();
  556. if (coBlk.lcEnd.nLine == nTextRow || bLastLineEnd)
  557. {
  558. dwType |= XTP_EDIT_ROWNODE_ENDMARK;
  559. }
  560. if (coBlk.lcStart.nLine < nTextRow)
  561. {
  562. dwType |= XTP_EDIT_ROWNODE_NODEUP;
  563. }
  564. if (coBlk.lcEnd.nLine > nTextRow && !bCollapsedProcessed && !bLastLineEnd)
  565. {
  566. dwType |= XTP_EDIT_ROWNODE_NODEDOWN;
  567. }
  568. // check whether to skip the row
  569. if ((coBlk.lcStart.nLine < nTextRow) &&
  570. (coBlk.lcEnd.nLine >= nTextRow))
  571. {
  572. if (HasRowMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed))
  573. {
  574. rnSkipRowsCount = max(1, coBlk.lcEnd.nLine - nTextRow);
  575. }
  576. }
  577. }
  578. return dwType;
  579. }
  580. CRect CXTPSyntaxEditCtrl::CalcEditRects(CRect* prcBookMarks, CRect* prcLineNum, CRect* prcNodes, CRect* prcText,
  581. const CRect* prcClient)
  582. {
  583. CRect rcClient(0, 0, 100, 100);
  584. if (prcClient)
  585. rcClient = *prcClient;
  586. else if (m_hWnd)
  587. GetClientRect(&rcClient);
  588. // calculate rects
  589. CRect rcBookMarks = rcClient;
  590. rcBookMarks.right = rcBookMarks.left + (GetSelMargin() ? m_nMarginLength : 0);
  591. CRect rcLineNum = rcClient;
  592. rcLineNum.left = rcBookMarks.right;
  593. rcLineNum.right = rcLineNum.left + (GetLineNumbers() ? m_nLineNumLength : 0);
  594. CRect rcNodes = rcClient;
  595. rcNodes.left = rcLineNum.right;
  596. rcNodes.right = rcNodes.left + (m_bDrawNodes ? m_nNodesWidth : 0);
  597. CRect rcText = rcClient;
  598. rcText.left += m_nEditbarLength;
  599. //--------------------------------------------
  600. if (prcBookMarks)
  601. *prcBookMarks = rcBookMarks;
  602. if (prcLineNum)
  603. *prcLineNum = rcLineNum;
  604. if (prcNodes)
  605. *prcNodes = rcNodes;
  606. if (prcText)
  607. *prcText = rcText;
  608. return rcClient;
  609. }
  610. BOOL CXTPSyntaxEditCtrl::RegisterWindowClass(HINSTANCE hInstance /*= NULL*/)
  611. {
  612. return XTPDrawHelpers()->RegisterWndClass(hInstance,
  613. XTP_EDIT_CLASSNAME_EDITCTRL, CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS);
  614. }
  615. BOOL CXTPSyntaxEditCtrl::PreCreateWindow(CREATESTRUCT& )
  616. {
  617. m_bWndCreateInProgress = TRUE;
  618. return TRUE;
  619. }
  620. void CXTPSyntaxEditCtrl::PreSubclassWindow()
  621. {
  622. if (!m_bWndCreateInProgress)
  623. {
  624. // process only for SubclassWindow call
  625. DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
  626. m_bVertScrollBar = 0 != (dwStyle & WS_VSCROLL);
  627. m_bHorzScrollBar = 0 != (dwStyle & WS_HSCROLL);
  628. m_pParentWnd = GetParent();
  629. _InitEditControl();
  630. }
  631. }
  632. int CXTPSyntaxEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  633. {
  634. TRACE(_T("CXTPSyntaxEditCtrl::OnCreate() - %d n"), ::GetTickCount());
  635. m_bWndCreateInProgress = FALSE;
  636. if (CWnd::OnCreate(lpCreateStruct) == -1)
  637. return -1;
  638. if (!_InitEditControl())
  639. return -1;
  640. return 0;
  641. }
  642. void CXTPSyntaxEditCtrl::OnDestroy()
  643. {
  644. //TRACE(_T("CXTPSyntaxEditCtrl::OnDestroy() - %d nn"), ::GetTickCount());
  645. if (m_pToolTip->GetSafeHwnd())
  646. m_pToolTip->DestroyWindow();
  647. if (m_pAutoComplete->GetSafeHwnd())
  648. m_pAutoComplete->DestroyWindow();
  649. m_Sink.UnadviseAll();
  650. CWnd::OnDestroy();
  651. }
  652. BOOL CXTPSyntaxEditCtrl::Create(CWnd* pParentWnd, BOOL bHorzScroll, BOOL bVertScroll,
  653. CXTPSyntaxEditBufferManager *pBuffer,
  654. CCreateContext *lpCS, UINT nID)
  655. {
  656. if (pBuffer)
  657. {
  658. CMDTARGET_ADDREF(pBuffer);
  659. CMDTARGET_RELEASE(m_pBuffer);
  660. m_pBuffer = pBuffer;
  661. }
  662. //-------------------------------------------
  663. m_bVertScrollBar = bVertScroll;
  664. m_bHorzScrollBar = bHorzScroll;
  665. DWORD dwStyle = (WS_CHILD | WS_VISIBLE);
  666. if (m_bVertScrollBar && !IsCreateScrollbarOnParent())
  667. dwStyle |= WS_VSCROLL;
  668. if (m_bHorzScrollBar && !IsCreateScrollbarOnParent())
  669. dwStyle |= WS_HSCROLL;
  670. //-------------------------------------------
  671. ASSERT_VALID(pParentWnd); // must be valid.
  672. m_pParentWnd = pParentWnd;
  673. BOOL bCreate = CWnd::CreateEx(WS_EX_ACCEPTFILES, XTP_EDIT_CLASSNAME_EDITCTRL, NULL,
  674. dwStyle, CRect(0, 0, 100, 100), m_pParentWnd, nID, (LPVOID)lpCS);
  675. if (!bCreate)
  676. {
  677. TRACE0("Failed to create edit window.n");
  678. }
  679. return bCreate;
  680. }
  681. BOOL CXTPSyntaxEditCtrl::_InitEditControl()
  682. {
  683. // create tip window
  684. VERIFY(m_pToolTip->Create(this));
  685. // Create AutoComplete window.
  686. VERIFY(m_pAutoComplete->Create(this));
  687. CRect rcText(0, 0, 3000, 2000);
  688. m_DrawTextProcessor.SetTextRect(rcText);
  689. m_DrawTextProcessor.SetTabSize(GetTabSize());
  690. // create data manager if need
  691. if (!m_pBuffer)
  692. m_pBuffer = new CXTPSyntaxEditBufferManager;
  693. if (!m_pBuffer)
  694. return FALSE;
  695. if (GetConfigFile().IsEmpty())
  696. {
  697. CString csCfgFilePath = GetDefaultCfgFilePath();
  698. if (!SetConfigFile(csCfgFilePath))
  699. {
  700. TRACE1("n*** Could not locate config file '%s'.nn", (LPCTSTR)csCfgFilePath);
  701. }
  702. }
  703. _UpdateIMEStatus();
  704. SetCurCaretPos(1, 1, FALSE, FALSE);
  705. // Advise to events
  706. m_Sink.UnadviseAll();
  707. CXTPNotifyConnection* ptrConnParser = m_pBuffer->GetLexParser()->GetConnection();
  708. ASSERT(ptrConnParser);
  709. if (ptrConnParser)
  710. {
  711. m_Sink.Advise(ptrConnParser, xtpEditOnParserStarted, &CXTPSyntaxEditCtrl::OnParseEvent);
  712. m_Sink.Advise(ptrConnParser, xtpEditOnTextBlockParsed, &CXTPSyntaxEditCtrl::OnParseEvent);
  713. m_Sink.Advise(ptrConnParser, xtpEditOnParserEnded, &CXTPSyntaxEditCtrl::OnParseEvent);
  714. }
  715. CXTPNotifyConnection* ptrConnBufMan = m_pBuffer->GetConnection();
  716. ASSERT(ptrConnBufMan);
  717. if (ptrConnBufMan)
  718. {
  719. m_Sink.Advise(ptrConnBufMan, xtpEditClassSchWasChanged, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged);
  720. m_Sink.Advise(ptrConnBufMan, xtpEditThemeWasChanged, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged);
  721. m_Sink.Advise(ptrConnBufMan, xtpEditAllConfigWasChanged, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged);
  722. }
  723. return TRUE;
  724. }
  725. UINT CXTPSyntaxEditCtrl::OnGetDlgCode()
  726. {
  727. return DLGC_WANTTAB | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTALLKEYS;
  728. }
  729. BOOL CXTPSyntaxEditCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  730. {
  731. UNREFERENCED_PARAMETER(pWnd);
  732. UNREFERENCED_PARAMETER(nHitTest);
  733. UNREFERENCED_PARAMETER(message);
  734. CPoint pt;
  735. ::GetCursorPos(&pt);
  736. ScreenToClient(&pt);
  737. CXTPClientRect rcClient(this);
  738. CRect rcText(rcClient);
  739. rcText.left += m_nEditbarLength;
  740. CRect rcBookmark(0, 0, GetSelMargin() ? m_nMarginLength : 0, rcClient.Height());
  741. CRect rcLineNumAndNodes(rcBookmark.right, 0, m_nEditbarLength, rcClient.Height());
  742. CXTPEmptyRect rcNode;
  743. int nRow = 0, nCol = 0, nDispRow = 0;
  744. RowColFromPoint(pt, &nRow, &nCol, &nDispRow);
  745. if (m_bDrawNodes)
  746. {
  747. // calculate node icon rect
  748. DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
  749. if (GetRowNodes(nRow, dwType) && (dwType & (XTP_EDIT_ROWNODE_COLLAPSED | XTP_EDIT_ROWNODE_EXPANDED)) )
  750. {
  751. GetLineNodeRect(nDispRow-1, rcNode);
  752. }
  753. }
  754. if (m_bDragging)
  755. {
  756. if (rcClient.PtInRect(pt))
  757. {
  758. if ((::GetKeyState(VK_CONTROL) & KF_UP) == 0)
  759. {
  760. SetCursor(GetPaintManager()->GetCurMove());
  761. return TRUE;
  762. }
  763. else
  764. {
  765. SetCursor(GetPaintManager()->GetCurCopy());
  766. return TRUE;
  767. }
  768. }
  769. else
  770. {
  771. SetCursor(GetPaintManager()->GetCurNO());
  772. return TRUE;
  773. }
  774. }
  775. else if (rcText.PtInRect(pt))
  776. {
  777. if (m_Selection.IsInSel_str(nRow, nCol-1) && !m_Selection.bSelectingRunning
  778. || m_bRightButtonDrag)
  779. {
  780. SetCursor(GetPaintManager()->GetCurArrow());
  781. return TRUE;
  782. }
  783. else
  784. {
  785. if (!GetBlockFromPt(pt))
  786. {
  787. SetCursor(GetPaintManager()->GetCurIBeam());
  788. return TRUE;
  789. }
  790. }
  791. }
  792. else if (rcBookmark.PtInRect(pt))
  793. {
  794. SetCursor(GetPaintManager()->GetCurArrow());
  795. return TRUE;
  796. }
  797. else if (rcNode.PtInRect(pt))
  798. {
  799. SetCursor(GetPaintManager()->GetCurArrow());
  800. return TRUE;
  801. }
  802. else if (rcLineNumAndNodes.PtInRect(pt))
  803. {
  804. SetCursor(GetPaintManager()->GetCurLine());
  805. return TRUE;
  806. }
  807. SetCursor(GetPaintManager()->GetCurArrow());
  808. return TRUE;
  809. }
  810. LRESULT CXTPSyntaxEditCtrl::OnSetText(WPARAM wParam, LPARAM lParam)
  811. {
  812. UNREFERENCED_PARAMETER(wParam);
  813. LPCTSTR szText = (LPCTSTR)lParam;
  814. SetText(szText);
  815. return (LRESULT)TRUE;
  816. }
  817. LRESULT CXTPSyntaxEditCtrl::OnGetTextLen(WPARAM, LPARAM)
  818. {
  819. if (!GetEditBuffer())
  820. return 0;
  821. int nTextSize = 0;
  822. int nRowsCount = GetRowCount();
  823. for (int i = 1; i <= nRowsCount; i++)
  824. {
  825. nTextSize += GetEditBuffer()->GetLineTextLength(i, i < nRowsCount);
  826. }
  827. return (LRESULT)nTextSize;
  828. }
  829. LRESULT CXTPSyntaxEditCtrl::OnGetText(WPARAM wBufferSize, LPARAM lpBuffer)
  830. {
  831. if (wBufferSize == 0)
  832. return OnGetTextLen(0, 0);
  833. CMemFile memFile;
  834. if (!GetText(memFile, (int)wBufferSize))
  835. return 0;
  836. void* pTextData = NULL;
  837. void* pTextEnd = NULL;
  838. UINT uBufferB = memFile.GetBufferPtr(CFile::bufferRead, (UINT)wBufferSize, &pTextData, &pTextEnd);
  839. LPTSTR pDest = (LPTSTR)lpBuffer;
  840. STRNCPY_S(pDest, wBufferSize, (LPCTSTR)pTextData, wBufferSize);
  841. pDest[wBufferSize-1] = _T('');
  842. int nTextSize = (int)uBufferB/sizeof(TCHAR) - sizeof(TCHAR);
  843. nTextSize = max(0, nTextSize);
  844. nTextSize = min(nTextSize, (int)wBufferSize);
  845. //ASSERT(nTextSize == (int)_tcslen(pDest));
  846. return (LRESULT)nTextSize;
  847. }
  848. CString CXTPSyntaxEditCtrl::GetText(int nMaxLen)
  849. {
  850. CMemFile memFile;
  851. if (!GetText(memFile, nMaxLen))
  852. return _T("");
  853. void* pTextData = NULL;
  854. void* pTextEnd = NULL;
  855. memFile.GetBufferPtr(CFile::bufferRead, (UINT)nMaxLen, &pTextData, &pTextEnd);
  856. if (pTextEnd)
  857. {
  858. TCHAR* pEnd = (TCHAR*)pTextEnd;
  859. *(pEnd - 1) = _T('');
  860. }
  861. return CString((LPCTSTR)pTextData);
  862. }
  863. BOOL CXTPSyntaxEditCtrl::GetText(CMemFile& memFile, int nMaxLen)
  864. {
  865. if (!GetEditBuffer())
  866. return FALSE;
  867. CArchive ar(&memFile, CArchive::store);
  868. BOOL bUnicode = (sizeof(TCHAR) == 2);
  869. if (nMaxLen > 0)
  870. nMaxLen = nMaxLen * sizeof(TCHAR);
  871. GetEditBuffer()->SerializeEx(ar, bUnicode, FALSE, (UINT)-1, NULL, nMaxLen);
  872. ar << (TCHAR)0;
  873. ar.Close();
  874. memFile.SeekToBegin();
  875. return TRUE;
  876. }
  877. void CXTPSyntaxEditCtrl::SetText(LPCTSTR pcszText)
  878. {
  879. if (!GetEditBuffer() || !pcszText)
  880. {
  881. ASSERT(FALSE);
  882. return;
  883. }
  884. int nStrLenB = (int)_tcslen(pcszText) * sizeof(TCHAR);
  885. CMemFile memFile((BYTE*)pcszText, nStrLenB);
  886. memFile.SeekToBegin();
  887. CArchive ar(&memFile, CArchive::load);
  888. BOOL bUnicode = (sizeof(TCHAR) == 2);
  889. GetEditBuffer()->SerializeEx(ar, bUnicode);
  890. //---------------------------------------
  891. RefreshColors();
  892. RecalcScrollBars();
  893. Invalidate(FALSE);
  894. }
  895. void CXTPSyntaxEditCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  896. {
  897. UNREFERENCED_PARAMETER(pScrollBar); UNREFERENCED_PARAMETER(nPos);
  898. SCROLLINFO info;
  899. ZeroMemory(&info, sizeof(SCROLLINFO));
  900. info.cbSize = sizeof(SCROLLINFO);
  901. info.fMask = SIF_ALL;
  902. GetScrollInfo(SB_HORZ, &info);
  903. int nStep = m_DrawTextProcessor.GetTextMetrics().tmAveCharWidth;
  904. int nCurrPos = m_DrawTextProcessor.GetScrollXOffset(); //GetScrollPos(SB_HORZ);
  905. switch(nSBCode)
  906. {
  907. case SB_LINELEFT:
  908. nCurrPos -= nStep;
  909. break;
  910. case SB_LINERIGHT:
  911. nCurrPos += nStep;
  912. break;
  913. case SB_PAGELEFT:
  914. nCurrPos -= info.nPage;
  915. break;
  916. case SB_PAGERIGHT:
  917. nCurrPos += info.nPage;
  918. break;
  919. case SB_LEFT:
  920. nCurrPos = info.nMin;
  921. break;
  922. case SB_RIGHT:
  923. nCurrPos = info.nMax;
  924. case SB_ENDSCROLL:
  925. return;
  926. case SB_THUMBPOSITION:
  927. case SB_THUMBTRACK:
  928. {
  929. nCurrPos = nPos;
  930. int nDelta = ((nCurrPos % nStep) >= nStep/2 ? 1 : 0);
  931. nCurrPos = (nCurrPos / nStep + nDelta) * nStep;
  932. ASSERT(nCurrPos <= info.nMax);
  933. }
  934. break;
  935. default:
  936. break;
  937. }
  938. nCurrPos = max(0, nCurrPos);
  939. SetScrollPos(SB_HORZ, nCurrPos);
  940. m_DrawTextProcessor.SetScrollXOffset(nCurrPos);
  941. if (m_bFocused)
  942. {
  943. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
  944. }
  945. Invalidate(FALSE);
  946. UpdateWindow();
  947. }
  948. void CXTPSyntaxEditCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  949. {
  950. UNREFERENCED_PARAMETER(nPos);
  951. UNREFERENCED_PARAMETER(pScrollBar);
  952. SCROLLINFO info;
  953. ZeroMemory(&info, sizeof(SCROLLINFO));
  954. info.cbSize = sizeof(SCROLLINFO);
  955. info.fMask = SIF_ALL;
  956. GetScrollInfo(SB_VERT, &info);
  957. int iMin = 0, iMax = 0;
  958. GetScrollRange(SB_VERT, &iMin, &iMax);
  959. int iPos = GetScrollPos(SB_VERT);
  960. BOOL bChanged = FALSE;
  961. switch(nSBCode) {
  962. case SB_LINEDOWN:
  963. bChanged = ShiftCurrentVisibleRowDown(1);
  964. if (bChanged)
  965. SetScrollPos(SB_VERT, iPos + 1);
  966. break;
  967. case SB_LINEUP:
  968. bChanged = ShiftCurrentVisibleRowUp(1);
  969. if (bChanged)
  970. SetScrollPos(SB_VERT, iPos - 1);
  971. break;
  972. case SB_PAGEUP:
  973. bChanged = ShiftCurrentVisibleRowUp(info.nPage);
  974. if (bChanged)
  975. SetScrollPos(SB_VERT, max(1, iPos - info.nPage));
  976. break;
  977. case SB_PAGEDOWN:
  978. bChanged = ShiftCurrentVisibleRowDown(info.nPage);
  979. if (bChanged)
  980. SetScrollPos(SB_VERT, (iPos + info.nPage));
  981. break;
  982. case SB_TOP:
  983. SetScrollPos(SB_VERT, iMin);
  984. SetCurrentDocumentRow(iMin);
  985. m_nCurrentCol = m_nDispCol = 1;
  986. bChanged = TRUE;
  987. break;
  988. case SB_BOTTOM:
  989. SetScrollPos(SB_VERT, iMax);
  990. SetCurrentDocumentRow(iMax);
  991. m_nCurrentCol = m_nDispCol = 1;
  992. bChanged = TRUE;
  993. break;
  994. case SB_THUMBTRACK:
  995. {
  996. SCROLLINFO si;
  997. ZeroMemory(&si, sizeof(SCROLLINFO));
  998. si.cbSize = sizeof(SCROLLINFO);
  999. si.fMask = SIF_TRACKPOS;
  1000. if (GetScrollInfo(SB_VERT, &si))
  1001. {
  1002. int nShift = si.nTrackPos - GetVisibleRowsCount(m_nTopRow);
  1003. if (nShift > 0)
  1004. {
  1005. bChanged = ShiftCurrentVisibleRowDown(nShift);
  1006. }
  1007. else if (nShift < 0)
  1008. {
  1009. bChanged = ShiftCurrentVisibleRowUp(-nShift);
  1010. }
  1011. SetScrollPos(SB_VERT, si.nTrackPos);
  1012. }
  1013. }
  1014. break;
  1015. case SB_ENDSCROLL:
  1016. return;
  1017. default:
  1018. break;
  1019. }
  1020. int nTopDocRow = GetDocumentRow(1);
  1021. int nBottomDocRow = GetDocumentRow(GetRowPerPage());
  1022. int nCurDocRow = GetCurrentDocumentRow();
  1023. if (nCurDocRow >= nTopDocRow && nCurDocRow <= nBottomDocRow)
  1024. {
  1025. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
  1026. }
  1027. if (bChanged)
  1028. {
  1029. Invalidate(FALSE);
  1030. UpdateWindow();
  1031. }
  1032. RecalcScrollBars();
  1033. }
  1034. void CXTPSyntaxEditCtrl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1035. {
  1036. CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
  1037. #ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
  1038. if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, TRUE, nChar))
  1039. return;
  1040. #endif
  1041. if (nChar == 0)
  1042. {
  1043. return;
  1044. }
  1045. CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
  1046. }
  1047. void CXTPSyntaxEditCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1048. {
  1049. CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
  1050. #ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
  1051. if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, TRUE, nChar))
  1052. return;
  1053. #endif
  1054. if (nChar == 0)
  1055. {
  1056. return;
  1057. }
  1058. m_pToolTip->Hide();
  1059. if (m_bDragging || m_bRightButtonDrag || m_Selection.bSelectingRunning /* || m_bSelectionStarted*/)
  1060. {
  1061. OnSetCursor(0,0,0);
  1062. return;
  1063. }
  1064. BOOL bCtrlKey  = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
  1065. BOOL bShiftKey  = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
  1066. BOOL bUpdateAll = FALSE;
  1067. int nTopRow_prev = m_nTopRow;
  1068. int nDispCol_prev = m_nDispCol;
  1069. int nTextRow_prev = GetCurrentDocumentRow();
  1070. int nRowCount_prev = GetRowCount();
  1071. CXTPSyntaxEditSelection selData_prev = m_Selection;
  1072. switch(nChar)
  1073. {
  1074. case VK_UP:
  1075. m_nAutoIndentCol = 0;
  1076. if (GetCurrentDocumentRow() < 1)
  1077. {
  1078. // Do nothing
  1079. }
  1080. else if (bCtrlKey)
  1081. {
  1082. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol) ;
  1083. ShiftCurrentVisibleRowUp(1, TRUE);
  1084. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
  1085. }
  1086. else if (GetCurrentDocumentRow() >= 1)
  1087. {
  1088. if (!m_Selection.IsSelExist())
  1089. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1090. if (!bShiftKey)
  1091. {
  1092. m_Selection.Reset_disp(m_Selection.GetNormalStart_disp().nLine,
  1093.    m_nDispCol); //m_Selection.GetNormalEnd_disp().nCol);
  1094. SetCurCaretPos(m_Selection.GetNormalStart_disp().nLine,
  1095.    m_Selection.GetNormalEnd_disp().nCol, FALSE);
  1096. }
  1097. MoveCurrentVisibleRowUp(1);
  1098. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
  1099. if (bShiftKey)
  1100. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1101. else
  1102. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1103. }
  1104. break;
  1105. case VK_DOWN:
  1106. m_nAutoIndentCol = 0;
  1107. if (bCtrlKey)
  1108. {
  1109. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol) ;
  1110. ShiftCurrentVisibleRowDown(1, TRUE);
  1111. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
  1112. }
  1113. else if (GetCurrentDocumentRow() <= GetRowCount())
  1114. {
  1115. if (!m_Selection.IsSelExist())
  1116. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1117. if (!bShiftKey)
  1118. {
  1119. m_Selection.Reset_disp(m_Selection.GetNormalEnd_disp().nLine,
  1120.    m_nDispCol); //m_Selection.GetNormalEnd_disp().nCol);
  1121. SetCurCaretPos(m_Selection.GetNormalStart_str().nLine,
  1122.    m_Selection.GetNormalEnd_disp().nCol, FALSE, TRUE);
  1123. }
  1124. MoveCurrentVisibleRowDown(1);
  1125. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
  1126. if (bShiftKey)
  1127. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1128. else
  1129. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1130. }
  1131. break;
  1132. case VK_LEFT:
  1133. //      if (m_nAutoIndentCol > 0)
  1134. //      {
  1135. m_nAutoIndentCol = 0;
  1136. //          m_nCurrentCol = m_nDispCol = 1;
  1137. //          break;
  1138. //      }
  1139. if (!m_Selection.IsSelExist())
  1140. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1141. if (!bShiftKey && m_Selection.IsSelExist())
  1142. {
  1143. // move cursor to the selection begin
  1144. m_Selection.Reset_disp(m_Selection.GetNormalStart_disp().nLine,
  1145.    m_Selection.GetNormalStart_disp().nCol);
  1146. SetCurCaretPos(m_Selection.GetNormalStart_disp().nLine,
  1147.    m_Selection.GetNormalStart_disp().nCol, FALSE/*, FALSE*/);
  1148. break;
  1149. }
  1150. if (!bCtrlKey)
  1151. {
  1152. int nCurDocRow = GetCurrentDocumentRow();
  1153. if ((nCurDocRow > 1 && m_nCurrentCol >= 1) ||
  1154. (nCurDocRow == 1 && m_nCurrentCol > 1))
  1155. {
  1156. m_nCurrentCol--;
  1157. }
  1158. if (m_nCurrentCol < 1 && nCurDocRow > 1)
  1159. {
  1160. if (_IsVirtualSpaceActive())
  1161. m_nCurrentCol = 1;
  1162. else
  1163. MoveCurrentVisibleRowUp(1);
  1164. }
  1165. LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
  1166. if (m_nCurrentCol < 1)
  1167. m_nCurrentCol = (int)_tcsclen(szText) + 1;
  1168. m_nDispCol = CalcDispCol(szText, m_nCurrentCol);
  1169. }
  1170. else
  1171. {
  1172. // This will modify Current Row, m_nCurrentCol, m_nDispCol
  1173. FindWord(XTP_EDIT_FINDWORD_PREV);
  1174. }
  1175. if (bShiftKey)
  1176. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1177. else
  1178. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1179. break;
  1180. case VK_RIGHT:
  1181. m_nAutoIndentCol = 0;
  1182. if (!m_Selection.IsSelExist())
  1183. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1184. if (!bShiftKey && m_Selection.IsSelExist())
  1185. {
  1186. // move cursor to the end of the selection
  1187. m_Selection.Reset_disp(m_Selection.GetNormalEnd_disp().nLine,
  1188.    m_Selection.GetNormalEnd_disp().nCol);
  1189. SetCurCaretPos(m_Selection.GetNormalStart_str().nLine,
  1190.    m_Selection.GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
  1191. break;
  1192. }
  1193. if (!bCtrlKey)
  1194. {
  1195. int nCurDocRow = GetCurrentDocumentRow();
  1196. LPCTSTR szText = GetLineText(nCurDocRow);
  1197. const int nTextLen = (int)_tcsclen(szText);
  1198. if (m_nCurrentCol > nTextLen && (nCurDocRow < GetRowCount()) && !_IsVirtualSpaceActive())
  1199. {
  1200. MoveCurrentVisibleRowDown(1);
  1201. m_nCurrentCol = 1;
  1202. }
  1203. else if (m_nCurrentCol <= nTextLen || _IsVirtualSpaceActive())
  1204. {
  1205. m_nCurrentCol++;
  1206. }
  1207. m_nDispCol = CalcDispCol(szText, m_nCurrentCol);
  1208. }
  1209. else
  1210. {
  1211. FindWord(XTP_EDIT_FINDWORD_NEXT);
  1212. }
  1213. if (bShiftKey)
  1214. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1215. else
  1216. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1217. break;
  1218. case VK_HOME:
  1219. m_nAutoIndentCol = 0;
  1220. if (!m_Selection.IsSelExist())
  1221. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1222. if (!bShiftKey && m_Selection.IsSelExist())
  1223. {
  1224. // move cursor to the selection begin
  1225. m_Selection.Reset_disp(m_Selection.GetNormalStart_disp().nLine,
  1226.    m_Selection.GetNormalEnd_disp().nCol);
  1227. SetCurCaretPos(m_Selection.GetNormalStart_disp().nLine,
  1228.    m_Selection.GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
  1229. }
  1230. if (bCtrlKey)
  1231. {
  1232. SetCurrentDocumentRow(1);
  1233. EnsureVisibleRow(1);
  1234. SetCurCaretPos(1, 1, FALSE/*, FALSE*/);
  1235. }
  1236. else
  1237. {
  1238. LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
  1239. // find number of tabs and spaces from the left
  1240. int iCol = 1;
  1241. LPCTSTR szPtr = szText;
  1242. while (szPtr)
  1243. {
  1244. if (*szPtr == _T('t') || *szPtr == _T(' '))
  1245. iCol++;
  1246. else
  1247. break;
  1248. szPtr = _tcsinc(szPtr);
  1249. }
  1250. if (m_nCurrentCol == iCol)
  1251. {
  1252. //m_nCurrentCol = 1;
  1253. //m_nDispCol = 1;
  1254. SetCurCaretPos(GetCurrentDocumentRow(), 1, FALSE/*, FALSE*/);
  1255. }
  1256. else
  1257. {
  1258. m_nDispCol = CalcDispCol(szText, iCol);
  1259. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
  1260. }
  1261. }
  1262. if (bShiftKey)
  1263. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1264. else
  1265. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1266. break;
  1267. case VK_END:
  1268. {
  1269. m_nAutoIndentCol = 0;
  1270. if (!m_Selection.IsSelExist())
  1271. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1272. if (!bShiftKey && m_Selection.IsSelExist())
  1273. {
  1274. // move cursor to the end of the selection
  1275. m_Selection.Reset_disp(m_Selection.GetNormalEnd_disp().nLine,
  1276.    m_Selection.GetNormalEnd_disp().nCol);
  1277. SetCurCaretPos(m_Selection.GetNormalStart_str().nLine,
  1278.    m_Selection.GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
  1279. }
  1280. if (bCtrlKey)
  1281. {
  1282. SetCurrentDocumentRow(GetRowCount());
  1283. EnsureVisibleRow(GetRowCount());
  1284. }
  1285. LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
  1286. int nLenC = (int)_tcsclen(szText);
  1287. SetCurCaretPos(GetCurrentDocumentRow(), CalcDispCol(szText, nLenC + 1),
  1288. FALSE/*, FALSE*/);
  1289. }
  1290. if (bShiftKey)
  1291. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1292. else
  1293. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1294. break;
  1295. case VK_PRIOR:
  1296. m_nAutoIndentCol = 0;
  1297. {
  1298. if (!m_Selection.IsSelExist())
  1299. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1300. if (!bShiftKey && m_Selection.IsSelExist())
  1301. {
  1302. // move cursor to the selection begin
  1303. m_Selection.Reset_disp(m_Selection.GetNormalStart_disp().nLine,
  1304.    m_Selection.GetNormalEnd_disp().nCol);
  1305. SetCurCaretPos(m_Selection.GetNormalStart_disp().nLine,
  1306.    m_Selection.GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
  1307. }
  1308. int iRowPerPage = GetRowPerPage();
  1309. if ((m_nTopRow - iRowPerPage) < 1)
  1310. {
  1311. SetCurrentDocumentRow(1);
  1312. EnsureVisibleRow(1);
  1313. }
  1314. else
  1315. {
  1316. MoveCurrentVisibleRowUp(iRowPerPage);
  1317. }
  1318. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
  1319. if (bShiftKey)
  1320. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1321. else
  1322. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1323. }
  1324. break;
  1325. case VK_NEXT:
  1326. m_nAutoIndentCol = 0;
  1327. {
  1328. if (!m_Selection.IsSelExist())
  1329. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1330. if (!bShiftKey && m_Selection.IsSelExist())
  1331. {
  1332. // move cursor to the end of the selection
  1333. m_Selection.Reset_disp(m_Selection.GetNormalEnd_disp().nLine,
  1334.    m_Selection.GetNormalEnd_disp().nCol);
  1335. SetCurCaretPos(m_Selection.GetNormalStart_str().nLine,
  1336.    m_Selection.GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
  1337. }
  1338. int iRowPerPage = GetRowPerPage();
  1339. if ((m_nTopRow + iRowPerPage) > GetRowCount())
  1340. {
  1341. SetCurrentDocumentRow(GetRowCount());
  1342. EnsureVisibleRow(GetRowCount());
  1343. }
  1344. else
  1345. {
  1346. MoveCurrentVisibleRowDown(iRowPerPage);
  1347. }
  1348. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
  1349. if (bShiftKey)
  1350. m_Selection.SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
  1351. else
  1352. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1353. }
  1354. break;
  1355. case VK_DELETE:
  1356. {
  1357. BOOL bDeleted = TRUE;
  1358. if (m_Selection.IsSelExist() && !bCtrlKey)
  1359. {
  1360. bDeleted = DeleteSelection();
  1361. }
  1362. else if (!bCtrlKey)
  1363. {
  1364. if (GetAutoIndent() && m_nAutoIndentCol > 0)
  1365. {
  1366. CString strInsertText(
  1367. CString(_T('t'), m_nInsertTabCount) +
  1368. CString(_T(' '), m_nInsertSpaceCount));
  1369. int iNewDispCol = (m_nInsertTabCount * GetTabSize()) + m_nInsertSpaceCount + 1;
  1370. int iNewCol = m_nInsertTabCount + m_nInsertSpaceCount + 1;
  1371. //**----------------------
  1372. OnBeforeEditChanged(GetCurrentDocumentRow(), 1);
  1373. m_pBuffer->InsertText(strInsertText, GetCurrentDocumentRow(), 1);
  1374. OnEditChanged(GetCurrentDocumentRow(), 1, GetCurrentDocumentRow(), iNewCol, xtpEditActInsert);
  1375. //**----------------------
  1376. m_nCurrentCol = iNewCol;
  1377. m_nDispCol = iNewDispCol;
  1378. m_nAutoIndentCol = 0;
  1379. }
  1380. bDeleted = DeleteChar(GetCurrentDocumentRow(), m_nCurrentCol, xtpEditDelPosAfter);
  1381. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1382. }
  1383. else
  1384. {
  1385. BOOL bSelectionExist = m_Selection.IsSelExist();
  1386. int nDelFlags = 0;
  1387. if (bSelectionExist)
  1388. {
  1389. nDelFlags |= xtpEditForceRedraw;
  1390. DeleteSelection();
  1391. }
  1392. int iStartRow = GetCurrentDocumentRow();
  1393. int iStartCol = m_nCurrentCol;
  1394. FindWord(XTP_EDIT_FINDWORD_NEXT);
  1395. int iEndRow = GetCurrentDocumentRow();
  1396. int iEndCol = m_nCurrentCol;
  1397. DeleteBuffer(iStartRow, iStartCol, iEndRow, iEndCol, nDelFlags);
  1398. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1399. if (bSelectionExist)
  1400. m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
  1401. }
  1402. bUpdateAll = TRUE;
  1403. m_nAutoIndentCol = 0;
  1404. }
  1405. break;
  1406. case VK_BACK:
  1407. if (m_nAutoIndentCol > 0)
  1408. {
  1409. if (m_nInsertSpaceCount == 0)
  1410. m_nInsertTabCount--;
  1411. else
  1412. m_nInsertSpaceCount--;
  1413. if (m_nInsertTabCount || m_nInsertSpaceCount)
  1414. {
  1415. m_nAutoIndentCol = (m_nInsertTabCount * GetTabSize()) + m_nInsertSpaceCount + 1;
  1416. m_nDispCol = m_nAutoIndentCol;
  1417. }
  1418. else
  1419. {
  1420. m_nAutoIndentCol = 0;
  1421. m_nDispCol = 1;
  1422. }
  1423. }
  1424. else if (!bCtrlKey)
  1425. {
  1426. if (m_Selection.IsSelExist())
  1427. {
  1428. DeleteSelection();
  1429. }
  1430. else
  1431. {
  1432. DeleteChar(GetCurrentDocumentRow(), m_nCurrentCol, xtpEditDelPosBefore);
  1433. }
  1434. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1435. }
  1436. else
  1437. {
  1438. BOOL bSelectionExist = m_Selection.IsSelExist();
  1439. if (bSelectionExist)
  1440. {
  1441. DeleteSelection();
  1442. }
  1443. int iStartRow = GetCurrentDocumentRow();
  1444. int iStartCol = m_nCurrentCol;
  1445. FindWord(XTP_EDIT_FINDWORD_PREV);
  1446. int iEndRow = GetCurrentDocumentRow();
  1447. int iEndCol = m_nCurrentCol;
  1448. DeleteBuffer(iStartRow, iStartCol, iEndRow, iEndCol);
  1449. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  1450. if (bSelectionExist)
  1451. m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
  1452. }
  1453. bUpdateAll = TRUE;
  1454. break;
  1455. case VK_INSERT:
  1456. {
  1457. NotifyParent(XTP_EDIT_NM_INSERTKEY);
  1458. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
  1459. SetOverwriteMode(!m_pBuffer->GetOverwriteFlag());
  1460. }
  1461. break;
  1462. case VK_SPACE:
  1463. if (bCtrlKey)
  1464. {
  1465. CPoint pt(CWnd::GetCaretPos());
  1466. pt.y += m_DrawTextProcessor.GetRowHeight();
  1467. ClientToScreen(&pt);
  1468. CString strText(GetLineText(GetCurrentDocumentRow()));
  1469. int nTextPos = m_nCurrentCol - 2;
  1470. CString strSearch;
  1471. while (strText.GetLength() > 0 && nTextPos >= 0 && m_pAutoComplete->m_strDelims.Find(strText.GetAt(nTextPos)) < 0)
  1472. {
  1473. strSearch = strText.GetAt(nTextPos--) + strSearch;
  1474. }
  1475. SetAutoCompleteList();
  1476. m_pAutoComplete->Show(pt, strSearch);
  1477. }
  1478. break;
  1479. }
  1480. BOOL bChanged = nTopRow_prev != m_nTopRow || nDispCol_prev != m_nDispCol ||
  1481. nTextRow_prev != GetCurrentDocumentRow() || nRowCount_prev != GetRowCount() ||
  1482. selData_prev != m_Selection;
  1483. if (bChanged)
  1484. {
  1485. int nCurDocRow = GetCurrentDocumentRow();
  1486. SetCurCaretPos(nCurDocRow, m_nDispCol);
  1487. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  1488. Invalidate(FALSE);
  1489. UpdateWindow();
  1490. if (nTopRow_prev != m_nTopRow)
  1491. RecalcScrollBars();
  1492. DWORD dwUpdate = (XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
  1493. if (bUpdateAll)
  1494. dwUpdate |= XTP_EDIT_UPDATE_DIAG;
  1495. UpdateScrollPos(dwUpdate);
  1496. }
  1497. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  1498. }
  1499. void CXTPSyntaxEditCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  1500. {
  1501. if (m_bDragging || m_bRightButtonDrag)
  1502. {
  1503. OnSetCursor(0,0,0);
  1504. return;
  1505. }
  1506. NotifySelInit();
  1507. BOOL bAltKey  = (::GetKeyState(VK_MENU) & KF_UP) != 0;
  1508. BOOL bCtrlKey  = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
  1509. BOOL bShiftKey  = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
  1510. CString strCurCRLF = m_pBuffer->GetCurCRLF();
  1511. LPCTSTR szCurCRLF = strCurCRLF;
  1512. BOOL bProcessed = FALSE;
  1513. if (nChar == VK_TAB)
  1514. {
  1515. if (bShiftKey)
  1516. bProcessed = DecreaseIndent();
  1517. else
  1518. bProcessed = IncreaseIndent();
  1519. }
  1520. if (!bProcessed && (bCtrlKey && !bAltKey) && nChar == 0x0C) // 0x0C is 'l' or 'L'
  1521. {
  1522. // Delete the entire line or the selection
  1523. DeleteSelectedLines(GetCurrentDocumentRow());
  1524. }
  1525. else if (nChar != VK_BACK && nChar != VK_ESCAPE && !(bCtrlKey && !bAltKey) && !bProcessed)
  1526. {
  1527. if (!CanEditDoc())
  1528. {
  1529. return;
  1530. }
  1531. BOOL bModified = FALSE;
  1532. //**----------------------
  1533. OnBeforeEditChanged(GetCurrentDocumentRow(), m_nCurrentCol);
  1534. //**----------------------
  1535. int nChainActionCount = 1;
  1536. BOOL bRedraw = FALSE;
  1537. BOOL bPrevOverwriteMode = m_pBuffer->GetOverwriteFlag();
  1538. if (m_Selection.IsSelExist())
  1539. {
  1540. if (!m_pBuffer->GetOverwriteFlag() || (m_pBuffer->GetOverwriteFlag() && nChar != VK_RETURN))
  1541. {
  1542. BOOL bRes = DeleteSelection();
  1543. bModified |= bRes;
  1544. nChainActionCount = 2;
  1545. bRedraw = TRUE;
  1546. m_pBuffer->SetOverwriteFlag(FALSE);
  1547. }
  1548. }
  1549. TCHAR szText[3];
  1550. szText[0] = (TCHAR)nChar;
  1551. szText[1] = NULL;
  1552. // DBCS Support (specially for IME)
  1553. #ifndef _UNICODE
  1554. //if (m_bIsImeEnabled)
  1555. if (isleadbyte((int)nChar) && m_chPrevLeadByte == 0)
  1556. {
  1557. // do not process lead byte. just remember it and exit.
  1558. m_chPrevLeadByte = (BYTE)nChar;
  1559. return;
  1560. }
  1561. if (m_chPrevLeadByte)
  1562. {
  1563. szText[0] = (TCHAR)m_chPrevLeadByte;
  1564. szText[1] = (TCHAR)nChar;
  1565. szText[2] = NULL;
  1566. }
  1567. m_chPrevLeadByte = 0;
  1568. #endif
  1569. if (nChar == _T('r'))
  1570. {
  1571. lstrcpy(szText, szCurCRLF);
  1572. szText[2] = NULL;
  1573. // here we should expand collapsed block if we are on it
  1574. if (GetLineMarksManager()->HasRowMark(GetCurrentDocumentRow(), xtpEditLMT_Collapsed))
  1575. {
  1576. GetLineMarksManager()->DeleteLineMark(GetCurrentDocumentRow(), xtpEditLMT_Collapsed);
  1577. }
  1578. }
  1579. int iNewDispCol  = m_nDispCol;
  1580. int iNewCol      = m_nCurrentCol;
  1581. int iNewRow      = GetCurrentDocumentRow();
  1582. int iEditRowFrom = iNewRow;
  1583. int iEditRowTo   = iNewRow;
  1584. CString strTextToIns;
  1585. // Create text to insert
  1586. BOOL bCanProcess =
  1587. CreateInsertText(szText,
  1588. strTextToIns,
  1589. iNewRow,
  1590. iNewCol,
  1591. iNewDispCol,
  1592. iEditRowFrom,
  1593. iEditRowTo,
  1594. nChainActionCount);
  1595. BOOL bGroupInsMode = FALSE;
  1596. if (!bPrevOverwriteMode)
  1597. {
  1598. static LPCTSTR szSeps = _T(" [{()}];.,trn"");
  1599. if (_tcschr(szSeps, (TCHAR)nChar))
  1600. bGroupInsMode = FALSE;
  1601. else
  1602. bGroupInsMode = TRUE;
  1603. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(bGroupInsMode);
  1604. }
  1605. else
  1606. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  1607. if (bCanProcess)
  1608. {
  1609. int nInsCol = m_nCurrentCol;
  1610. if (nChar == VK_RETURN && m_nAutoIndentCol)
  1611. nInsCol = min(m_nCurrentCol, m_pBuffer->GetLineTextLengthC(GetCurrentDocumentRow()) + 1);
  1612. BOOL bInsRes = m_pBuffer->InsertText(strTextToIns, GetCurrentDocumentRow(), nInsCol, TRUE);
  1613. bModified |= bInsRes;
  1614. if (nChainActionCount > 1)
  1615. {
  1616. m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
  1617. m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_TYPING);
  1618. }
  1619. }
  1620. //m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  1621. m_pBuffer->SetOverwriteFlag(bPrevOverwriteMode);
  1622. //**----------------------
  1623. OnEditChanged(GetCurrentDocumentRow(), m_nCurrentCol, iNewRow, iNewCol, xtpEditActInsert);
  1624. //**----------------------
  1625. BOOL bInsAt0 = (m_nCurrentCol == 1) || GetLineText(GetCurrentDocumentRow()).GetLength() == 0;
  1626. m_nCurrentCol = iNewCol;
  1627. m_nDispCol    = iNewDispCol;
  1628. SetCurrentDocumentRow(iNewRow);
  1629. BOOL bNewRow = FALSE;
  1630. if (nChar == VK_RETURN)
  1631. bNewRow = TRUE;
  1632. UINT nAction = XTP_EDIT_EDITACTION_MODIFYROW;
  1633. if (bNewRow)
  1634. nAction |= XTP_EDIT_EDITACTION_INSERTROW;
  1635. if (bNewRow && bInsAt0)
  1636. nAction |= XTP_EDIT_EDITACTION_INSERTROW_NEW;
  1637. NotifyEditChanged(iEditRowFrom, iEditRowTo, nAction);
  1638. //      if (nChar == VK_RETURN)
  1639. //      {
  1640. //          DoAutoIndentIfNeed(nDispCol_prev);
  1641. //      }
  1642. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
  1643. RecalcScrollBars();
  1644. Invalidate(FALSE);
  1645. UpdateWindow();
  1646. UpdateScrollPos();
  1647. if (bModified)
  1648. SetDocModified();
  1649. }
  1650. else if (!bProcessed && nChar == VK_ESCAPE)
  1651. {
  1652. Unselect();
  1653. UpdateScrollPos();
  1654. }
  1655. // AutoComplete Processing
  1656. if (m_pAutoComplete->IsOpenTag((TCHAR)nChar))
  1657. {
  1658. CPoint pt(CWnd::GetCaretPos());
  1659. pt.y += m_DrawTextProcessor.GetRowHeight();
  1660. ClientToScreen(&pt);
  1661. SetAutoCompleteList();
  1662. m_pAutoComplete->Show(pt);
  1663. }
  1664. CWnd::OnChar(nChar, nRepCnt, nFlags);
  1665. }
  1666. void CXTPSyntaxEditCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  1667. {
  1668. CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
  1669. #ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
  1670. if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, FALSE, nChar))
  1671. return;
  1672. #endif
  1673. if (nChar == 0)
  1674. {
  1675. return;
  1676. }
  1677. if (m_bDragging)
  1678. {
  1679. OnSetCursor(0,0,0);
  1680. return;
  1681. }
  1682. CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
  1683. }
  1684. void CXTPSyntaxEditCtrl::SetCurPos(int nTextRow, int nDispCol, BOOL bRemainSelected, BOOL bForceVisible)
  1685. {
  1686. if (nTextRow > GetRowCount())
  1687. nTextRow = GetRowCount();
  1688. //reset autoindent
  1689. m_nAutoIndentCol = 0;
  1690. CString strText = GetLineText(nTextRow);
  1691. // validate col
  1692. m_nCurrentCol = CalcAbsCol(strText, nDispCol);
  1693. m_nDispCol = CalcDispCol(strText, m_nCurrentCol);
  1694. if (!bRemainSelected && m_Selection.IsSelExist())
  1695. {
  1696. m_Selection.Reset_disp(nTextRow, m_nDispCol);
  1697. }
  1698. SetCurCaretPos(nTextRow, m_nDispCol, TRUE, bForceVisible);
  1699. Invalidate(FALSE);
  1700. UpdateWindow();
  1701. UpdateScrollPos(XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
  1702. }
  1703. void CXTPSyntaxEditCtrl::SetCurCaretPos(int nTextRow, int nDispCol, BOOL bRowColNotify, BOOL bEnsureVisible)
  1704. {
  1705. if (bEnsureVisible)
  1706. _EnsureVisible(nTextRow, nDispCol);
  1707. int nDispRow = GetVisibleRow(nTextRow);
  1708. if (nDispRow > m_DrawTextProcessor.GetRowsCount(TRUE) + 10)
  1709. nDispRow = m_DrawTextProcessor.GetRowsCount(TRUE) + 10;
  1710. if (m_nAutoIndentCol > 0)
  1711. nDispCol = m_nAutoIndentCol;
  1712. int nCol = max(0, nDispCol - 1);
  1713. m_nDispCol = nCol + 1;
  1714. m_nCurrentCol = CalcAbsCol(nTextRow, m_nDispCol);
  1715. SetCurrentDocumentRow(nTextRow);
  1716. if (bRowColNotify)
  1717. NotifyCurRowCol(GetCurrentDocumentRow(), m_nDispCol);
  1718. Invalidate(FALSE);
  1719. //TRACE(_T("CXTPSyntaxEditCtrl::SetCurCaretPos(%d, %d) n"), nDispRow, nDispCol);
  1720. }
  1721. void CXTPSyntaxEditCtrl::_EnsureVisible(int nTextRow, int nDispCol/*, BOOL bRedraw*/)
  1722. {
  1723. BOOL bVScrolled = EnsureVisibleRow(nTextRow);
  1724. nDispCol = nDispCol;
  1725. if (m_nAutoIndentCol > 0)
  1726. nDispCol = m_nAutoIndentCol;
  1727. int nDispRow = GetVisibleRow(nTextRow);
  1728. BOOL bHScrolled = EnsureVisibleCol(nDispRow, nDispCol);
  1729. //  BOOL bVirtSpace = _IsVirtualSpaceActive() || m_nAutoIndentCol;
  1730. //  m_nCurrentCol = m_DrawTextProcessor.DispPosToStrPos(nDispRow - 1, m_nDispCol-1, bVirtSpace) + 1;
  1731. if (bVScrolled || bHScrolled /*|| bRedraw*/)
  1732. {
  1733. Invalidate(FALSE);
  1734. }
  1735. }
  1736. BOOL CXTPSyntaxEditCtrl::EnsureVisibleRow(int nTextRow)
  1737. {
  1738. int nPrevTopRow = m_nTopRow;
  1739. int nDispRowsCount = m_DrawTextProcessor.GetRowsCount(FALSE);
  1740. int nCurPageMaxTextRow = GetDocumentRow(nDispRowsCount);
  1741. if (nDispRowsCount == 0)
  1742. {
  1743. return FALSE;
  1744. }
  1745. if (nTextRow > nCurPageMaxTextRow)
  1746. {
  1747. m_nTopRow += nTextRow - nCurPageMaxTextRow;
  1748. }
  1749. else if (nTextRow < m_nTopRow)
  1750. {
  1751. m_nTopRow = max (1, nTextRow);
  1752. }
  1753. if (GetVertScrollBar() /*&& nPrevTopRow != m_nTopRow*/)
  1754. {
  1755. BOOL bEnableVertScrl = (CalculateVisibleRow(1, GetRowCount()) > nDispRowsCount);
  1756. EnableScrollBarCtrl(SB_VERT, bEnableVertScrl);
  1757. if (bEnableVertScrl)
  1758. SetScrollPos(SB_VERT,  CalculateVisibleRow(1, m_nTopRow));
  1759. }
  1760. return nPrevTopRow != m_nTopRow;
  1761. }
  1762. BOOL CXTPSyntaxEditCtrl::EnsureVisibleCol(int nDispRow, int nDispCol)
  1763. {
  1764. int nTextRow = GetDocumentRow(nDispRow);
  1765. UpdateRowInfoInternally(nTextRow);
  1766. int nColWidth = 0;
  1767. int nColPos = m_DrawTextProcessor.GetColPosX(nDispRow - 1, nDispCol, &nColWidth, m_bVirtualSpace);
  1768. int nOffsetX = m_DrawTextProcessor.GetScrollXOffset();
  1769. CRect rcText = m_DrawTextProcessor.GetTextRect();
  1770. int nNewScrollOffset = -1;
  1771. if (nColPos - max(14, nColWidth * 2) < rcText.left)
  1772. {
  1773. nNewScrollOffset = max(0, nOffsetX - (rcText.left - nColPos )- nColWidth * 15);
  1774. }
  1775. else if (nColPos + nColWidth >= rcText.right)
  1776. {
  1777. nNewScrollOffset = nOffsetX + (nColPos + nColWidth) - rcText.right + min(rcText.Width()/3, nColWidth * 15);
  1778. }
  1779. if (nNewScrollOffset >= 0)
  1780. {
  1781. SetScrollPos(SB_HORZ, nNewScrollOffset);
  1782. m_DrawTextProcessor.SetScrollXOffset(nNewScrollOffset);
  1783. }
  1784. return nNewScrollOffset >= 0;
  1785. }
  1786. int CXTPSyntaxEditCtrl::CalcDispCol(int nTextRow, int nActualCol)
  1787. {
  1788. CString strLine = GetLineText(nTextRow);
  1789. return CalcDispCol(strLine, nActualCol);
  1790. }
  1791. int CXTPSyntaxEditCtrl::CalcAbsCol(int nTextRow, int nDispCol)
  1792. {
  1793. CString strLine = GetLineText(nTextRow);
  1794. return CalcAbsCol(strLine, nDispCol);
  1795. }
  1796. int CXTPSyntaxEditCtrl::CalcDispCol(LPCTSTR szText, int nActualCol)
  1797. {
  1798. int iDispCol = 0;
  1799. int nAbsCol = 1;
  1800. for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
  1801. {
  1802. if (nAbsCol >= nActualCol)
  1803. break;
  1804. if (*pcszChar == _T('t'))
  1805. {
  1806. // Now calculate tab size
  1807. iDispCol += (GetTabSize() - (iDispCol % GetTabSize()));
  1808. }
  1809. else
  1810. iDispCol++;
  1811. nAbsCol++;
  1812. }
  1813. iDispCol++;
  1814. if (nAbsCol < nActualCol)
  1815. {
  1816. if (_IsVirtualSpaceActive())
  1817. iDispCol += nActualCol - nAbsCol;
  1818. else
  1819. iDispCol++;
  1820. }
  1821. return iDispCol;
  1822. }
  1823. int CXTPSyntaxEditCtrl::CalcAbsCol(LPCTSTR szText, int iDispCol)
  1824. {
  1825. int nAbsCol = 0;
  1826. int nDispColCalc = 0;
  1827. for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
  1828. {
  1829. if (nDispColCalc >= iDispCol)
  1830. break;
  1831. //if (szText[i] == _T('t'))
  1832. if (*pcszChar == _T('t'))
  1833. nDispColCalc += (GetTabSize() - (nDispColCalc % GetTabSize()));
  1834. else
  1835. nDispColCalc++;
  1836. nAbsCol++;
  1837. }
  1838. if (nDispColCalc < iDispCol)
  1839. {
  1840. if (_IsVirtualSpaceActive())
  1841. nAbsCol += iDispCol - nDispColCalc;
  1842. else
  1843. nAbsCol++;
  1844. }
  1845. if (nAbsCol == 0)
  1846. nAbsCol = 1;
  1847. return nAbsCol;
  1848. }
  1849. int CXTPSyntaxEditCtrl::CalcValidDispCol(LPCTSTR szText, int iCol)
  1850. {
  1851. int iDispCol = 0;
  1852. for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
  1853. {
  1854. if (iDispCol >= iCol-1)
  1855. break;
  1856. if (*pcszChar == _T('t'))
  1857. {
  1858. // Now calculate tab size
  1859. iDispCol += (GetTabSize() - (iDispCol % GetTabSize()));
  1860. }
  1861. else
  1862. iDispCol++;
  1863. }
  1864. return ++iDispCol;
  1865. }
  1866. int CXTPSyntaxEditCtrl::CalcMaximumWidth(LPCTSTR szText)
  1867. {
  1868. int iMaxWidth = 1;
  1869. for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
  1870. {
  1871. if (*pcszChar == _T('t'))
  1872. {
  1873. // Now calculate tab size
  1874. iMaxWidth += ((GetTabSize() + 1) - (iMaxWidth - ((iMaxWidth / GetTabSize()) * GetTabSize())));
  1875. }
  1876. else
  1877. iMaxWidth++;
  1878. }
  1879. return iMaxWidth;
  1880. }
  1881. void CXTPSyntaxEditCtrl::GetLineNodeRect(int nRow, CRect& rcNode, CRect* prcNodeFull)
  1882. {
  1883. // calculate node rect
  1884. CRect rcNodes, rcText;
  1885. CalcEditRects(NULL, NULL, &rcNodes, &rcText);
  1886. int nRowHeight = m_DrawTextProcessor.GetRowHeight();
  1887. int nYPos = rcNodes.top + nRow * nRowHeight;
  1888. rcNode = rcNodes;
  1889. rcNode.top = nYPos + (nRowHeight - m_nNodesWidth) / 2;
  1890. rcNode.bottom = rcNode.top + m_nNodesWidth - 1;
  1891. if (prcNodeFull)
  1892. {
  1893. prcNodeFull->left = rcNodes.left;
  1894. prcNodeFull->right = rcText.left;
  1895. prcNodeFull->top = nYPos;
  1896. prcNodeFull->bottom = nYPos + nRowHeight;
  1897. }
  1898. }
  1899. BOOL CXTPSyntaxEditCtrl::ProcessCollapsedTextEx(CDC* pDC, XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk,
  1900. const XTP_EDIT_TEXTBLOCK& txtBlk,
  1901. CRect& rcCoBlk)
  1902. {
  1903. if (!pCoDrawBlk)
  1904. {
  1905. ASSERT(FALSE);
  1906. return FALSE;
  1907. }
  1908. if (txtBlk.nPos < pCoDrawBlk->collBlock.lcStart.nCol)
  1909. {
  1910. return FALSE;
  1911. }
  1912. ProcessCollapsedText(pDC, pCoDrawBlk, rcCoBlk);
  1913. return TRUE;
  1914. }
  1915. void CXTPSyntaxEditCtrl::ProcessCollapsedText(CDC* pDC, XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk,
  1916. CRect& rcCoBlk)
  1917. {
  1918. CString strText = pCoDrawBlk->collBlock.strCollapsedText; // "[..]"
  1919. CXTPFontDC fontDC(pDC, GetPaintManager()->GetFont());
  1920. rcCoBlk.right = rcCoBlk.left + pDC->GetTextExtent(strText).cx + 3;
  1921. pCoDrawBlk->rcCollMark = rcCoBlk;
  1922. }
  1923. CString CXTPSyntaxEditCtrl::GetCollapsedText(XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk, int nMaxLinesCount)
  1924. {
  1925. if (!pCoDrawBlk || !m_pBuffer)
  1926. {
  1927. ASSERT(FALSE);
  1928. return _T("");
  1929. }
  1930. CString strCoText;
  1931. int nLine1 = pCoDrawBlk->collBlock.lcStart.nLine;
  1932. int nLine2 = pCoDrawBlk->collBlock.lcEnd.nLine;
  1933. int nLine2max = min(nLine2, nLine1 + nMaxLinesCount-1);
  1934. int nCol1 = pCoDrawBlk->collBlock.lcStart.nCol;
  1935. int nCol2 = pCoDrawBlk->collBlock.lcEnd.nCol;
  1936. for (int nLine = nLine1; nLine <= nLine2max; nLine++)
  1937. {
  1938. CString strTmp = m_pBuffer->GetLineText(nLine);
  1939. int nTextLen = strTmp.GetLength();
  1940. if (nTextLen)
  1941. {
  1942. if (nLine == nLine2)
  1943. {
  1944. ASSERT(nCol2 < nTextLen+2);
  1945. nCol2 = max(0, min(nCol2, nTextLen-1));
  1946. strTmp = strTmp.Left(nCol2+1);
  1947. }
  1948. if (nLine == nLine1)
  1949. {
  1950. nTextLen = strTmp.GetLength();
  1951. ASSERT(nCol1 < nTextLen+2);
  1952. if (nCol1 < nTextLen)
  1953. {
  1954. strTmp = strTmp.Mid(nCol1);
  1955. }
  1956. else
  1957. {
  1958. strTmp.Empty();
  1959. }
  1960. }
  1961. }
  1962. if (!strCoText.IsEmpty())
  1963. {
  1964. strCoText += _T("rn");
  1965. }
  1966. strCoText += strTmp;
  1967. }
  1968. return strCoText;
  1969. }
  1970. int CXTPSyntaxEditCtrl::ExpandChars(CDC* pDC, LPCTSTR pszChars, int nCurPos, CString& strBuffer)
  1971. {
  1972. int nTabSize = GetTabSize();
  1973. const int nLength = (int)_tcslen(pszChars);
  1974. if (nLength == 0)
  1975. return 0;
  1976. int nActualOffset = nCurPos;
  1977. int I;
  1978. for (I = 0; I < nLength; I++)
  1979. {
  1980. if (pszChars[I] == _T('t'))
  1981. nActualOffset += (nTabSize - nActualOffset % nTabSize);
  1982. else
  1983. nActualOffset ++;
  1984. }
  1985. int nActualLength = nActualOffset - nCurPos;
  1986. for (I = 0; I < nLength; I++)
  1987. {
  1988. if (pszChars[I] == _T('t'))
  1989. {
  1990. int nSpaces = nTabSize - (nCurPos % nTabSize);
  1991. BOOL bFirstChar = TRUE;
  1992. while (nSpaces > 0)
  1993. {
  1994. if (bFirstChar && m_bEnableWhiteSpace && !pDC->IsPrinting())
  1995. {
  1996. strBuffer += (TCHAR)(unsigned char)0xBB;
  1997. bFirstChar = FALSE;
  1998. }
  1999. else
  2000. strBuffer += _T(' ');
  2001. nSpaces--;
  2002. nCurPos++;
  2003. }
  2004. }
  2005. else
  2006. {
  2007. if (m_bEnableWhiteSpace && pszChars[I] == _T(' ') && !pDC->IsPrinting())
  2008. strBuffer += (TCHAR)(unsigned char)0xB7;
  2009. else
  2010. strBuffer += pszChars[I];
  2011. nCurPos++;
  2012. }
  2013. }
  2014. return nActualLength;
  2015. }
  2016. void CXTPSyntaxEditCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  2017. {
  2018. SetFocus();
  2019. // Manage AutoCompleteView
  2020. if (m_pAutoComplete->IsActive())
  2021. {
  2022. CRect rcACcomplete;
  2023. m_pAutoComplete->GetWindowRect(&rcACcomplete);
  2024. ScreenToClient(&rcACcomplete);
  2025. if (rcACcomplete.PtInRect(point))
  2026. return;
  2027. else
  2028. m_pAutoComplete->Hide();
  2029. }
  2030. m_bDragging = FALSE;
  2031. m_bRightButtonDrag = FALSE;
  2032. m_nAutoIndentCol = 0;
  2033. m_Selection.bSelectingRunning = FALSE;
  2034. if (m_Selection.IsSelExist())
  2035. Invalidate(FALSE);
  2036. NotifySelInit();
  2037. SetCapture();
  2038. BOOL bCtrlKey  = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
  2039. BOOL bShiftKey  = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
  2040. BOOL bAltKey  = (::GetKeyState(VK_MENU) & KF_UP) != 0;
  2041. CXTPClientRect rcClient(this);
  2042. CRect rcBookmark, rcLineNum, rcNodes, rcText;
  2043. rcClient.bottom = rcClient.top + m_DrawTextProcessor.GetRowHeight() * m_DrawTextProcessor.GetRowsCount(FALSE);
  2044. CalcEditRects(&rcBookmark, &rcLineNum, &rcNodes, &rcText, &rcClient);
  2045. CRect rcLineNumAndNodes(rcLineNum);
  2046. rcLineNumAndNodes.right = rcNodes.right;
  2047. int nNewRow = 0, nNewCol = 0, nNewDispRow = 0, nNewDispCol = 0;
  2048. RowColFromPoint(point, &nNewRow, &nNewCol, &nNewDispRow, &nNewDispCol);
  2049. BOOL bSelFromLeftBar = rcLineNumAndNodes.PtInRect(point);
  2050. //  TRACE(_T("*** OnLButtonDown. RowColFromPoint: nNewRow=%d, nNewCol=%d, nNewDispRow=%d, nNewDispCol=%d n"),
  2051. //          nNewRow, nNewCol, nNewDispRow, nNewDispCol);
  2052. //--------------------------------------------------------------------
  2053. if (GetCurrentDocumentRow() != nNewRow || m_nDispCol != nNewDispCol)
  2054. {
  2055. // reset undo buffer group mode processing
  2056. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  2057. }
  2058. //--------------------------------------------------------------------
  2059. if (rcBookmark.PtInRect(point))
  2060. {
  2061. m_Selection.Reset_disp(nNewRow, nNewDispCol);
  2062. if (!NotifyMarginLBtnClick(nNewRow, nNewDispRow))
  2063. {
  2064. AddRemoveBreakPoint(nNewRow);
  2065. SetCurPos(nNewRow, 1);
  2066. }
  2067. CWnd::OnLButtonDown(nFlags, point);
  2068. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
  2069. return;
  2070. }
  2071. //--------------------------------------------------------------------
  2072. if (m_bDrawNodes && rcNodes.PtInRect(point))
  2073. {
  2074. CXTPEmptyRect rcNode;
  2075. DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
  2076. if (GetRowNodes(nNewRow, dwType) && (dwType & (XTP_EDIT_ROWNODE_COLLAPSED | XTP_EDIT_ROWNODE_EXPANDED)))
  2077. {
  2078. GetLineNodeRect(nNewDispRow-1, rcNode);
  2079. }
  2080. if (rcNode.PtInRect(point) && m_pBuffer)
  2081. {
  2082. m_Selection.Reset_disp(m_Selection.GetEnd_disp().nLine, m_Selection.GetEnd_disp().nCol);
  2083. // expand/collapse a node
  2084. CollapseExpandBlock(nNewRow);
  2085. SetCurPos(nNewRow, 1);
  2086. CWnd::OnLButtonDown(nFlags, point);
  2087. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
  2088. return;
  2089. }
  2090. }
  2091. //--------------------------------------------------------------------
  2092. if (rcText.PtInRect(point) && m_Selection.IsInSel_disp(nNewRow, nNewDispCol))
  2093. {
  2094. m_Selection.bSelectingRunning = FALSE;
  2095. if (!m_bEnableOleDrag)
  2096. m_bDragging = TRUE;
  2097. else
  2098. {
  2099. NotifyParent(XTP_EDIT_NM_STARTOLEDRAG);
  2100. }
  2101. CWnd::OnLButtonDown(nFlags, point);
  2102. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
  2103. return;
  2104. }
  2105. //--------------------------------------------------------------------
  2106. if (bAltKey)
  2107. {
  2108. m_Selection.Reset_disp(nNewRow, nNewDispCol);
  2109. m_Selection.bSelectingRunning = TRUE;
  2110. m_Selection.bBlockSelectionMode = TRUE;
  2111. }
  2112. else if (bShiftKey)
  2113. {
  2114. m_Selection.SetEnd_disp(nNewRow, nNewDispCol);
  2115. m_Selection.bSelectingRunning = TRUE;
  2116. m_Selection.bBlockSelectionMode = FALSE;
  2117. m_Selection.bWordSelectionMode = bCtrlKey;
  2118. }
  2119. else
  2120. {
  2121. m_Selection.Reset_disp(nNewRow, nNewDispCol);
  2122. m_Selection.bSelectingRunning = TRUE;
  2123. m_Selection.bWordSelectionMode = bCtrlKey;
  2124. if (bSelFromLeftBar)
  2125. m_Selection.nSelStartTextRowFromLeftBar = m_Selection.GetStart_str().nLine;
  2126. }
  2127. //  TRACE(_T("Selection: (row=%d, strPos=%d, DispCol=%d)-(row=%d, strPos=%d, DispCol=%d) n"),
  2128. //          m_Selection.GetStart_str().nLine, m_Selection.GetStart_str().nCol, m_Selection.GetStart_disp().nCol,
  2129. //          m_Selection.GetEnd_str().nLine, m_Selection.GetEnd_str().nCol, m_Selection.GetEnd_disp().nCol);
  2130. if (m_Selection.bWordSelectionMode)
  2131. {
  2132. XTP_EDIT_LINECOL lcWord1, lcWord2;
  2133. BOOL bOverSpace = FALSE;
  2134. UINT nFindDir = m_Selection.IsSelNormal() ? XTP_EDIT_FINDWORD_NEXT : XTP_EDIT_FINDWORD_PREV;
  2135. BOOL bFind = FindWordEx_str(nFindDir, m_Selection.GetEnd_str(), lcWord1, lcWord2, bOverSpace);
  2136. //      TRACE(_T("1-FindWordEx_str = %d (%d,%d - %d,%d)"), bFind,
  2137. //              lcWord1.nLine, lcWord1.nCol,lcWord2.nLine, lcWord2.nCol);
  2138. if (bFind && lcWord1.IsValidData() && lcWord1 != m_Selection.GetNormalStart_str())
  2139. {
  2140. if (m_Selection.IsSelNormal())
  2141. m_Selection.SetStart_str(lcWord1.nLine, lcWord1.nCol-1);
  2142. else
  2143. m_Selection.SetEnd_str(lcWord1.nLine, lcWord1.nCol-1);
  2144. }
  2145. if (lcWord2.IsValidData() && lcWord2 != m_Selection.GetNormalEnd_str())
  2146. {
  2147. if (m_Selection.IsSelNormal())
  2148. m_Selection.SetEnd_str(lcWord2.nLine, lcWord2.nCol-1);
  2149. else
  2150. m_Selection.SetStart_str(lcWord2.nLine, lcWord2.nCol-1);
  2151. }
  2152. }
  2153. SetCurrentDocumentRow(nNewRow);
  2154. m_nDispCol =  m_Selection.GetEnd_disp().nCol;
  2155. m_nCurrentCol = m_Selection.GetEnd_str().nCol + 1;
  2156. SetCurCaretPos(m_Selection.GetEnd_disp().nLine, m_nDispCol, TRUE, FALSE);
  2157. if (m_Selection.bSelectingRunning)
  2158. SetTimer(TIMER_SELECTION_ID, TIMER_SELECTION_TIME, NULL);
  2159. Invalidate(FALSE);
  2160. CWnd::OnLButtonDown(nFlags, point);
  2161. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
  2162. }
  2163. void CXTPSyntaxEditCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
  2164. {
  2165. KillTimer(TIMER_SELECTION_ID);
  2166. int nRow = ProcessCollapsedBlockDblClick(point);
  2167. if (nRow > 0)
  2168. {
  2169. // close tooltip.
  2170. ShowCollapsedToolTip(CPoint(0,0));
  2171. }
  2172. else
  2173. {
  2174. // Select the word
  2175. SelectWord(point);
  2176. }
  2177. CWnd::OnLButtonDblClk(nFlags, point);
  2178. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDBLCLICK, nFlags, point);
  2179. }
  2180. void CXTPSyntaxEditCtrl::OnLButtonUp(UINT nFlags, CPoint point)
  2181. {
  2182. if (!GetCapture() || GetCapture() != this || GetFocus() != this)
  2183. {
  2184. return;
  2185. }
  2186. if (GetCapture() == this)
  2187. {
  2188. ReleaseCapture();
  2189. }
  2190. int nNewRow = 0, nNewCol = 0, nNewDispRow = 0, nNewDispCol = 0;
  2191. BOOL bRowCol = RowColFromPoint(point, &nNewRow, &nNewCol, &nNewDispRow, &nNewDispCol);
  2192. if (bRowCol && m_Selection.IsInSel_disp(nNewRow, nNewDispCol) &&
  2193. !m_Selection.bSelectingRunning && !m_bDragging) // dragging
  2194. {
  2195. m_Selection.Reset_disp(m_Selection.GetStart_disp().nLine, m_Selection.GetStart_disp().nCol);
  2196. }
  2197. else
  2198. {
  2199. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
  2200. }
  2201. m_Selection.bSelectingRunning = FALSE;
  2202. KillTimer(TIMER_SELECTION_ID);
  2203. m_dwAutoScrollDirection = 0;
  2204. KillTimer(TIMER_AUTOSCROLL_ID);
  2205. //-----------------------------------------------------------------------
  2206. if (m_bDragging)
  2207. {
  2208. if (m_bDroppable)
  2209. {
  2210. BOOL bCtrlKey  = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
  2211. CopyOrMoveText(bCtrlKey);
  2212. }
  2213. else
  2214. {
  2215. m_Selection.Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
  2216. }
  2217. }
  2218. m_bDragging = FALSE;
  2219. m_bDroppable = FALSE;
  2220. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
  2221. Invalidate(FALSE);
  2222. UpdateWindow();
  2223. CWnd::OnLButtonUp(nFlags, point);
  2224. NotifyMouseEvent(XTP_EDIT_NM_LBUTTONUP, nFlags, point);
  2225. }
  2226. void CXTPSyntaxEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
  2227. {
  2228. if (m_bDragging || m_bRightButtonDrag)
  2229. {
  2230. m_bDragging = TRUE;
  2231. CXTPClientRect rcWnd(this);
  2232. if (rcWnd.PtInRect(point))
  2233. {
  2234. int nNewRow = 0, nNewCol = 0, nNewDispCol = 0;
  2235. RowColFromPoint(point, &nNewRow, &nNewCol, NULL, &nNewDispCol);
  2236. //TRACE(_T("DropPOS: nNewRow=%d, nNewCol=%d, nNewDispCol=%d n"), nNewRow, nNewCol, nNewDispCol);
  2237. if (nNewRow != m_ptDropPos.y || nNewDispCol != m_ptDropPos.x)
  2238. {
  2239. m_nDispCol = nNewDispCol;
  2240. m_ptDropPos.x = m_nDispCol;
  2241. m_ptDropPos.y = nNewRow;
  2242. //SetCurrentDocumentRow(nNewRow);
  2243. SetCurCaretPos(m_ptDropPos.y, m_ptDropPos.x, FALSE, FALSE);
  2244. }
  2245. m_bDroppable = !m_Selection.IsInSel_disp(m_ptDropPos.y, m_ptDropPos.x);
  2246. OnSetCursor(0,0,0);
  2247. }
  2248. else
  2249. {
  2250. m_bDroppable = FALSE;
  2251. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO));
  2252. }
  2253. }
  2254. //  else if (m_Selection.bSelectingRunning)
  2255. //  {
  2256. //      OnTimer(TIMER_SELECTION_ID);
  2257. //  }
  2258. ShowCollapsedToolTip(point);
  2259. CWnd::OnMouseMove(nFlags, point);
  2260. NotifyMouseEvent(XTP_EDIT_NM_MOUSEMOVE, nFlags, point);
  2261. }
  2262. XTP_EDIT_COLLAPSEDBLOCK* CXTPSyntaxEditCtrl::GetBlockFromPt(const CPoint& ptMouse)
  2263. {
  2264. // enumerate all collapsed blocks coordinates
  2265. // to find the one where mouse into
  2266. XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = NULL;
  2267. XTP_EDIT_LMPARAM LMCoParam;
  2268. int nActualRow = 0;
  2269. for (int i = 0; i < m_nCollapsedTextRowsCount; i++)
  2270. {
  2271. int nRow = m_arCollapsedTextRows[i];
  2272. if (nRow <= nActualRow)
  2273. {
  2274. continue;
  2275. }
  2276. if (!HasRowMark(nRow, xtpEditLMT_Collapsed, &LMCoParam))
  2277. {
  2278. continue;
  2279. }
  2280. // get count of collapsed rows under this row
  2281. int nHiddenRows = 0;
  2282. if (!GetCollapsedBlockLen(nRow, nHiddenRows))
  2283. {
  2284. continue;
  2285. }
  2286. nActualRow = nRow + nHiddenRows;
  2287. // get collapsed block pointer
  2288. pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
  2289. if (!pCoDrawBlk)
  2290. {
  2291. ASSERT(FALSE);
  2292. continue;
  2293. }
  2294. CRect crCollapsed(pCoDrawBlk->rcCollMark);
  2295. if (crCollapsed.PtInRect(ptMouse))
  2296. {
  2297. return pCoDrawBlk;
  2298. }
  2299. }
  2300. return NULL;
  2301. }
  2302. int CXTPSyntaxEditCtrl::ProcessCollapsedBlockDblClick(const CPoint& ptMouse)
  2303. {
  2304. // Find required collapsed block by coordinates
  2305. XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = GetBlockFromPt(ptMouse);
  2306. if (pCoDrawBlk)
  2307. {
  2308. int nRow = pCoDrawBlk->collBlock.lcStart.nLine;
  2309. CollapseExpandBlock(nRow);
  2310. return nRow;
  2311. }
  2312. return 0;
  2313. }
  2314. AFX_STATIC CString AFX_CDECL TrimLeftIndent(const CString& csText)
  2315. {
  2316. CString csTrimmedText(csText);
  2317. int nLastLine = csTrimmedText.ReverseFind('n');
  2318. CString csTrimText(csTrimmedText.Right(csTrimmedText.GetLength() - nLastLine).SpanIncluding(_T("n t")));
  2319. REPLACE_S(csTrimmedText, csTrimText, _T("n"));
  2320. return csTrimmedText;
  2321. }
  2322. void CXTPSyntaxEditCtrl::ShowCollapsedToolTip(const CPoint& ptMouse)
  2323. {
  2324. if (ptMouse == m_ptPrevMouse)
  2325. {
  2326. return;
  2327. }
  2328. // Find required collapsed block by coordinates
  2329. XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = GetBlockFromPt(ptMouse);
  2330. if (pCoDrawBlk)
  2331. {
  2332. m_ptPrevMouse = ptMouse;
  2333. // set tooltip rect
  2334. CRect rcTip(ptMouse, ptMouse);
  2335. rcTip.right += 200;
  2336. rcTip.bottom += 200;
  2337. rcTip +=  CSize(18, 18);
  2338. ClientToScreen(&rcTip);
  2339. m_pToolTip->SetHoverRect(rcTip);
  2340. // set tooltip text
  2341. CString strToolText(GetCollapsedText(pCoDrawBlk));
  2342. m_pToolTip->Activate(TrimLeftIndent(strToolText));
  2343. }
  2344. // Then Hide Tip if it is displayed for some other block
  2345. if (ptMouse != m_ptPrevMouse)
  2346. {
  2347. m_pToolTip->Hide();
  2348. }
  2349. }
  2350. void CXTPSyntaxEditCtrl::OnRButtonDown(UINT nFlags, CPoint point)
  2351. {
  2352. m_bDragging = FALSE;
  2353. m_nAutoIndentCol = 0;
  2354. KillTimer(TIMER_SELECTION_ID);
  2355. int iRow, iCol;
  2356. RowColFromPoint(point, &iRow, &iCol);
  2357. if (!m_Selection.IsSelExist() || !m_Selection.IsInSel_str(iRow, iCol))
  2358. {
  2359. LPCTSTR szLineText = GetLineText(iRow);
  2360. //SetCurrentDocumentRow(iRow);
  2361. m_nDispCol = CalcValidDispCol(szLineText, iCol);
  2362. m_nCurrentCol = CalcAbsCol(szLineText, iCol);
  2363. SetCurCaretPos(iRow, m_nDispCol);
  2364. //Unselect();
  2365. m_Selection.Reset_disp(iRow, m_nDispCol);
  2366. NotifySelInit();
  2367. }
  2368. SetCapture();
  2369. if (m_Selection.IsSelExist() && m_Selection.IsInSel_str(iRow, iCol))
  2370. {
  2371. m_bRightButtonDrag = TRUE;
  2372. if (m_bEnableOleDrag)
  2373. {
  2374. NotifyParent(XTP_EDIT_NM_STARTOLEDRAG);
  2375. }
  2376. }
  2377. //  if (!m_Selection.IsSelExist() && !m_bEnableOleDrag)
  2378. //  {
  2379. //      RowColFromPoint(point, &iRow, &iCol);
  2380. //      // SetCurPos will determine valid column
  2381. //      SetCurPos(iRow, iCol);
  2382. //  }
  2383. CWnd::OnRButtonDown(nFlags, point);
  2384. NotifyMouseEvent(XTP_EDIT_NM_RBUTTONDOWN, nFlags, point);
  2385. }
  2386. void CXTPSyntaxEditCtrl::OnRButtonUp(UINT nFlags, CPoint point)
  2387. {
  2388. CWnd::OnRButtonUp(nFlags, point);
  2389. NotifyMouseEvent(XTP_EDIT_NM_RBUTTONUP, nFlags, point);
  2390. }
  2391. void CXTPSyntaxEditCtrl::Scroll(int x, int y)
  2392. {
  2393. m_bScrolling = TRUE;
  2394. if (y > 0)
  2395. ShiftCurrentVisibleRowDown(y);
  2396. else if (y < 0)
  2397. ShiftCurrentVisibleRowUp(-y);
  2398. if (x)
  2399. {
  2400. SCROLLINFO info;
  2401. ZeroMemory(&info, sizeof(SCROLLINFO));
  2402. info.cbSize = sizeof(SCROLLINFO);
  2403. info.fMask = SIF_ALL;
  2404. GetScrollInfo(SB_HORZ, &info);
  2405. int nStep = m_DrawTextProcessor.GetTextMetrics().tmAveCharWidth;
  2406. int nCurrPos = m_DrawTextProcessor.GetScrollXOffset();
  2407. nCurrPos += x * nStep;
  2408. nCurrPos = max(0, nCurrPos);
  2409. //      TRACE(_T("SCROLL.X. from %d -> %d n"), (int)m_DrawTextProcessor.GetScrollXOffset(), nCurrPos);
  2410. SetScrollPos(SB_HORZ, nCurrPos);
  2411. m_DrawTextProcessor.SetScrollXOffset(nCurrPos);
  2412. }
  2413. //RecalcVertScrollPos();
  2414. //RecalcHorzScrollPos();
  2415. Invalidate(FALSE);
  2416. UpdateWindow();
  2417. RecalcScrollBars();
  2418. int nTopDocRow = GetDocumentRow(1);
  2419. int nBottomDocRow = GetDocumentRow(GetRowPerPage());
  2420. int nCurDocRow = GetCurrentDocumentRow();
  2421. if (nCurDocRow >= nTopDocRow && nCurDocRow <= nBottomDocRow)
  2422. {
  2423. SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE, FALSE);
  2424. }
  2425. DWORD dwUpdate = 0;
  2426. if (y != 0)
  2427. dwUpdate |= XTP_EDIT_UPDATE_HORZ;
  2428. if (x != 0)
  2429. dwUpdate |= XTP_EDIT_UPDATE_VERT;
  2430. if (dwUpdate != 0)
  2431. UpdateScrollPos(dwUpdate);
  2432. m_bScrolling = FALSE;
  2433. }
  2434. BOOL CXTPSyntaxEditCtrl::RowColFromPoint(CPoint pt, int *pRow, int *pCol,
  2435. int *pDispRow, int *pDispCol, BOOL bVirtualSpace)
  2436. {
  2437. if (bVirtualSpace < 0)
  2438. bVirtualSpace = _IsVirtualSpaceActive();
  2439. int nDispRow0 = 0, nDispCol0 = 0;
  2440. if (!m_DrawTextProcessor.HitTestRow(pt.y, nDispRow0))
  2441. {
  2442. nDispRow0 = pt.y < m_DrawTextProcessor.GetTextRect().top ? 0 : m_DrawTextProcessor.GetRowsCount(FALSE) - 1;
  2443. }
  2444. int nRow = GetDocumentRow(nDispRow0 + 1);
  2445. if (nRow < 1 || nRow > GetRowCount())
  2446. nRow = nRow < 1 ? 1 : GetRowCount();
  2447. nDispRow0 = GetVisibleRow(nRow) - 1;
  2448. UpdateRowInfoInternally(nRow); // to ensure than x positions are valid
  2449. BOOL bRet = m_DrawTextProcessor.ColFromXPos(nDispRow0, pt.x, nDispCol0, bVirtualSpace);
  2450. if (!bRet)
  2451. {
  2452. if (pt.x < m_DrawTextProcessor.GetTextRect().left)
  2453. {
  2454. nDispCol0 = 0;
  2455. }
  2456. else if (pt.x > m_DrawTextProcessor.GetTextRect().right)
  2457. {
  2458. int nX1 = max(0, m_DrawTextProcessor.GetTextRect().right - 1);
  2459. m_DrawTextProcessor.ColFromXPos(nDispRow0, nX1, nDispCol0, bVirtualSpace);
  2460. }
  2461. }
  2462. int nCol0 = m_DrawTextProcessor.DispPosToStrPos(nDispRow0, nDispCol0, bVirtualSpace);
  2463. // to align to TABs positions
  2464. nDispCol0 = m_DrawTextProcessor.StrPosToDispPos(nDispRow0, nCol0, bVirtualSpace);
  2465. if (pRow)
  2466. *pRow = nRow;
  2467. if (pCol)
  2468. *pCol = nCol0 + 1;
  2469. if (pDispRow)
  2470. *pDispRow = nDispRow0 + 1;
  2471. if (pDispCol)
  2472. *pDispCol = nDispCol0 + 1;
  2473. return bRet;
  2474. }
  2475. void CXTPSyntaxEditCtrl::OnSize(UINT nType, int cx, int cy)
  2476. {
  2477. CWnd::OnSize(nType, cx, cy);
  2478. if (m_bmpCache.m_hObject)
  2479. m_bmpCache.DeleteObject();
  2480. if (!GetPaintManager()->GetFont()->GetSafeHandle())
  2481. return;
  2482. CRect rcText;
  2483. CalcEditRects(NULL, NULL, NULL, &rcText);
  2484. m_DrawTextProcessor.SetTextRect(rcText);
  2485. RecalcVertScrollPos();
  2486. Invalidate(FALSE);
  2487. UpdateWindow();
  2488. RecalcHorzScrollPos();
  2489. }
  2490. int CXTPSyntaxEditCtrl::GetScrollPos(int nBar)
  2491. {
  2492. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2493. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2494. {
  2495. return pParentWnd->GetScrollPos(nBar);
  2496. }
  2497. return CWnd::GetScrollPos(nBar);
  2498. }
  2499. void CXTPSyntaxEditCtrl::GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
  2500. {
  2501. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2502. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2503. {
  2504. pParentWnd->GetScrollRange(nBar, lpMinPos, lpMaxPos);
  2505. }
  2506. else
  2507. {
  2508. CWnd::GetScrollRange(nBar, lpMinPos, lpMaxPos);
  2509. }
  2510. }
  2511. void CXTPSyntaxEditCtrl::ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect, LPCRECT lpClipRect)
  2512. {
  2513. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2514. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2515. {
  2516. pParentWnd->ScrollWindow(xAmount, yAmount, lpRect, lpClipRect);
  2517. }
  2518. else
  2519. {
  2520. CWnd::ScrollWindow(xAmount, yAmount, lpRect, lpClipRect);
  2521. }
  2522. }
  2523. int CXTPSyntaxEditCtrl::ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, CRgn *prgnUpdate, LPRECT lpRectUpdate, UINT flags)
  2524. {
  2525. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2526. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2527. {
  2528. return pParentWnd->ScrollWindowEx(dx, dy, lpRectScroll, lpRectClip, prgnUpdate, lpRectUpdate, flags);
  2529. }
  2530. return CWnd::ScrollWindowEx(dx, dy, lpRectScroll, lpRectClip, prgnUpdate, lpRectUpdate, flags);
  2531. }
  2532. BOOL CXTPSyntaxEditCtrl::GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, UINT nMask)
  2533. {
  2534. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2535. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2536. {
  2537. return pParentWnd->GetScrollInfo(nBar, lpScrollInfo, nMask);
  2538. }
  2539. return CWnd::GetScrollInfo(nBar, lpScrollInfo, nMask);
  2540. }
  2541. int CXTPSyntaxEditCtrl::GetScrollLimit(int nBar)
  2542. {
  2543. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2544. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2545. {
  2546. return pParentWnd->GetScrollLimit(nBar);
  2547. }
  2548. return CWnd::GetScrollLimit(nBar);
  2549. }
  2550. BOOL CXTPSyntaxEditCtrl::SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw)
  2551. {
  2552. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2553. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2554. {
  2555. return pParentWnd->SetScrollInfo(nBar, lpScrollInfo, bRedraw);
  2556. }
  2557. return CWnd::SetScrollInfo(nBar, lpScrollInfo, bRedraw);
  2558. }
  2559. int CXTPSyntaxEditCtrl::SetScrollPos(int nBar, int nPos, BOOL bRedraw)
  2560. {
  2561. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2562. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2563. {
  2564. return pParentWnd->SetScrollPos(nBar, nPos, bRedraw);
  2565. }
  2566. return CWnd::SetScrollPos(nBar, nPos, bRedraw);
  2567. }
  2568. void CXTPSyntaxEditCtrl::SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw)
  2569. {
  2570. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2571. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2572. {
  2573. pParentWnd->SetScrollRange(nBar, nMinPos, nMaxPos, bRedraw);
  2574. }
  2575. else
  2576. {
  2577. CWnd::SetScrollRange(nBar, nMinPos, nMaxPos, bRedraw);
  2578. }
  2579. }
  2580. void CXTPSyntaxEditCtrl::ShowScrollBar(UINT nBar, BOOL bShow)
  2581. {
  2582. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2583. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2584. {
  2585. pParentWnd->ShowScrollBar(nBar, bShow);
  2586. }
  2587. else
  2588. {
  2589. CWnd::ShowScrollBar(nBar, bShow);
  2590. }
  2591. }
  2592. void CXTPSyntaxEditCtrl::EnableScrollBarCtrl(int nBar, BOOL bEnable)
  2593. {
  2594. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2595. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2596. {
  2597. pParentWnd->EnableScrollBarCtrl(nBar, bEnable);
  2598. DWORD dwScrollBar = (nBar == SB_HORZ) ? WS_HSCROLL : 0;
  2599. dwScrollBar |= (nBar == SB_VERT) ? WS_VSCROLL : 0;
  2600. dwScrollBar |= (nBar == SB_BOTH) ? (WS_HSCROLL | WS_VSCROLL) : 0;
  2601. _EnableScrollBarNotify((DWORD)dwScrollBar, bEnable ? (DWORD)dwScrollBar : 0);
  2602. }
  2603. else
  2604. {
  2605. CWnd::EnableScrollBarCtrl(nBar, bEnable);
  2606. }
  2607. }
  2608. CScrollBar* CXTPSyntaxEditCtrl::GetScrollBarCtrl(int nBar) const
  2609. {
  2610. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2611. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2612. {
  2613. return pParentWnd->GetScrollBarCtrl(nBar);
  2614. }
  2615. return CWnd::GetScrollBarCtrl(nBar);
  2616. }
  2617. void CXTPSyntaxEditCtrl::RepositionBars(UINT nIDFirst, UINT nIDLast, UINT nIDLeftOver, UINT nFlag, LPRECT lpRectParam, LPCRECT lpRectClient, BOOL bStretch)
  2618. {
  2619. CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
  2620. if (pParentWnd != NULL && IsCreateScrollbarOnParent())
  2621. {
  2622. pParentWnd->RepositionBars(nIDFirst, nIDLast, nIDLeftOver, nFlag, lpRectParam, lpRectClient, bStretch);
  2623. }
  2624. else
  2625. {
  2626. CWnd::RepositionBars(nIDFirst, nIDLast, nIDLeftOver, nFlag, lpRectParam, lpRectClient, bStretch);
  2627. }
  2628. }
  2629. BOOL CXTPSyntaxEditCtrl::DeleteSelection()
  2630. {
  2631. if (!m_Selection.IsSelExist())
  2632. return TRUE;
  2633. int nFlags = (m_Selection.bBlockSelectionMode ? xtpEditTextAsBlock : 0) | xtpEditDispCol;
  2634. if (!DeleteBuffer(m_Selection.GetNormalStart_disp().nLine, m_Selection.GetNormalStart_disp().nCol,
  2635.   m_Selection.GetNormalEnd_disp().nLine, m_Selection.GetNormalEnd_disp().nCol,
  2636.   nFlags))
  2637. {
  2638. return FALSE;
  2639. }
  2640. m_Selection.Reset_disp(m_Selection.GetNormalStart_disp().nLine, m_Selection.GetNormalStart_disp().nCol);
  2641. SetCurrentDocumentRow(m_Selection.GetNormalStart_disp().nLine);
  2642. EnsureVisibleRow(GetCurrentDocumentRow());
  2643. SetCurCaretPos(GetCurrentDocumentRow(), m_Selection.GetStart_disp().nCol);
  2644. Invalidate(FALSE);
  2645. return TRUE;
  2646. }
  2647. BOOL CXTPSyntaxEditCtrl::DeleteBuffer(int iRowFrom, int iColFrom, int iRowTo, int iColTo,
  2648.  int nFlags )
  2649. {
  2650. int iTempRow1 = iRowFrom, iTempRow2 = iRowTo;
  2651. int iTempCol1 = iColFrom, iTempCol2 = iColTo;
  2652. if (iTempRow2 < iTempRow1)
  2653. {
  2654. iRowFrom = iTempRow2;
  2655. iColFrom = iTempCol2;
  2656. iRowTo = iTempRow1;
  2657. iColTo = iTempCol1;
  2658. }
  2659. else if (iTempRow1 == iTempRow2)
  2660. {
  2661. iColFrom = min(iTempCol1, iTempCol2);
  2662. iColTo = max(iTempCol1, iTempCol2);
  2663. }
  2664. if ((nFlags & xtpEditTextAsBlock) &&
  2665. (iColTo < iColFrom))
  2666. {
  2667. // swap them
  2668. int nTemp = iColTo;
  2669. iColTo = iColFrom;
  2670. iColFrom = nTemp;
  2671. }
  2672. if (!CanEditDoc())
  2673. {
  2674. return FALSE;
  2675. }
  2676. BOOL bDispCol = (nFlags & xtpEditDispCol) != 0;
  2677. int nColFrom_str = bDispCol ? CalcAbsCol(iRowFrom, iColFrom) : iColFrom;
  2678. int nColTo_str = bDispCol ? CalcAbsCol(iRowTo, iColTo) : iColTo;
  2679. //**----------------------
  2680. OnBeforeEditChanged(iRowFrom, nColFrom_str);
  2681. //**----------------------
  2682. ASSERT((nFlags & xtpEditTextAsBlock) && bDispCol || !(nFlags & xtpEditTextAsBlock));
  2683. if ((nFlags & xtpEditTextAsBlock) && iRowFrom != iRowTo)
  2684. {
  2685. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(TRUE);
  2686. for (int i = iRowFrom; i <= iRowTo; i++)
  2687. {
  2688. m_pBuffer->DeleteText(i, iColFrom, i, iColTo, TRUE, bDispCol);
  2689. }
  2690. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  2691. m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_DELETE_TEXT_BLOCK);
  2692. }
  2693. else
  2694. {
  2695. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  2696. m_pBuffer->DeleteText(iRowFrom, iColFrom, iRowTo, iColTo, TRUE, bDispCol);
  2697. }
  2698. LPCTSTR szLineText = GetLineText(iRowFrom);
  2699. SetCurrentDocumentRow(iRowFrom);
  2700. m_nCurrentCol = nColFrom_str;
  2701. m_nDispCol = CalcDispCol(szLineText, m_nCurrentCol);
  2702. //**----------------------
  2703. OnEditChanged(iRowFrom, nColFrom_str, iRowTo, nColTo_str, xtpEditActDelete);
  2704. //**----------------------
  2705. UINT uFlags = XTP_EDIT_EDITACTION_DELETEROW | XTP_EDIT_EDITACTION_MODIFYROW;
  2706. NotifyEditChanged(iRowFrom, iRowTo, uFlags);
  2707. SetDocModified();
  2708. RecalcScrollBars();
  2709. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
  2710. if (nFlags & xtpEditRedraw)
  2711. {
  2712. Invalidate(FALSE);
  2713. UpdateWindow();
  2714. }
  2715. return TRUE;
  2716. }
  2717. BOOL CXTPSyntaxEditCtrl::DeleteChar(int iRow, int iCol, XTPSyntaxEditDeletePos pos)
  2718. {
  2719. CString strText;
  2720. int iRowTo = iRow, iColTo = iCol;
  2721. if (pos == xtpEditDelPosAfter) // If deleting using DEL key
  2722. {
  2723. GetLineText(iRow, strText);
  2724. int nLineLen = (int)_tcsclen(strText);
  2725. if (iCol > nLineLen)
  2726. {
  2727. iRowTo = iRow + 1;
  2728. iColTo = 1;
  2729. if (iRowTo > GetRowCount())
  2730. return FALSE;
  2731. int nColFrom = nLineLen + 1;
  2732. int nAdditionalTabs = 0;
  2733. int nDispCol2 = CalcDispCol(strText, iCol);
  2734. int nDispCol0  = CalcDispCol(strText, nColFrom);
  2735. int nDC = nDispCol0 + GetTabSize() - (nDispCol0 -1) % GetTabSize();
  2736. if (nDC <= nDispCol2)
  2737. nAdditionalTabs++;
  2738. else
  2739. nDC = nDispCol0;
  2740. for(; nDC + GetTabSize() <= nDispCol2; nDC += GetTabSize())
  2741. nAdditionalTabs++;
  2742. int nAdditionalSpaces = max(0, nDispCol2 - nDC);
  2743. CString strTabs = CString(_T('t'), nAdditionalTabs) +  CString(_T(' '), nAdditionalSpaces);
  2744. //**----------------------
  2745. OnBeforeEditChanged(iRow, nColFrom);
  2746. XTP_EDIT_LINECOL lcFinal;
  2747. m_pBuffer->InsertText(strTabs, iRow, nColFrom, TRUE, &lcFinal);
  2748. m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_FORMAT);
  2749. OnEditChanged(iRow, nColFrom, iRow, lcFinal.nCol, xtpEditActInsert);
  2750. //**----------------------
  2751. iCol = lcFinal.nCol;
  2752. }
  2753. else
  2754. iColTo++;
  2755. }
  2756. else // If deleting using back space
  2757. {
  2758. if (iCol == 1)
  2759. {
  2760. if (iRow > 1)
  2761. {
  2762. iRow--;
  2763. // if we are in the end of collapsed block, expand it...
  2764. CXTPSyntaxEditRowsBlockArray arCoBlocks;
  2765. GetCollapsableBlocksInfo(iRow, arCoBlocks);
  2766. int nCount = (int)arCoBlocks.GetSize();
  2767. for(int i = 0; i < nCount; i++)
  2768. {
  2769. XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
  2770. if (coBlk.lcEnd.nLine == iRow) // Expand!
  2771. {
  2772. if (HasRowMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed))
  2773. GetLineMarksManager()->DeleteLineMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed);
  2774. }
  2775. }
  2776. //GetLineText(iRow, strText);
  2777. //iCol = (int)_tcsclen(strText) + 1;
  2778. iCol = m_pBuffer->GetLineTextLengthC(iRow) + 1;
  2779. }
  2780. else
  2781. return FALSE;
  2782. }
  2783. else
  2784. iCol--;
  2785. }
  2786. if (!DeleteBuffer(iRow, iCol, iRowTo, iColTo))
  2787. return FALSE;
  2788. return TRUE;
  2789. }
  2790. BOOL CXTPSyntaxEditCtrl::DoUndoRedo(int nActionsCount, BOOL bUndoRedo)
  2791. {
  2792. CWaitCursor wait;
  2793. if (!CanEditDoc())
  2794. return FALSE;
  2795. CXTPSyntaxEditUndoRedoManager* pUndoMgr = m_pBuffer->GetUndoRedoManager();
  2796. if (!pUndoMgr)
  2797. return FALSE;
  2798. m_Selection.Reset_disp(m_Selection.GetEnd_disp().nLine, m_Selection.GetEnd_disp().nCol);
  2799. m_nAutoIndentCol = 0;
  2800. int nCurDocRow = GetCurrentDocumentRow();
  2801. XTP_EDIT_LINECOL lcTotalFrom = XTP_EDIT_LINECOL::MAXPOS;
  2802. XTP_EDIT_LINECOL lcTotalTo = XTP_EDIT_LINECOL::MINPOS;
  2803. for (int nAction = 0; nAction < nActionsCount; nAction++)
  2804. {
  2805. XTP_EDIT_LINECOL lcFrom, lcTo;
  2806. // perform undo
  2807. int nEditAction = bUndoRedo ?
  2808. pUndoMgr->DoUndo(lcFrom, lcTo, this) :
  2809. pUndoMgr->DoRedo(lcFrom, lcTo, this);
  2810. // perform some total calculations
  2811. lcTotalFrom = min(lcTotalFrom, lcFrom);
  2812. lcTotalTo = max(lcTotalTo, lcTo);
  2813. // TODO: ???????????????????????????????????
  2814. // send update notifications
  2815. // Commented out to eliminate double call of OnEditChanged that
  2816. // leads to improper calculation of collapsible blocks borders
  2817. //      if (nEditAction & XTP_EDIT_EDITACTION_INSERTTEXT)
  2818. //      {
  2819. //          OnEditChanged(lcFrom, lcTo, xtpEditActInsert);
  2820. //      }
  2821. //      else if (nEditAction & XTP_EDIT_EDITACTION_DELETETEXT)
  2822. //      {
  2823. //          OnEditChanged(lcFrom, lcTo, xtpEditActDelete);
  2824. //      }
  2825. NotifyEditChanged(lcFrom.nLine, lcTo.nLine, nEditAction);
  2826. }
  2827. int nRowsAffected = lcTotalTo.nLine - lcTotalFrom.nLine;
  2828. m_nDispCol = CalcDispCol(GetCurrentDocumentRow(), m_nCurrentCol);
  2829. RecalcScrollBars();
  2830. if (GetCurrentDocumentRow() > GetRowCount())
  2831. {
  2832. SetCurrentDocumentRow(GetRowCount());
  2833. m_nCurrentCol = m_nDispCol = 1;
  2834. }
  2835. nCurDocRow = GetCurrentDocumentRow();
  2836. if (nActionsCount > 1)
  2837. {
  2838. ValidateCol(nCurDocRow, m_nDispCol, m_nCurrentCol);
  2839. SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE/*, FALSE*/);
  2840. }
  2841. nCurDocRow = GetCurrentDocumentRow();
  2842. if ((nCurDocRow > 0 && m_nCurrentCol > 0) ||
  2843. !(nRowsAffected == 0 && nActionsCount == 1))
  2844. {
  2845. SetCurCaretPos(nCurDocRow, m_nDispCol);
  2846. }
  2847. Invalidate(FALSE);
  2848. UpdateWindow();
  2849. UpdateScrollPos();
  2850. SetDocModified(m_pBuffer->IsModified());
  2851. return TRUE;
  2852. }
  2853. BOOL CXTPSyntaxEditCtrl::Undo(int nActionsCount)
  2854. {
  2855. if (CanUndo())
  2856. {
  2857. return DoUndoRedo(nActionsCount, TRUE);
  2858. }
  2859. return FALSE;
  2860. }
  2861. BOOL CXTPSyntaxEditCtrl::Redo(int nActionsCount)
  2862. {
  2863. if (CanRedo())
  2864. {
  2865. return DoUndoRedo(nActionsCount, FALSE);
  2866. }
  2867. return FALSE;
  2868. }
  2869. BOOL CXTPSyntaxEditCtrl::CanUndo()
  2870. {
  2871. if (m_pBuffer && m_pBuffer->GetUndoRedoManager())
  2872. return CanEditDoc() && m_pBuffer->GetUndoRedoManager()->CanUndo();
  2873. return FALSE;
  2874. }
  2875. BOOL CXTPSyntaxEditCtrl::CanRedo()
  2876. {
  2877. if (m_pBuffer && m_pBuffer->GetUndoRedoManager())
  2878. return CanEditDoc() && m_pBuffer->GetUndoRedoManager()->CanRedo();
  2879. return FALSE;
  2880. }
  2881. void CXTPSyntaxEditCtrl::Cut()
  2882. {
  2883. if (m_Selection.IsSelExist())
  2884. {
  2885. Copy();
  2886. DeleteSelection();
  2887. UpdateWindow();
  2888. }
  2889. }
  2890. void CXTPSyntaxEditCtrl::Copy()
  2891. {
  2892. if (!m_Selection.IsSelExist())
  2893. return;
  2894. CWaitCursor wait;
  2895. if (!OpenClipboard())
  2896. {
  2897. #ifdef _DEBUG
  2898. LPVOID lpMsgBuf;
  2899. ::FormatMessage(
  2900. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2901. FORMAT_MESSAGE_FROM_SYSTEM |
  2902. FORMAT_MESSAGE_IGNORE_INSERTS,
  2903. NULL,
  2904. ::GetLastError(),
  2905. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  2906. (LPTSTR) &lpMsgBuf,
  2907. 0,
  2908. NULL
  2909. );
  2910. // Process any inserts in lpMsgBuf.
  2911. // ...
  2912. // Display the string.
  2913. AfxMessageBox((LPCTSTR)lpMsgBuf, MB_OK | MB_ICONINFORMATION );
  2914. // Free the buffer.
  2915. ::LocalFree( lpMsgBuf );
  2916. #endif
  2917. return;
  2918. }
  2919. // prepare clipboard
  2920. ::EmptyClipboard();
  2921. // retrieve the text string from buffer
  2922. CMemFile file(CalcAveDataSize(m_Selection.GetNormalStart_str().nLine,
  2923.   m_Selection.GetNormalEnd_str().nLine));
  2924. BOOL bRes = m_pBuffer->GetBuffer(m_Selection.GetNormalStart_disp(),
  2925.  m_Selection.GetNormalEnd_disp(), file,
  2926.  m_Selection.bBlockSelectionMode, TRUE);
  2927. if (!bRes)
  2928. return;
  2929. // Copy the buffer to clipboard
  2930. DWORD dwBytes = (DWORD)file.GetLength();
  2931. BYTE *pBytes = file.Detach();
  2932. HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwBytes+sizeof(TCHAR));
  2933. if (!hMem)
  2934. return;
  2935. LPVOID lpSource = (LPVOID)::GlobalLock(hMem);
  2936. if (!lpSource)
  2937. return;
  2938. MEMCPY_S(lpSource, pBytes, dwBytes);
  2939. ::ZeroMemory(((BYTE *)lpSource+dwBytes), sizeof(TCHAR));
  2940. free(pBytes);
  2941. UINT uCodePage = m_pBuffer->GetCodePage();
  2942. #ifdef _UNICODE
  2943. // Determine the byte requirement
  2944. int nLen  = ::WideCharToMultiByte(uCodePage, 0, (LPWSTR)lpSource, -1, NULL, 0, NULL, NULL);
  2945. HGLOBAL hMBCSMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (nLen + 2));    // Maximum number of bytes is dwBytes
  2946. if (!hMBCSMem)
  2947. {
  2948. CloseClipboard();
  2949. return;
  2950. }
  2951. LPSTR lpMBCSSource = (LPSTR)::GlobalLock(hMBCSMem);
  2952. if (!lpMBCSSource)
  2953. return;
  2954. int nBytes = ::WideCharToMultiByte(uCodePage, 0, (LPWSTR)lpSource, -1, lpMBCSSource, nLen, NULL, NULL);
  2955. ASSERT(nBytes <= (int)dwBytes);
  2956. lpMBCSSource[nBytes] = _T('');
  2957. ::GlobalUnlock(hMem);
  2958. ::GlobalUnlock(hMBCSMem);
  2959. // lpSource is Unicode text
  2960. ::SetClipboardData(CF_UNICODETEXT, hMem);
  2961. ::SetClipboardData(CF_TEXT, hMBCSMem);
  2962. ::SetClipboardData(CF_OEMTEXT, hMBCSMem);
  2963. #else
  2964. int nUBytes = (dwBytes+2) * sizeof(WCHAR);
  2965. HGLOBAL hUnicodeMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, nUBytes);
  2966. if (!hUnicodeMem)
  2967. {
  2968. CloseClipboard();
  2969. return;
  2970. }
  2971. LPWSTR lpWSource = (LPWSTR)::GlobalLock(hUnicodeMem);
  2972. if (!lpWSource)
  2973. {
  2974. CloseClipboard();
  2975. return;
  2976. }
  2977. int nLen = ::MultiByteToWideChar(uCodePage, 0, (LPCSTR)lpSource, -1, lpWSource, nUBytes);
  2978. ASSERT(nLen <= (int)(nUBytes/sizeof(WCHAR)));
  2979. lpWSource[nLen] = _T('');
  2980. ::GlobalUnlock(hMem);
  2981. ::GlobalUnlock(hUnicodeMem);
  2982. // lpSource is MBCS text
  2983. ::SetClipboardData(CF_TEXT, hMem);
  2984. ::SetClipboardData(CF_OEMTEXT, hMem);
  2985. ::SetClipboardData(CF_UNICODETEXT, hUnicodeMem);
  2986. #endif
  2987. if (m_Selection.bBlockSelectionMode)
  2988. {
  2989. HGLOBAL hMem_BLK = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
  2990. if (!hMem_BLK)
  2991. {
  2992. CloseClipboard();
  2993. return;
  2994. }
  2995. BYTE* pMem_BLK = (BYTE*)::GlobalLock(hMem_BLK);
  2996. if (pMem_BLK)
  2997. {
  2998. *pMem_BLK = 1;
  2999. }
  3000. ::GlobalUnlock(hMem_BLK);
  3001. CLIPFORMAT uCF_MSDEVColumnSelect = (CLIPFORMAT)::RegisterClipboardFormat(XTP_EDIT_CFMSDEVCOLSEL);
  3002. ::SetClipboardData(uCF_MSDEVColumnSelect, hMem_BLK);
  3003. }
  3004. CloseClipboard();
  3005. }
  3006. void CXTPSyntaxEditCtrl::Paste()
  3007. {
  3008. CWaitCursor wait;
  3009. if (!OpenClipboard())
  3010. return;
  3011. BOOL bCBTextIsBlock = FALSE;
  3012. CLIPFORMAT uCF_MSDEVColumnSelect = (CLIPFORMAT)::RegisterClipboardFormat(XTP_EDIT_CFMSDEVCOLSEL);
  3013. HANDLE hMem_TextBlok = ::GetClipboardData(uCF_MSDEVColumnSelect);
  3014. if (hMem_TextBlok)
  3015. {
  3016. int nSize = (int)::GlobalSize(hMem_TextBlok);
  3017. BYTE* arColBlk = (BYTE*)::GlobalLock(hMem_TextBlok);
  3018. if (arColBlk && nSize)
  3019. {
  3020. bCBTextIsBlock = TRUE;
  3021. //TRACE(_T("MSDEVColumnSelect data [size=%d] = %d n"), nSize, (int)arColBlk[0]);
  3022. }
  3023. }
  3024. #ifdef _UNICODE
  3025. HANDLE hMem = ::GetClipboardData(CF_UNICODETEXT);
  3026. #else
  3027. HANDLE hMem = ::GetClipboardData(CF_TEXT);
  3028. #endif
  3029. if (!hMem)
  3030. {
  3031. return;
  3032. }
  3033. LPTSTR szData = (LPTSTR)::GlobalLock(hMem);
  3034. BOOL bReplace = GetTabWithSpace();
  3035. BOOL bOverwrite = m_pBuffer->GetOverwriteFlag();
  3036. SetTabWithSpace(FALSE);
  3037. m_pBuffer->SetOverwriteFlag(FALSE);
  3038. if (bCBTextIsBlock)
  3039. {
  3040. InsertTextBlock(szData, GetCurrentDocumentRow(), m_nCurrentCol, m_Selection.IsSelExist());
  3041. }
  3042. else
  3043. {
  3044. InsertString(szData, GetCurrentDocumentRow(), m_nCurrentCol, m_Selection.IsSelExist());
  3045. }
  3046. SetTabWithSpace(bReplace);
  3047. m_pBuffer->SetOverwriteFlag(bOverwrite);
  3048. m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_PASTE);
  3049. ::GlobalUnlock(hMem);
  3050. CloseClipboard();
  3051. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
  3052. SetDocModified();
  3053. UpdateScrollPos(XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
  3054. UpdateWindow();
  3055. }
  3056. void CXTPSyntaxEditCtrl::SetRowText(int nRow, LPCTSTR pcszText, BOOL bCanUndo)
  3057. {
  3058. if (!m_pBuffer)
  3059. return;
  3060. int nRowLen = m_pBuffer->GetLineTextLengthC(nRow, FALSE);
  3061. if (nRowLen)
  3062. {
  3063. //**----------------------
  3064. OnBeforeEditChanged(nRow, 1);
  3065. //**----------------------
  3066. if (bCanUndo)
  3067. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  3068. m_pBuffer->DeleteText(nRow, 1, nRow, nRowLen + 1, bCanUndo, FALSE);
  3069. //**----------------------
  3070. OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActDelete);
  3071. //**----------------------
  3072. }
  3073. //**----------------------
  3074. OnBeforeEditChanged(nRow, 1);
  3075. //**----------------------
  3076. if (bCanUndo)
  3077. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  3078. //XTP_EDIT_LINECOL finalLC;
  3079. m_pBuffer->InsertText(pcszText, nRow, 1, bCanUndo);//finalLC);
  3080. //**----------------------
  3081. OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActInsert);
  3082. //**----------------------
  3083. NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_MODIFYROW);
  3084. }
  3085. void CXTPSyntaxEditCtrl::InsertRow(int nRow, LPCTSTR pcszText, BOOL bCanUndo)
  3086. {
  3087. if (!m_pBuffer)
  3088. return;
  3089. CString strLine = pcszText;
  3090. strLine += m_pBuffer->GetCurCRLF();
  3091. //**----------------------
  3092. OnBeforeEditChanged(nRow, 1);
  3093. //**----------------------
  3094. if (bCanUndo)
  3095. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  3096. //XTP_EDIT_LINECOL finalLC;
  3097. m_pBuffer->InsertText(pcszText, nRow, 1, bCanUndo);//finalLC);
  3098. //**----------------------
  3099. OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActInsert);
  3100. //**----------------------
  3101. NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_INSERTROW);
  3102. }
  3103. void CXTPSyntaxEditCtrl::RemoveRow(int nRow, BOOL bCanUndo)
  3104. {
  3105. if (!m_pBuffer)
  3106. return;
  3107. //**----------------------
  3108. OnBeforeEditChanged(nRow, 1);
  3109. //**----------------------
  3110. if (bCanUndo)
  3111. m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
  3112. m_pBuffer->RemoveLine(nRow, bCanUndo);
  3113. //**----------------------
  3114. OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActDelete);
  3115. //**----------------------
  3116. NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_DELETEROW);
  3117. }
  3118. void CXTPSyntaxEditCtrl::OnSetFocus(CWnd* pOldWnd)
  3119. {
  3120. CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
  3121. //  TRACE (_T("CXTPSyntaxEditCtrl::OnSetFocus. this=%x, pOldWnd=%x n"), this, pOldWnd);
  3122. ::DestroyCaret();
  3123. m_bFocused = TRUE;
  3124. Invalidate(FALSE);
  3125. RestoreCursor();
  3126. NotifyCurRowCol(GetCurrentDocumentRow(), m_nDispCol);
  3127. UpdateWindow();
  3128. CWnd::OnSetFocus(pOldWnd);
  3129. #ifdef XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS
  3130. XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS(this, this, TRUE)
  3131. #endif
  3132. }
  3133. void CXTPSyntaxEditCtrl::OnKillFocus(CWnd* pNewWnd)
  3134. {
  3135. CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
  3136. CWnd::OnKillFocus(pNewWnd);
  3137. ::DestroyCaret();
  3138. m_pAutoComplete->Hide();
  3139. m_bFocused = FALSE;
  3140. #ifdef XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS
  3141. XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS(this, this, FALSE)
  3142. #endif
  3143. }
  3144. BOOL CXTPSyntaxEditCtrl::OnNcActivate(BOOL bActive)
  3145. {
  3146. return CWnd::OnNcActivate(bActive);
  3147. }
  3148. int CXTPSyntaxEditCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  3149. {
  3150. //  SetFocus();
  3151. return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
  3152. }
  3153. BOOL CXTPSyntaxEditCtrl::IsSelectionExist()
  3154. {
  3155. return m_Selection.IsSelExist();
  3156. }
  3157. void CXTPSyntaxEditCtrl::SelectAll()
  3158. {
  3159. int nLastRow = GetRowCount();
  3160. LPCTSTR szLineText = GetLineText(nLastRow);
  3161. const int nEndCol = (int)_tcsclen(szLineText) + 1;
  3162. SetCurrentDocumentRow(nLastRow);
  3163. m_nCurrentCol = nEndCol;
  3164. m_nDispCol = CalcDispCol(szLineText, m_nCurrentCol);
  3165. m_Selection.Reset_disp(1, 1);
  3166. m_Selection.SetEnd_disp(nLastRow, m_nDispCol);
  3167. m_nAutoIndentCol = 0;
  3168. SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
  3169. }
  3170. void CXTPSyntaxEditCtrl::SetFontIndirect(LPLOGFONT pLogfont, BOOL bUpdateReg/*=FALSE*/)
  3171. {
  3172. GetPaintManager()->CreateFontIndirect(pLogfont, bUpdateReg);
  3173. CWindowDC dc(NULL);