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

对话框与窗口

开发平台:

Visual C++

  1. // XTPSyntaxEditBufferManager.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/XTPColorManager.h"
  24. #include "Common/XTPNotifyConnection.h"
  25. #include "Common/XTPSmartPtrInternalT.h"
  26. #include "Common/XTPVC80Helpers.h"
  27. #include "Common/XTPVC50Helpers.h"
  28. // syntax editor includes
  29. #include "XTPSyntaxEditDefines.h"
  30. #include "XTPSyntaxEditStruct.h"
  31. #include "XTPSyntaxEditUndoManager.h"
  32. #include "XTPSyntaxEditLineMarksManager.h"
  33. #include "XTPSyntaxEditLexPtrs.h"
  34. #include "XTPSyntaxEditLexClassSubObjT.h"
  35. #include "XTPSyntaxEditTextIterator.h"
  36. #include "XTPSyntaxEditSectionManager.h"
  37. #include "XTPSyntaxEditLexCfgFileReader.h"
  38. #include "XTPSyntaxEditLexClassSubObjDef.h"
  39. #include "XTPSyntaxEditLexClass.h"
  40. #include "XTPSyntaxEditLexParser.h"
  41. #include "XTPSyntaxEditLexColorFileReader.h"
  42. #include "XTPSyntaxEditBufferManager.h"
  43. #include "XTPSyntaxEditCtrl.h"
  44. #include <malloc.h>
  45. #ifdef _DEBUG
  46. #define new DEBUG_NEW
  47. #undef THIS_FILE
  48. static char THIS_FILE[] = __FILE__;
  49. #endif
  50. IMPLEMENT_DYNCREATE(CXTPSyntaxEditBufferManager, CCmdTarget)
  51. //===========================================================================
  52. // CRLF styles
  53. static const char *g_pcszCRLFStyles[] =
  54. {
  55. "x0Dx0A",         //  DOS/Windows style
  56. "x0Ax0D",         //  UNIX style
  57. "x0A"              //  Macintosh style
  58. };
  59. static const WCHAR *g_pcszCRLFStylesW[] =
  60. {
  61. L"x0Dx0A",        //  DOS/Windows style
  62. L"x0Ax0D",        //  UNIX style
  63. L"x0A"             //  Macintosh style
  64. };
  65. //===========================================================================
  66. // CXTPSyntaxEditBufferManager
  67. //===========================================================================
  68. CXTPSyntaxEditConfigurationManagerPtr CXTPSyntaxEditBufferManager::s_ptrLexConfigurationManager_Default;
  69. LONG CXTPSyntaxEditBufferManager::s_dwLexConfigurationManager_DefaultRefs = 0;
  70. //===========================================================================
  71. template <class _TFileChar>
  72. inline _TFileChar* _T_GetCRLF(int nCRLFLenStyle, _TFileChar c = 0)
  73. {
  74. UNREFERENCED_PARAMETER(c);
  75. _TFileChar** ppStyles = NULL;
  76. if (sizeof(_TFileChar) == 1)
  77. {
  78. ppStyles = (_TFileChar**)g_pcszCRLFStyles;
  79. }
  80. else
  81. {
  82. ASSERT(sizeof(_TFileChar) == 2);
  83. ppStyles = (_TFileChar**)g_pcszCRLFStylesW;
  84. }
  85. if (nCRLFLenStyle < 0 || nCRLFLenStyle >= _countof(g_pcszCRLFStyles))
  86. {
  87. ASSERT(FALSE);
  88. nCRLFLenStyle = 0;
  89. }
  90. return ppStyles[nCRLFLenStyle];
  91. }
  92. template <class _TFileChar>
  93. inline int _T_StrLen(_TFileChar* pStr)
  94. {
  95. if (sizeof(_TFileChar) == 1)
  96. {
  97. return (int)strlen((CHAR*)pStr);
  98. }
  99. ASSERT(sizeof(_TFileChar) == 2);
  100. return (int)wcslen((WCHAR*)pStr);
  101. }
  102. CString GetFileExtention(CFile* pFile)
  103. {
  104. TCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFileName[_MAX_FNAME], szExt[_MAX_EXT];
  105. szDrive[0]    = _T('');
  106. szDir[0]      = _T('');
  107. szFileName[0] = _T('');
  108. szExt[0]      = _T('');
  109. SPLITPATH_S(pFile->GetFileName(), szDrive, szDir, szFileName, szExt);
  110. return szExt;
  111. }
  112. //---------------------------------------------------------------------------
  113. int _cdecl _Compare_BYTE(const void* pb1, const void* pb2)
  114. {
  115. if ( *((BYTE*)pb1) > *((BYTE*)pb2) )
  116. return 1;
  117. if ( *((BYTE*)pb2) > *((BYTE*)pb1) )
  118. return -1;
  119. return 0;
  120. }
  121. BOOL _IsUnicodeFile_heuristic(CFile *pFile)
  122. {
  123. pFile->SeekToBegin();
  124. const int cnBufferSize = 1024;
  125. BYTE arData[cnBufferSize];
  126. BYTE arData0[cnBufferSize/2];
  127. BYTE arData1[cnBufferSize/2];
  128. UINT uDataSize = pFile->Read(arData, cnBufferSize);
  129. pFile->SeekToBegin();
  130. UINT uDataXcount = uDataSize / 2;
  131. UINT i;
  132. for (i = 0; i < uDataXcount; i++)
  133. {
  134. arData0[i] = arData[i*2];
  135. arData1[i] = arData[i*2 + 1];
  136. if ((arData0[i] == 0xA || arData0[i] == 0xD) && arData1[i] == 0)
  137. return TRUE;
  138. }
  139. qsort(arData0, uDataXcount, sizeof(BYTE), _Compare_BYTE);
  140. qsort(arData1, uDataXcount, sizeof(BYTE), _Compare_BYTE);
  141. int nVariation0 = 0;
  142. int nVariation1 = 0;
  143. int nSmallNumbers1 = 0;
  144. for (i = 1; i < uDataXcount; i++)
  145. {
  146. if (arData0[i] != arData0[i - 1])
  147. nVariation0++;
  148. }
  149. for (i = 1; i < uDataXcount; i++)
  150. {
  151. if (arData1[i] != arData1[i - 1])
  152. nVariation1++;
  153. if (arData1[i] < 9)
  154. nSmallNumbers1++;
  155. }
  156. if (uDataXcount < 10)
  157. return nVariation0 > nVariation1 || nSmallNumbers1;
  158. int nVariationDiff = nVariation0 * 100 / max(1, nVariation1);
  159. int nSmallNumbersPc = nSmallNumbers1 * 100 / max(1, uDataXcount);
  160. return nVariationDiff > 150 || nSmallNumbersPc > 3;
  161. }
  162. BOOL IsUnicodeFile(CFile *pFile)
  163. {
  164. pFile->SeekToBegin();
  165. WORD wPrefix;
  166. UINT uReaded = pFile->Read(&wPrefix, 2);
  167. if (uReaded == 2 && wPrefix == 0xFEFF)
  168. {
  169. return TRUE;
  170. }
  171. DWORD_PTR dwFileSize = (DWORD_PTR)pFile->GetLength();
  172. if (dwFileSize % 2 == 0)
  173. {
  174. return _IsUnicodeFile_heuristic(pFile);
  175. }
  176. pFile->SeekToBegin();
  177. return FALSE;
  178. }
  179. //===========================================================================
  180. template <class _TFileChar>
  181. inline int _T_GetCRLFStyle(_TFileChar chEOL1, _TFileChar chEOL2, int* pnCRLFLen)
  182. {
  183. int nCRLFLen = 1;
  184. int nCRLFStyle = xtpEditCRLFStyleUnknown;
  185. if (chEOL1 == 13)
  186. {
  187. //ASSERT(chEOL2 == 10); // incorrect text - reversed DOS CRLF style
  188. nCRLFLen = chEOL2 == 10 ? 2 : 1;
  189. nCRLFStyle = xtpEditCRLFStyleDos;
  190. }
  191. else if (chEOL1 == 10)
  192. {
  193. if (chEOL2 == 13)
  194. {
  195. nCRLFLen = 2;
  196. nCRLFStyle = xtpEditCRLFStyleUnix;
  197. }
  198. else
  199. {
  200. nCRLFLen = 1;
  201. nCRLFStyle = xtpEditCRLFStyleMac;
  202. }
  203. }
  204. if (pnCRLFLen)
  205. {
  206. *pnCRLFLen = nCRLFLen;
  207. }
  208. return nCRLFStyle;
  209. }
  210. template <class _TFileChar, int _cnMaxStr2_chars>
  211. inline void _T_StrAdd(CString& rStr, _TFileChar* pStr2, UINT uCodePage)
  212. {
  213. if (sizeof(TCHAR) == 2 && sizeof(_TFileChar) == 1)
  214. {
  215. const int cnBuf2Size = _cnMaxStr2_chars+1;
  216. WCHAR szBuf2[cnBuf2Size];
  217. ::ZeroMemory(szBuf2, sizeof(szBuf2));
  218. int nLen = MultiByteToWideChar(uCodePage, 0, (LPCSTR)pStr2, -1, szBuf2, cnBuf2Size-1);
  219. ASSERT(nLen <= cnBuf2Size-1);
  220. rStr += szBuf2;
  221. }
  222. else
  223. {
  224. //ASSERT(sizeof(TCHAR) == sizeof(_TFileChar));
  225. UNREFERENCED_PARAMETER(uCodePage);
  226. rStr += pStr2;
  227. }
  228. }
  229. //===========================================================================
  230. template <class _TFileChar>
  231. BOOL _T_ReadStringFromFile(CFile *pFile, CString& rstrString, int& rnCRLFStyle,
  232. UINT uCodePage, _TFileChar c = 0)
  233. {
  234. UNREFERENCED_PARAMETER(c);
  235. ASSERT(pFile);
  236. if (!pFile)
  237. return FALSE;
  238. rstrString = _T("");
  239. rnCRLFStyle = -1;
  240. const int cnBuffSize = 128; //512;
  241. _TFileChar pBuff[cnBuffSize+10];
  242. UINT uFileSize = (UINT)pFile->GetLength();
  243. while ((UINT)pFile->GetPosition() < uFileSize)
  244. {
  245. UINT uReadSizeB = (cnBuffSize) * sizeof(_TFileChar);
  246. UINT uBufDataCountB = pFile->Read(pBuff, uReadSizeB);
  247. if (!uBufDataCountB)
  248. {
  249. ASSERT(FALSE);
  250. break;
  251. }
  252. ASSERT(uBufDataCountB%sizeof(_TFileChar) == 0);
  253. int nBufDataLen = uBufDataCountB/sizeof(_TFileChar);
  254. pBuff[nBufDataLen] = _T('');
  255. int nBufStrLen = _T_StrLen(pBuff);
  256. ASSERT(nBufStrLen <= nBufDataLen);
  257. _TFileChar* pEOL = NULL;
  258. if (sizeof(_TFileChar) == 1)
  259. {
  260. #ifdef _MBCS
  261. pEOL = (_TFileChar*)_mbspbrk((BYTE*)pBuff, (BYTE*)"x0Ax0D");
  262. #else
  263. pEOL = (_TFileChar*)strpbrk((char*)pBuff, "x0Ax0D");
  264. #endif
  265. }
  266. else
  267. {
  268. pEOL = (_TFileChar*)wcspbrk((wchar_t*)pBuff, L"x0Ax0D");
  269. }
  270. BOOL bEOL_badFormat = FALSE;
  271. // check bad case: when zero char is rathe then readed buffer end
  272. if (!pEOL && nBufStrLen < nBufDataLen)
  273. {
  274. pEOL = pBuff + nBufStrLen;
  275. bEOL_badFormat = TRUE;
  276. }
  277. //---------------------------------
  278. if (!pEOL)
  279. {
  280. _T_StrAdd<_TFileChar, cnBuffSize>(rstrString, pBuff, uCodePage);
  281. continue;
  282. }
  283. _TFileChar chEOL1 = pEOL[0];
  284. _TFileChar chEOL2 = pEOL[1];
  285. *pEOL = 0;
  286. _T_StrAdd<_TFileChar, cnBuffSize>(rstrString, pBuff, uCodePage);
  287. if (!bEOL_badFormat && chEOL2 == 0 && (chEOL1 == 10 || chEOL1 == 13))
  288. {   // buffer ended on the middle of CRLF ?
  289.     // read one more char to be sure in CRLF style.
  290. if (uReadSizeB == uBufDataCountB && (UINT)pFile->GetPosition() < uFileSize)
  291. {
  292. _TFileChar* pBufTail = pBuff + uBufDataCountB/sizeof(_TFileChar);
  293. UINT uReadedB = pFile->Read(pBufTail, sizeof(_TFileChar));
  294. pBufTail[1] = 0;
  295. chEOL2 = pBufTail[0];
  296. uReadSizeB += uReadedB;
  297. uBufDataCountB += uReadedB;
  298. }
  299. }
  300. int nCRLFLen = 1;
  301. if (!bEOL_badFormat)
  302. {
  303. rnCRLFStyle = _T_GetCRLFStyle<_TFileChar>(chEOL1, chEOL2, &nCRLFLen);
  304. ASSERT(rnCRLFStyle != xtpEditCRLFStyleUnknown);
  305. }
  306. int nEolPos = int(pEOL - pBuff);
  307. int nSeekBack = (nEolPos + nCRLFLen)*sizeof(_TFileChar) - uBufDataCountB;
  308. pFile->Seek(nSeekBack, CFile::current);
  309. return TRUE;
  310. }
  311. return rstrString.GetLength() > 0;
  312. }
  313. //===========================================================================
  314. template <class _TFileChar, class _TFile >
  315. int _T_WriteStringToFile(_TFile *pFile, LPCTSTR pszString, int nCRLFStyle,
  316.    UINT uCodePage, CByteArray* parBuffer = NULL, _TFileChar c = 0)
  317. {
  318. UNREFERENCED_PARAMETER(c);
  319. CByteArray arBufferInt;
  320. if (!parBuffer)
  321. {
  322. parBuffer = &arBufferInt;
  323. }
  324. int nStrLen = (int)_tcslen(pszString);
  325. BYTE* pFileBuffer = NULL;
  326. int nFileBufferLenB = 0;
  327. //------------------------------------------------------------------------
  328. if (sizeof(TCHAR) == sizeof(_TFileChar))
  329. {
  330. pFileBuffer = (BYTE*)pszString;
  331. nFileBufferLenB = nStrLen * sizeof(_TFileChar);
  332. }
  333. else
  334. {
  335. int nNeedBufSizeB = nStrLen * 2 + 30;
  336. if (parBuffer->GetSize() < nNeedBufSizeB)
  337. {
  338. parBuffer->SetSize(nNeedBufSizeB + 256);
  339. }
  340. pFileBuffer = parBuffer->GetData();
  341. ASSERT(parBuffer->GetSize() >= nNeedBufSizeB);
  342. ZeroMemory(pFileBuffer, nNeedBufSizeB);
  343. if (sizeof(TCHAR) == 2 && sizeof(_TFileChar) == 1)
  344. {
  345. int nMBCStextLen = WideCharToMultiByte(uCodePage, 0,
  346. (LPCWSTR)pszString, -1,
  347. (LPSTR)pFileBuffer, nNeedBufSizeB, NULL, NULL);
  348. nFileBufferLenB = max(nMBCStextLen - 1, 0);
  349. }
  350. else if (sizeof(TCHAR) == 1 && sizeof(_TFileChar) == 2)
  351. {
  352. int nWtextLen = MultiByteToWideChar(uCodePage, 0,
  353. (LPCSTR)pszString, -1,
  354. (LPWSTR)pFileBuffer, nNeedBufSizeB/2);
  355. nFileBufferLenB = max(nWtextLen - 1, 0) * 2;
  356. }
  357. else
  358. {
  359. ASSERT(FALSE);
  360. return 0;
  361. }
  362. }
  363. //------------------------------------------------------------------------
  364. if (nFileBufferLenB > 0)
  365. {
  366. pFile->Write(pFileBuffer, nFileBufferLenB);
  367. }
  368. if (nCRLFStyle >= 0)
  369. {
  370. _TFileChar* tszCRLF = _T_GetCRLF<_TFileChar>(nCRLFStyle);
  371. int nCRLFlenB = _T_StrLen(tszCRLF) * sizeof(_TFileChar);
  372. pFile->Write(tszCRLF, nCRLFlenB);
  373. nFileBufferLenB += nCRLFlenB;
  374. }
  375. return nFileBufferLenB;
  376. }
  377. //===========================================================================
  378. AFX_INLINE BOOL ReadStringFromFileEx(CFile *pFile, CString& rstrString, int& rnCRLFStyle,
  379.  UINT uCodePage, BOOL bUnicode)
  380. {
  381. if (bUnicode)
  382. {
  383. return _T_ReadStringFromFile<WCHAR>(pFile, rstrString, rnCRLFStyle, uCodePage);
  384. }
  385. return _T_ReadStringFromFile<CHAR>(pFile, rstrString, rnCRLFStyle, uCodePage);
  386. }
  387. template <class _TFile >
  388. AFX_INLINE int _T_WriteStringToFileEx(_TFile *pFile, LPCTSTR pszString, int nCRLFStyle,
  389.    UINT uCodePage, CByteArray* parBuffer, BOOL bUnicode)
  390. {
  391. if (bUnicode)
  392. {
  393. return _T_WriteStringToFile<WCHAR>(pFile, pszString, nCRLFStyle, uCodePage, parBuffer);
  394. }
  395. return _T_WriteStringToFile<CHAR>(pFile, pszString, nCRLFStyle, uCodePage, parBuffer);
  396. }
  397. //===========================================================================
  398. CXTPSyntaxEditBufferManager::CXTPSyntaxEditBufferManager()
  399. {
  400. m_pConnect = new CXTPNotifyConnection();
  401. m_pLexParser = new CXTPSyntaxEditLexParser();
  402. m_bOverwrite = FALSE;
  403. m_nCodePage = CP_ACP;
  404. m_bUnicodeFileFormat = FALSE;
  405. m_nTabSize = 4;
  406. m_iCRLFStyle = xtpEditCRLFStyleDos;
  407. m_nAverageLineLen = XTP_EDIT_AVELINELEN;
  408. m_pLineMarksManager = new CXTPSyntaxEditLineMarksManager();
  409. m_pUndoRedoManager = new CXTPSyntaxEditUndoRedoManager();
  410. m_bIsParserEnabled = TRUE;
  411. if (!s_ptrLexConfigurationManager_Default)
  412. {
  413. s_ptrLexConfigurationManager_Default = new CXTPSyntaxEditConfigurationManager();
  414. }
  415. if (s_ptrLexConfigurationManager_Default)
  416. {
  417. SetLexConfigurationManager(s_ptrLexConfigurationManager_Default);
  418. s_dwLexConfigurationManager_DefaultRefs++;
  419. }
  420. CWinApp* pWinApp = AfxGetApp();
  421. if (pWinApp)
  422. {
  423. m_nTabSize = pWinApp->GetProfileInt(
  424. XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_TABSIZE, m_nTabSize);
  425. }
  426. }
  427. CXTPSyntaxEditBufferManager::~CXTPSyntaxEditBufferManager()
  428. {
  429. Close();
  430. if (s_dwLexConfigurationManager_DefaultRefs)
  431. {
  432. s_dwLexConfigurationManager_DefaultRefs--;
  433. if (s_dwLexConfigurationManager_DefaultRefs == 0)
  434. {
  435. s_ptrLexConfigurationManager_Default->Close();
  436. s_ptrLexConfigurationManager_Default = NULL;
  437. }
  438. }
  439. CMDTARGET_RELEASE(m_pLexParser);
  440. CMDTARGET_RELEASE(m_pConnect);
  441. SAFE_DELETE(m_pLineMarksManager);
  442. SAFE_DELETE(m_pUndoRedoManager);
  443. }
  444. void CXTPSyntaxEditBufferManager::Close()
  445. {
  446. m_LexConfigManSinkMT.UnadviseAll();
  447. m_pLexParser->Close();
  448. CleanUp();
  449. }
  450. void CXTPSyntaxEditBufferManager::CleanUp()
  451. {
  452. m_Strings.RemoveAllStrs();
  453. m_pUndoRedoManager->Clear();
  454. //m_strFileExt = _T("");
  455. }
  456. void CXTPSyntaxEditBufferManager::Load(CFile *pFile, LPCTSTR pcszFileExt)
  457. {
  458. CArchive ar(pFile, CArchive::load);
  459. SerializeEx(ar, -1, FALSE, m_nCodePage, pcszFileExt);
  460. }
  461. void CXTPSyntaxEditBufferManager::Serialize(CArchive &ar)
  462. {
  463. BOOL bUnicode = ar.IsStoring() ? m_bUnicodeFileFormat : -1;
  464. SerializeEx(ar, bUnicode, TRUE, m_nCodePage, NULL);
  465. if (ar.IsStoring())
  466. m_pUndoRedoManager->MarkSaved();
  467. }
  468. void CXTPSyntaxEditBufferManager::SerializeEx(CArchive &ar, BOOL bUnicode, BOOL bWriteUnicodeFilePrefix,
  469.   UINT nCodePage, LPCTSTR pcszFileExt, int nDataSizeLimit)
  470. {
  471. if (m_bIsParserEnabled)
  472. {
  473. m_pLexParser->StopParseInThread();
  474. }
  475. if (nCodePage != (UINT)-1)
  476. m_nCodePage = nCodePage;
  477. CFile* pFile = ar.GetFile();
  478. if (ar.IsLoading())
  479. {
  480. CleanUp();
  481. // IsUnicodeFile is take care about start text offset
  482. //pFile->Seek(m_bUnicodeFileFormat ? 2 : 0, CFile::begin);
  483. //
  484. if (bUnicode < 0)
  485. m_bUnicodeFileFormat = IsUnicodeFile(pFile);
  486. else
  487. m_bUnicodeFileFormat = (bUnicode > 0);
  488. CString strString;
  489. int nCRLFStyle = -1;
  490. int nCRLFLastLineStyle = -1;
  491. BOOL bSETeol = TRUE;
  492. int nRow = 1;
  493. while (ReadStringFromFileEx(pFile, strString, nCRLFStyle, m_nCodePage, m_bUnicodeFileFormat))
  494. {
  495. m_Strings.SetAtGrowStr(nRow, strString);
  496. if (bSETeol && nCRLFStyle >= 0)
  497. {
  498. SetCRLFStyle(nCRLFStyle);
  499. bSETeol = FALSE;
  500. }
  501. nCRLFLastLineStyle = nCRLFStyle;
  502. nRow++;
  503. }
  504. if (nCRLFLastLineStyle >= 0)
  505. {
  506. m_Strings.SetAtGrowStr(nRow, _T(""));
  507. }
  508. CString strExt = pcszFileExt ? pcszFileExt : GetFileExtention(pFile);
  509. if (!strExt.IsEmpty())
  510. SetFileExt(strExt);
  511. }
  512. else if (ar.IsStoring())
  513. {
  514. if (bUnicode == -1)
  515. bUnicode = m_bUnicodeFileFormat;
  516. if ((bUnicode) && bWriteUnicodeFilePrefix)
  517. {
  518. ar << (BYTE)255;
  519. ar << (BYTE)254;
  520. }
  521. CByteArray arBuffer;
  522. int nCRLFStyle = GetCurCRLFType();
  523. int nDataSize = 0;
  524. int nRowsCount = m_Strings.GetCount();
  525. for (int i = 1; i < nRowsCount; i++)
  526. {
  527. CString strLine = m_Strings.GetStr(i);
  528. if (i == nRowsCount-1)
  529. { // last line
  530. nCRLFStyle = -1;// do not write CRLF
  531. }
  532. int nWrittenBytes = _T_WriteStringToFileEx(&ar, strLine, nCRLFStyle,
  533. m_nCodePage, &arBuffer, bUnicode);
  534. nDataSize += nWrittenBytes;
  535. if (nDataSizeLimit > 0 && nDataSize > nDataSizeLimit)
  536. break;
  537. }
  538. //---------------
  539. CString strExt = pcszFileExt ? pcszFileExt : GetFileExtention(pFile);
  540. if (!strExt.IsEmpty())
  541. SetFileExt(strExt);
  542. }
  543. }
  544. void CXTPSyntaxEditBufferManager::SetLexConfigurationManager(
  545. CXTPSyntaxEditConfigurationManager* pMan)
  546. {
  547. m_LexConfigManSinkMT.UnadviseAll();
  548. m_ptrLexConfigurationManager.SetPtr(pMan, TRUE);
  549. if (pMan)
  550. {
  551. CXTPNotifyConnection* ptrConn = pMan->GetConnection();
  552. ASSERT(ptrConn);
  553. if (ptrConn)
  554. {
  555. m_LexConfigManSinkMT.Advise(ptrConn, xtpEditClassSchWasChanged, &CXTPSyntaxEditBufferManager::OnLexConfigManEventHandler);
  556. m_LexConfigManSinkMT.Advise(ptrConn, xtpEditThemeWasChanged, &CXTPSyntaxEditBufferManager::OnLexConfigManEventHandler);
  557. m_LexConfigManSinkMT.Advise(ptrConn, xtpEditAllConfigWasChanged, &CXTPSyntaxEditBufferManager::OnLexConfigManEventHandler);
  558. }
  559. }
  560. }
  561. void CXTPSyntaxEditBufferManager::OnLexConfigManEventHandler(XTP_NOTIFY_CODE Event,
  562.   WPARAM wParam, LPARAM lParam)
  563. {
  564. if (!m_bIsParserEnabled)
  565. {
  566. return;
  567. }
  568. if (Event == xtpEditClassSchWasChanged || Event == xtpEditAllConfigWasChanged)
  569. {
  570. CXTPSyntaxEditTextSchema* ptrNewTxtSch = NULL;
  571. BOOL bSetTxtSch = FALSE;
  572. if (Event == xtpEditClassSchWasChanged)
  573. {
  574. // wParam = LPCTSTR - Schema name;
  575. // lParam = CXTPSyntaxEditLexTextSchema* New text schema pointer
  576. //            or NULL if schema was removed.
  577. CXTPSyntaxEditLexTextSchema* pTxtSch = (CXTPSyntaxEditLexTextSchema*)lParam;
  578. if (pTxtSch)
  579. {
  580. if (pTxtSch->IsFileExtSupported(m_strFileExt) )
  581. {
  582. ptrNewTxtSch = pTxtSch;
  583. bSetTxtSch = TRUE;
  584. }
  585. else
  586. {
  587. CXTPSyntaxEditLexTextSchema* ptrTxtSch_current = m_pLexParser->GetTextSchema();
  588. CString strName_current = ptrTxtSch_current ? ptrTxtSch_current->GetSchName() : _T("");
  589. CString strName_New = pTxtSch->GetSchName();
  590. if (strName_current.CompareNoCase(strName_New) == 0)
  591. {
  592. //such file ext is no longer supported by this schema
  593. ptrNewTxtSch = NULL;
  594. bSetTxtSch = TRUE;
  595. }
  596. }
  597. }
  598. else
  599. {
  600. ptrNewTxtSch = GetMasterTextSchema(m_strFileExt);
  601. bSetTxtSch = !ptrNewTxtSch;
  602. }
  603. }
  604. if (Event == xtpEditAllConfigWasChanged)
  605. {
  606. ptrNewTxtSch = GetMasterTextSchema(m_strFileExt);
  607. bSetTxtSch = TRUE;
  608. }
  609. //====================================================================
  610. if (bSetTxtSch)
  611. {
  612. m_pLexParser->SetTextSchema(ptrNewTxtSch);
  613. if (ptrNewTxtSch)
  614. {
  615. XTP_EDIT_LINECOL pos1_0 = {1,0};
  616. BOOL bParseInThread = m_pLexParser->GetSchemaOptions(
  617. GetFileExt())->m_bConfigChangedReparceInSeparateThread;
  618. if (bParseInThread)
  619. {
  620. m_pLexParser->StartParseInThread(this, &pos1_0, NULL, 0, TRUE);
  621. }
  622. else
  623. {
  624. CXTPSyntaxEditLexTextSchema* ptrTextSch = m_pLexParser->GetTextSchema();
  625. if (ptrTextSch)
  626. {
  627. CXTPSyntaxEditTextIterator txtIter(this);
  628. ptrTextSch->RunParseUpdate(TRUE, &txtIter, &pos1_0, NULL);
  629. }
  630. }
  631. }
  632. //----------------------------------------------
  633. m_pConnect->SendEvent(Event, wParam, lParam);
  634. }
  635. }
  636. if (Event == xtpEditThemeWasChanged)
  637. {
  638. // wParam = LPCTSTR - Theme name;
  639. // lParam = CXTPSyntaxEditColorTheme* New theme pointer
  640. //            or NULL if theme was removed.
  641. CXTPSyntaxEditColorTheme* pNewTheme = (CXTPSyntaxEditColorTheme*)lParam;
  642. CXTPSyntaxEditLexTextSchema* ptrTxtSch = m_pLexParser->GetTextSchema();
  643. if (ptrTxtSch)
  644. {
  645. ptrTxtSch->ApplyTheme(pNewTheme);
  646. //----------------------------------------------
  647. m_pConnect->SendEvent(Event, wParam, lParam);
  648. }
  649. }
  650. }
  651. BOOL CXTPSyntaxEditBufferManager::InsertText(LPCTSTR szText, int nRow, int nCol,
  652. BOOL bCanUndo, XTP_EDIT_LINECOL* pFinalLC)
  653. {
  654. int nStrLenB = (int)_tcslen(szText) * sizeof(TCHAR);
  655. CMemFile memFile((BYTE*)szText, nStrLenB);
  656. CString strString;
  657. CString strReplased;
  658. int nLastLineEOLstyle = -1;
  659. CString strRow1, strRow2;
  660. memFile.SeekToBegin();
  661. // process first row (cut and concatenate)
  662. if (_T_ReadStringFromFile<TCHAR>(&memFile, strString, nLastLineEOLstyle, m_nCodePage))
  663. {
  664. strRow1 = m_Strings.GetStr(nRow);
  665. //int nLen = strRow1.GetLength();
  666. int nLenC = (int)_tcsclen(strRow1);
  667. if (nCol-1 < nLenC)
  668. {
  669. int nPosX = (int)_tcsnbcnt(strRow1, nCol-1);
  670. strRow2 = strRow1.Mid(nPosX);
  671. strRow1 = strRow1.Left(nPosX);
  672. strRow1 += strString;
  673. if (m_bOverwrite)
  674. {
  675. int nReplaceLen = min(strString.GetLength(), strRow2.GetLength());
  676. strReplased = strRow2.Left(nReplaceLen);
  677. DELETE_S(strRow2, 0, nReplaceLen);
  678. }
  679. m_Strings.SetAtGrowStr(nRow, strRow1);
  680. }
  681. else
  682. {
  683. m_Strings.InsertText(nRow, nCol-1, strString, TRUE);
  684. }
  685. }
  686. // process middle rows (insert them)
  687. int nCRLFStyleX = -1;
  688. int r = nRow + 1;
  689. while (_T_ReadStringFromFile<TCHAR>(&memFile, strString, nCRLFStyleX, m_nCodePage))
  690. {
  691. m_Strings.InsertStr(r, strString);
  692. r++;
  693. nLastLineEOLstyle = nCRLFStyleX;
  694. }
  695. // process last row (concatenate)
  696. int nRowTo = nRow;
  697. int nColTo = nCol+1;
  698. if (nLastLineEOLstyle >= 0)
  699. {
  700. m_Strings.InsertStr(r, strRow2);
  701. nRowTo = r;
  702. nColTo = (int)_tcsclen(strString) + 1;
  703. }
  704. else
  705. {
  706. strString = m_Strings.GetStr(r-1);
  707. nRowTo = r-1;
  708. nColTo = (int)_tcsclen(strString) + 1;
  709. strString += strRow2;
  710. m_Strings.SetAtGrowStr(r-1, strString);
  711. }
  712. //===========================================================================
  713. if (pFinalLC)
  714. {
  715. pFinalLC->nLine = nRowTo;
  716. pFinalLC->nCol = nColTo;
  717. }
  718. if (bCanUndo)
  719. {
  720. if (!m_bOverwrite || strReplased == "") // By Leva: added 2nd condition to eliminate undo bug
  721. {
  722. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditInsertStringCommand(this,
  723.  szText,
  724.  XTP_EDIT_LINECOL::MakeLineCol(nRow, nCol),
  725.  XTP_EDIT_LINECOL::MakeLineCol(nRowTo, nColTo)) );
  726. }
  727. else
  728. {
  729. m_pUndoRedoManager->SetGroupInsertMode(FALSE);
  730. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditReplaceStringCommand(this,
  731. szText, strReplased,
  732. XTP_EDIT_LINECOL::MakeLineCol(nRow, nCol),
  733. XTP_EDIT_LINECOL::MakeLineCol(nRowTo, nColTo)) );
  734. }
  735. }
  736. return TRUE;
  737. }
  738. BOOL CXTPSyntaxEditBufferManager::InsertTextBlock(LPCTSTR szText, int nRow,
  739. int nCol, BOOL bCanUndo, XTP_EDIT_LINECOL* pFinalLC)
  740. {
  741. int nStrLenB = (int)_tcslen(szText) * sizeof(TCHAR);
  742. CMemFile memFile((BYTE*)szText, nStrLenB);
  743. memFile.SeekToBegin();
  744. CString strString;
  745. int nEndPos = 0;
  746. int nCRLFStyleX = -1;
  747. int r = nRow;
  748. int nDispCol = StrPosToCol(nRow, nCol-1);
  749. if (bCanUndo)
  750. {
  751. m_pUndoRedoManager->SetGroupInsertMode(TRUE);
  752. }
  753. while (_T_ReadStringFromFile<TCHAR>(&memFile, strString, nCRLFStyleX, m_nCodePage))
  754. {
  755. CString strRow = m_Strings.GetStr(r);
  756. int nRowLen = (int)_tcsclen(strRow);
  757. int nRowCols = StrPosToCol(r, nRowLen);
  758. int nPos = ColToStrPos(r, nDispCol);
  759. if (nRowCols < nDispCol)
  760. {
  761. nPos = nRowLen + (nDispCol - nRowCols);
  762. }
  763. m_Strings.InsertText(r, nPos, strString, TRUE);
  764. //--------------------------------------------------------------------
  765. nEndPos = nPos + strString.GetLength();
  766. if (bCanUndo)
  767. {
  768. XTP_EDIT_LINECOL posFrom = {r, nPos+1};
  769. XTP_EDIT_LINECOL posTo = {r, nEndPos+1};
  770. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditInsertStringCommand(this,
  771. strString, posFrom, posTo) );
  772. }
  773. //--------------------------------------------------------------------
  774. r++;
  775. }
  776. if (bCanUndo)
  777. {
  778. m_pUndoRedoManager->SetGroupInsertMode(FALSE);
  779. }
  780. //===========================================================================
  781. if (pFinalLC)
  782. {
  783. pFinalLC->nLine = r-1;
  784. pFinalLC->nCol = nEndPos+1;
  785. }
  786. return TRUE;
  787. }
  788. void CXTPSyntaxEditBufferManager::GetLineText(int nLine, CString& strText,
  789.  BOOL bAddCRLF, int nCRLFStyle)
  790. {
  791. strText = GetLineText(nLine, bAddCRLF, nCRLFStyle);
  792. }
  793. CString CXTPSyntaxEditBufferManager::GetLineText(int nLine, BOOL bAddCRLF, int nCRLFStyle)
  794. {
  795. CString strText = m_Strings.GetStr(nLine);
  796. if (bAddCRLF)
  797. {
  798. strText += GetCRLF(nCRLFStyle);
  799. }
  800. return strText;
  801. }
  802. int CXTPSyntaxEditBufferManager::GetLineTextLength(int nLine, BOOL bAddCRLF, int nCRLFStyle)
  803. {
  804. int nLen = m_Strings.GetStrLen(nLine);
  805. if (bAddCRLF)
  806. {
  807. int nEOLlen = (int)_tcslen(GetCRLF(nCRLFStyle));
  808. nLen += nEOLlen;
  809. }
  810. return nLen;
  811. }
  812. int CXTPSyntaxEditBufferManager::GetLineTextLengthC(int nLine, BOOL bAddCRLF, int nCRLFStyle)
  813. {
  814. int nLen = m_Strings.GetStrLenC(nLine);
  815. if (bAddCRLF)
  816. {
  817. int nEOLlen = (int)_tcsclen(GetCRLF(nCRLFStyle));
  818. nLen += nEOLlen;
  819. }
  820. return nLen;
  821. }
  822. int CXTPSyntaxEditBufferManager::GetMaxLineTextLength() const
  823. {
  824. return CalcMaxLineTextLength();
  825. }
  826. int CXTPSyntaxEditBufferManager::CalcMaxLineTextLength(int nLineFrom, int nLineTo, BOOL bExpandTabs) const
  827. {
  828. nLineFrom = min(max(1, nLineFrom), GetRowCount());
  829. nLineTo = nLineTo < 0 ? GetRowCount() : min(nLineTo, GetRowCount());
  830. if (nLineFrom >= m_Strings.GetCount() || nLineTo >= m_Strings.GetCount() )
  831. {
  832. return 0;
  833. }
  834. int nTabSize = GetTabSize();
  835. int nMAXlen = 0;
  836. for (int i = nLineFrom; i <= nLineTo; i++)
  837. {
  838. CString* pCStrData = m_Strings.GetStrDataC(i);
  839. if (!pCStrData)
  840. continue;
  841. int nLen = pCStrData->GetLength();
  842. if (bExpandTabs)
  843. {
  844. LPCTSTR pcszString = (LPCTSTR)(*pCStrData);
  845. int nOffset = 0;
  846. for (int k = 0; k < nLen; k++)
  847. {
  848. if (pcszString[k] == _T('t'))
  849. nOffset += (nTabSize - nOffset % nTabSize);
  850. else
  851. nOffset++;
  852. }
  853. nLen = nOffset;
  854. }
  855. if (nLen > nMAXlen)
  856. nMAXlen = nLen;
  857. }
  858. return nMAXlen;
  859. }
  860. BOOL CXTPSyntaxEditBufferManager::DeleteText(int nRowFrom, int nColFrom,
  861. int nRowTo, int nColTo, BOOL bCanUndo, BOOL bDispCol)
  862. {
  863. ASSERT(nColFrom >= 1 && nColTo >= 1);
  864. if (bCanUndo)
  865. {
  866. int nPos1 = bDispCol ? nColFrom : StrPosToCol(nRowFrom, nColFrom - 1); // By Leva: moved -1 into brackets
  867. int nPos2 = bDispCol ? nColTo : StrPosToCol(nRowTo, nColTo - 1); // By Leva: moved -1 into brackets
  868. CMemFile file(CalcAveDataSize(nRowFrom, nRowTo));
  869. if (GetBuffer(nRowFrom, nPos1, nRowTo, nPos2, file))
  870. {
  871. TCHAR szNull = NULL;
  872. file.SeekToEnd();
  873. file.Write((const BYTE *)&szNull, sizeof(TCHAR));
  874. BYTE *pBytes = file.Detach();
  875. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditDeleteStringCommand(this, (LPCTSTR)pBytes,
  876. XTP_EDIT_LINECOL::MakeLineCol(nRowFrom, bDispCol ? ColToStrPos(nRowFrom, nColFrom)+1 : nColFrom),
  877. XTP_EDIT_LINECOL::MakeLineCol(nRowTo, bDispCol ? ColToStrPos(nRowTo, nColTo)+1 : nColTo)) );
  878. free(pBytes);
  879. }
  880. }
  881. BOOL bResult = FALSE;
  882. if (nRowFrom < nRowTo)
  883. {
  884. // Process nRowFrom
  885. int nStrLenR1 = m_Strings.GetStrLenC(nRowFrom);
  886. int nStrPos = bDispCol ? ColToStrPos(nRowFrom, nColFrom) : nColFrom-1;
  887. int nCount = nStrLenR1 - nStrPos;
  888. if (nStrLenR1 && nCount > 0)
  889. {
  890. ASSERT(nStrPos >=0);
  891. bResult = m_Strings.DeleteText(nRowFrom, nStrPos, nCount);
  892. ASSERT(bResult);
  893. }
  894. // Process nRowTo
  895. int nStrLenR2 = m_Strings.GetStrLenC(nRowTo);
  896. nStrPos = 0;
  897. nCount = bDispCol ? ColToStrPos(nRowTo, nColTo) : nColTo-1;
  898. if (nStrLenR2 && nCount > 0)
  899. {
  900. ASSERT(nStrPos >=0);
  901. bResult = m_Strings.DeleteText(nRowTo, nStrPos, nCount);
  902. ASSERT(bResult);
  903. }
  904. // Concatenate row <from> and row <to>
  905. CString strRowNew = m_Strings.GetStr(nRowFrom);
  906. CString strRow2 = m_Strings.GetStr(nRowTo);
  907. strRowNew += strRow2;
  908. m_Strings.SetAtGrowStr(nRowFrom, strRowNew);
  909. for (int r = nRowTo; r > nRowFrom; r--)
  910. {
  911. bResult = m_Strings.RemoveStr(r);
  912. //ASSERT(bResult);
  913. }
  914. }
  915. else
  916. {
  917. ASSERT(nRowFrom == nRowTo);
  918. int nPos1 = bDispCol ? ColToStrPos(nRowFrom, nColFrom) : nColFrom-1;
  919. int nPos2 = bDispCol ? ColToStrPos(nRowTo, nColTo) : nColTo-1;
  920. int nCount = abs(nPos2 - nPos1); //abs(nColTo - nColFrom);
  921. if (nCount)
  922. {
  923. bResult = m_Strings.DeleteText(nRowFrom, min(nPos1, nPos2), nCount);
  924. }
  925. }
  926. return bResult;
  927. }
  928. BOOL CXTPSyntaxEditBufferManager::RemoveLine(int nRow, BOOL bCanUndo, int nRowsCount)
  929. {
  930. int nRowEnd = min(GetRowCount() + 1, nRow + nRowsCount);
  931. if (bCanUndo)
  932. {
  933. CMemFile file(CalcAveDataSize(nRow, nRowEnd));
  934. if (GetBuffer(nRow, 1, nRowEnd, 1, file))
  935. {
  936. TCHAR szNull = _T('');
  937. file.SeekToEnd();
  938. file.Write((const BYTE *)&szNull, sizeof(TCHAR));
  939. BYTE *pBytes = file.Detach();
  940. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditDeleteStringCommand(this, (LPCTSTR)pBytes,
  941. XTP_EDIT_LINECOL::MakeLineCol(nRow, 1),
  942. XTP_EDIT_LINECOL::MakeLineCol(nRowEnd, 1)) );
  943. free(pBytes);
  944. }
  945. }
  946. BOOL bResult = FALSE;
  947. for (int r = nRowEnd - 1; r >= nRow; r--)
  948. {
  949. BOOL b = m_Strings.RemoveStr(r);
  950. bResult |= b;
  951. }
  952. return bResult;
  953. }
  954. BOOL CXTPSyntaxEditBufferManager::GetBuffer(
  955. int row1, int col1, int row2, int col2,
  956. CMemFile& file, BOOL bColumnSelection, BOOL bForceDOSStyleCRLF)
  957. {
  958. int nTempRow1 = row1, nTempRow2 = row2;
  959. int nTempCol1 = col1, nTempCol2 = col2;
  960. if (nTempRow2 < nTempRow1)
  961. {
  962. row1 = nTempRow2;
  963. col1 = nTempCol2;
  964. row2 = nTempRow1;
  965. col2 = nTempCol1;
  966. }
  967. if (nTempRow1 == nTempRow2 || bColumnSelection)
  968. {
  969. col1 = min(nTempCol1, nTempCol2);
  970. col2 = max(nTempCol1, nTempCol2);
  971. }
  972. BOOL bStart = TRUE;
  973. BOOL bEnd = FALSE;
  974. int nStartPos = 0, nEndPos = 0;
  975. int nSizeCopy = 0;
  976. int nNewCRLFStyle = (bForceDOSStyleCRLF) ? xtpEditCRLFStyleDos : m_iCRLFStyle;
  977. const CString strCRLF(GetCRLF(nNewCRLFStyle));
  978. for (int i = row1; i <= row2; i++)
  979. {
  980. if (i == row2)
  981. bEnd = TRUE;
  982. CString strBuffer;
  983. GetLineText(i, strBuffer);
  984. const int nLineLen = (int)_tcslen(strBuffer);
  985. nStartPos = min(bStart || bColumnSelection ? ColToStrPos(i, col1) : 0, nLineLen);
  986. nEndPos = min(bEnd || bColumnSelection ? ColToStrPos(i, col2) : nLineLen, nLineLen);
  987. if (bStart || bColumnSelection)
  988. nStartPos = (int)_tcsnbcnt(strBuffer, nStartPos);
  989. if (bEnd || bColumnSelection)
  990. nEndPos = (int)_tcsnbcnt(strBuffer, nEndPos);
  991. nSizeCopy = abs(nEndPos - nStartPos) * sizeof(TCHAR);
  992. if (nSizeCopy > 0)
  993. file.Write((LPVOID)((LPCTSTR)strBuffer + nStartPos), nSizeCopy);
  994. if (bColumnSelection)
  995. {
  996. // add spaces for the free size of the column block
  997. int nAddSpaces = abs(col2 - col1) -
  998. (int)_tcsnccnt((LPCTSTR)strBuffer + nStartPos, abs(nEndPos - nStartPos));
  999. if (nAddSpaces > 0)
  1000. {
  1001. const CString strSpaces(_T(' '), nAddSpaces);
  1002. file.Write((LPVOID)(LPCTSTR)strSpaces, nAddSpaces * sizeof(TCHAR));
  1003. }
  1004. }
  1005. if (row1 != row2 && i != row2 || bColumnSelection)
  1006. {
  1007. // add end of the line
  1008. file.Write((LPVOID)(LPCTSTR)strCRLF, strCRLF.GetLength() * sizeof(TCHAR));
  1009. }
  1010. bStart = FALSE;
  1011. }
  1012. return TRUE;
  1013. }
  1014. void CXTPSyntaxEditBufferManager::SetOverwriteFlag(BOOL bOverwrite)
  1015. {
  1016. m_bOverwrite = bOverwrite;
  1017. }
  1018. BOOL CXTPSyntaxEditBufferManager::GetOverwriteFlag()
  1019. {
  1020. return m_bOverwrite;
  1021. }
  1022. BOOL CXTPSyntaxEditBufferManager::IsTextCRLF(LPCTSTR szCompText, BOOL bFindReverse)
  1023. {
  1024. CString strCRLF(g_pcszCRLFStyles[m_iCRLFStyle]);
  1025. LPCTSTR szCurCRLF = (LPCTSTR)strCRLF;
  1026. LPCTSTR szTextToCompare = szCompText;
  1027. int nCRLFSize = lstrlen(szCurCRLF);
  1028. if (bFindReverse)
  1029. szTextToCompare = (szCompText - (nCRLFSize - 1));
  1030. BOOL bIsCRLF = (_tcsncmp(szTextToCompare, szCurCRLF, nCRLFSize) == 0);
  1031. return bIsCRLF;
  1032. }
  1033. #ifdef _UNICODE
  1034. BOOL CXTPSyntaxEditBufferManager::IsTextCRLF(LPCSTR szCompText, BOOL bFindReverse)
  1035. {
  1036. LPCSTR szCurCRLF = (LPCSTR)g_pcszCRLFStyles[m_iCRLFStyle];
  1037. LPCSTR szTextToCompare = szCompText;
  1038. int nCRLFSize = (int)strlen(szCurCRLF);
  1039. if (bFindReverse)
  1040. szTextToCompare = (szCompText - (nCRLFSize - 1));
  1041. BOOL bIsCRLF = (strncmp(szTextToCompare, szCurCRLF, nCRLFSize) == 0);
  1042. return bIsCRLF;
  1043. }
  1044. #endif
  1045. CString CXTPSyntaxEditBufferManager::GetCurCRLF() const
  1046. {
  1047. return GetCRLF();
  1048. }
  1049. LPCTSTR CXTPSyntaxEditBufferManager::GetCRLF(int nCRLFStyle) const
  1050. {
  1051. ASSERT(m_iCRLFStyle >= 0 && m_iCRLFStyle < _countof(g_pcszCRLFStyles));
  1052. int nCRLFidx = m_iCRLFStyle;
  1053. if (nCRLFStyle >= 0 && nCRLFStyle < _countof(g_pcszCRLFStyles))
  1054. {
  1055. nCRLFidx = nCRLFStyle;
  1056. }
  1057. return _T_GetCRLF<TCHAR>(nCRLFidx);
  1058. }
  1059. void CXTPSyntaxEditBufferManager::SetCRLFStyle(int nCRLFStyle)
  1060. {
  1061. if (nCRLFStyle >= 0 && nCRLFStyle < _countof(g_pcszCRLFStyles))
  1062. {
  1063. m_iCRLFStyle = nCRLFStyle;
  1064. } else {
  1065. ASSERT(FALSE);
  1066. }
  1067. }
  1068. int CXTPSyntaxEditBufferManager::GetCurCRLFType()
  1069. {
  1070. return m_iCRLFStyle;
  1071. }
  1072. BOOL CXTPSyntaxEditBufferManager::SetTabSize(int nTabSize, BOOL bUpdateReg/*=FALSE*/)
  1073. {
  1074. m_nTabSize = nTabSize;
  1075. if (bUpdateReg)
  1076. {
  1077. CWinApp* pWinApp = AfxGetApp();
  1078. if (pWinApp != NULL)
  1079. {
  1080. if (pWinApp->WriteProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_TABSIZE, nTabSize))
  1081. return TRUE;
  1082. }
  1083. return FALSE;
  1084. }
  1085. return TRUE;
  1086. }
  1087. int CXTPSyntaxEditBufferManager::GetRowCount() const
  1088. {
  1089. return m_Strings.GetCount() ? ((int)m_Strings.GetCount() - 1) : 0;
  1090. }
  1091. UINT CXTPSyntaxEditBufferManager::GetCodePage()
  1092. {
  1093. return m_nCodePage;
  1094. }
  1095. BOOL CXTPSyntaxEditBufferManager::IsModified()
  1096. {
  1097. return m_pUndoRedoManager->IsModified();
  1098. }
  1099. CString CXTPSyntaxEditBufferManager::GetFileExt()
  1100. {
  1101. return m_strFileExt;
  1102. }
  1103. void CXTPSyntaxEditBufferManager::SetFileExt(const CString& strExt)
  1104. {
  1105. if (m_strFileExt.CompareNoCase(strExt) == 0)
  1106. {
  1107. return;
  1108. }
  1109. m_strFileExt = strExt;
  1110. if (m_bIsParserEnabled)
  1111. {
  1112. CXTPSyntaxEditTextSchema* ptrMasterTxtSch = GetMasterTextSchema(strExt);
  1113. m_pLexParser->SetTextSchema(ptrMasterTxtSch);
  1114. }
  1115. }
  1116. CString CXTPSyntaxEditBufferManager::GetConfigFile()
  1117. {
  1118. if (!m_ptrLexConfigurationManager)
  1119. {
  1120. return _T("");
  1121. }
  1122. return m_ptrLexConfigurationManager->GetConfigFile();
  1123. }
  1124. BOOL CXTPSyntaxEditBufferManager::SetConfigFile(LPCTSTR szPath)
  1125. {
  1126. if (!m_ptrLexConfigurationManager)
  1127. return FALSE;
  1128. CString strCfgFile0 = m_ptrLexConfigurationManager->GetConfigFile();
  1129. if (strCfgFile0.CompareNoCase(szPath) != 0)
  1130. m_ptrLexConfigurationManager->ReloadConfig(szPath);
  1131. return TRUE;
  1132. }
  1133. CXTPSyntaxEditTextSchema* CXTPSyntaxEditBufferManager::GetMasterTextSchema(const CString& strExt)
  1134. {
  1135. if (!m_ptrLexConfigurationManager)
  1136. {
  1137. return NULL;
  1138. }
  1139. CXTPSyntaxEditTextSchemaPtr ptrMasterSch;
  1140. ptrMasterSch = m_ptrLexConfigurationManager->GetTextSchemesManager().FindSchema(strExt);
  1141. return ptrMasterSch;
  1142. }
  1143. UINT CXTPSyntaxEditBufferManager::CalcAveDataSize(int nRowStart, int nRowEnd)
  1144. {
  1145. UINT uSize = m_nAverageLineLen * abs(nRowStart - nRowEnd);
  1146. uSize = (uSize / 1024 + 1) * 1024;
  1147. return uSize;
  1148. }
  1149. BOOL CXTPSyntaxEditBufferManager::IsParserEnabled()
  1150. {
  1151. return m_bIsParserEnabled;
  1152. }
  1153. void CXTPSyntaxEditBufferManager::EnableParser(BOOL bEnable)
  1154. {
  1155. if (m_bIsParserEnabled == bEnable)
  1156. {
  1157. return;
  1158. }
  1159. m_bIsParserEnabled = bEnable;
  1160. if (m_bIsParserEnabled)
  1161. {
  1162. CXTPSyntaxEditTextSchema* ptrMasterTxtSch = GetMasterTextSchema(m_strFileExt);
  1163. m_pLexParser->SetTextSchema(ptrMasterTxtSch);
  1164. XTP_EDIT_LINECOL pos1_0 = {1,0};
  1165. BOOL bParseInThread = m_pLexParser->GetSchemaOptions(
  1166. GetFileExt())->m_bConfigChangedReparceInSeparateThread;
  1167. if (bParseInThread)
  1168. {
  1169. m_pLexParser->StartParseInThread(this, &pos1_0, NULL, 0, TRUE);
  1170. }
  1171. else
  1172. {
  1173. CXTPSyntaxEditLexTextSchema* ptrTextSch = m_pLexParser->GetTextSchema();
  1174. if (ptrTextSch)
  1175. {
  1176. CXTPSyntaxEditTextIterator txtIter(this);
  1177. ptrTextSch->RunParseUpdate(TRUE, &txtIter, &pos1_0, NULL);
  1178. }
  1179. }
  1180. }
  1181. else
  1182. {
  1183. m_pLexParser->SetTextSchema(NULL);
  1184. }
  1185. }
  1186. int CXTPSyntaxEditBufferManager::ColToStrPos(int nLine, int nDispCol) const
  1187. {
  1188. int nStrPos = 0;
  1189. int nCol = 0;
  1190. const CString strText = m_Strings.GetStr(nLine);
  1191. int nChars = (int)_tcsclen(strText);
  1192. LPCTSTR pChar = strText;
  1193. int nTabSize = GetTabSize();
  1194. for (int i = 0; *pChar != 0 && i < nChars && (nCol+1) < nDispCol; i++)
  1195. {
  1196. if (*pChar == _T('t'))
  1197. {
  1198. nCol += nTabSize - (nCol % nTabSize);
  1199. }
  1200. else
  1201. {
  1202. nCol++;
  1203. }
  1204. pChar = _tcsinc(pChar);
  1205. nStrPos++;
  1206. }
  1207. // support VirtualSpace by default
  1208. //m_bVirtualSpace
  1209. if (nCol + 1 < nDispCol)
  1210. nStrPos += nDispCol - nCol - 1;
  1211. return nStrPos;
  1212. }
  1213. int CXTPSyntaxEditBufferManager::StrPosToCol(int nLine, int nStrPos) const
  1214. {
  1215. int nDispCol = 1;
  1216. const CString strText = m_Strings.GetStr(nLine);
  1217. LPCTSTR pChar = strText;
  1218. int nTabSize = GetTabSize();
  1219. int i;
  1220. for (i = 0; *pChar != 0 && i < nStrPos;)
  1221. {
  1222. if (*pChar == _T('t'))
  1223. {
  1224. nDispCol += nTabSize - ((nDispCol-1) % nTabSize);
  1225. }
  1226. else
  1227. {
  1228. nDispCol++;
  1229. }
  1230. pChar = _tcsinc(pChar);
  1231. i++;
  1232. }
  1233. // support VirtualSpace by default
  1234. //m_bVirtualSpace
  1235. if (i < nStrPos)
  1236. nDispCol += nStrPos - i;
  1237. return nDispCol;
  1238. }
  1239. void CXTPSyntaxEditBufferManager::ChangeCase(int nRow, int nDispFrom, int nDispTo, BOOL bUpper, BOOL bCanUndo)
  1240. {
  1241. CString strText(m_Strings.GetStr(nRow));
  1242. int nFrom = (int)_tcsnbcnt(strText, ColToStrPos(nRow, nDispFrom));
  1243. int nTo = strText.GetLength();
  1244. if (nDispTo <= strText.GetLength() * GetTabSize())
  1245.  nTo = (int)_tcsnbcnt(strText, ColToStrPos(nRow, nDispTo));
  1246. CString strOriginal = strText.Mid(nFrom, nTo - nFrom);
  1247. CString strChanged(strOriginal);
  1248. // upper/lower text at row nRow from nFrom to nTo
  1249. if (bUpper)
  1250. strChanged.MakeUpper();
  1251. else
  1252. strChanged.MakeLower();
  1253. for (int i = nFrom; i < nTo; ++i)
  1254. strText.SetAt(i, strChanged[i-nFrom]);
  1255. m_Strings.SetAtGrowStr(nRow, strText);
  1256. if (bCanUndo)
  1257. {
  1258. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditReplaceStringCommand(this,
  1259. strChanged, strOriginal,
  1260. XTP_EDIT_LINECOL::MakeLineCol(nRow, nFrom + 1),
  1261. XTP_EDIT_LINECOL::MakeLineCol(nRow, nTo + 1)) );
  1262. }
  1263. }
  1264. void CXTPSyntaxEditBufferManager::ChangeTabification(int nRow, int nDispFrom, int nDispTo, BOOL bTabify, BOOL bCanUndo)
  1265. {
  1266. CString strText(m_Strings.GetStr(nRow));
  1267. const int nTextLen = (int)_tcsclen(strText);
  1268. int nFrom = ColToStrPos(nRow, nDispFrom);
  1269. int nTo = ColToStrPos(nRow, nDispTo);
  1270. const int nTabSize = GetTabSize();
  1271. const CString strTab(_T(' '), nTabSize);
  1272. CString strOriginal = strText.Mid(nFrom, nTo - nFrom);
  1273. CString strChanged(strOriginal);
  1274. // upper/lower text at row nRow from nFrom to nTo
  1275. if (bTabify)
  1276. {
  1277. REPLACE_S(strChanged, strTab, _T("x09"));
  1278. }
  1279. else
  1280. {
  1281. REPLACE_S(strChanged, _T("x09"), strTab);
  1282. }
  1283. strText = strText.Left(nFrom) + strChanged + strText.Right(nTextLen - nTo);
  1284. m_Strings.SetAtGrowStr(nRow, strText);
  1285. if (bCanUndo)
  1286. {
  1287. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditDeleteStringCommand(this,
  1288. strOriginal,
  1289. XTP_EDIT_LINECOL::MakeLineCol(nRow, nFrom + 1),
  1290. XTP_EDIT_LINECOL::MakeLineCol(nRow, nTo + 1)) );
  1291. m_pUndoRedoManager->AddCommand(new CXTPSyntaxEditInsertStringCommand(this,
  1292. strChanged,
  1293. XTP_EDIT_LINECOL::MakeLineCol(nRow, nFrom + 1),
  1294. XTP_EDIT_LINECOL::MakeLineCol(nRow, nFrom + (int)_tcsclen(strChanged) + 1)) );
  1295. }
  1296. }
  1297. ////////////////////////////////////////////////////////////////////////////
  1298. //class CXTPSyntaxEditStringsManager
  1299. CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::CXTPSyntaxEditStringsManager()
  1300. {
  1301. }
  1302. CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::~CXTPSyntaxEditStringsManager()
  1303. {
  1304. }
  1305. int CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::GetCount() const
  1306. {
  1307. return (int)m_arStrings.GetSize();
  1308. }
  1309. CString CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::GetStr(int nRow) const
  1310. {
  1311. CString* pCStr = GetStrDataC(nRow);
  1312. if (pCStr)
  1313. {
  1314. return *pCStr;
  1315. }
  1316. return _T("");
  1317. }
  1318. int CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::GetStrLen(int nRow) const
  1319. {
  1320. CString* pCStr = GetStrDataC(nRow);
  1321. if (!pCStr)
  1322. {
  1323. return 0;
  1324. }
  1325. int nLen = pCStr->GetLength();
  1326. return nLen;
  1327. }
  1328. int CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::GetStrLenC(int nRow) const
  1329. {
  1330. CString* pCStr = GetStrDataC(nRow);
  1331. if (!pCStr)
  1332. {
  1333. return 0;
  1334. }
  1335. int nLenC = (int)_tcsclen(*pCStr);
  1336. return nLenC;
  1337. }
  1338. void CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::SetAtGrowStr(int nRow, LPCTSTR pcszText)
  1339. {
  1340. CString* pCStr = GetStrData(nRow, TRUE);
  1341. if (!pCStr)
  1342. {
  1343. return;
  1344. }
  1345. *pCStr = pcszText;
  1346. }
  1347. void CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::SetAtGrowStr(int nRow,
  1348. const CString& strText)
  1349. {
  1350. CString* pCStr = GetStrData(nRow, TRUE);
  1351. if (!pCStr)
  1352. {
  1353. return;
  1354. }
  1355. *pCStr = strText;
  1356. }
  1357. void CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::InsertStr(int nRow,
  1358.   const CString& strText)
  1359. {
  1360. if (nRow >=0 && nRow < m_arStrings.GetSize() )
  1361. {
  1362. CString* pCStr = new CString(strText);
  1363. m_arStrings.InsertAt(nRow, pCStr);
  1364. }
  1365. else
  1366. {
  1367. SetAtGrowStr(nRow, strText);
  1368. }
  1369. }
  1370. BOOL CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::RemoveStr(int nRow)
  1371. {
  1372. if (nRow >=0 && nRow < m_arStrings.GetSize() )
  1373. {
  1374. CString* pCStr = m_arStrings[nRow];
  1375. m_arStrings.RemoveAt(nRow);
  1376. if (pCStr)
  1377. {
  1378. delete pCStr;
  1379. }
  1380. return TRUE;
  1381. }
  1382. return FALSE;
  1383. }
  1384. CString* CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::GetStrDataC(int nRow) const
  1385. {
  1386. CString* pCStr = NULL;
  1387. if (nRow >=0 && nRow < m_arStrings.GetSize() )
  1388. {
  1389. pCStr = m_arStrings[nRow];
  1390. }
  1391. return pCStr;
  1392. }
  1393. CString* CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::
  1394. GetStrData(int nRow, BOOL bGrowArrayIfNeed)
  1395. {
  1396. CString* pCStr = NULL;
  1397. if (nRow >=0 && nRow < m_arStrings.GetSize() )
  1398. {
  1399. pCStr = m_arStrings[nRow];
  1400. }
  1401. else if (bGrowArrayIfNeed)
  1402. {
  1403. m_arStrings.SetSize(nRow+1);
  1404. }
  1405. else
  1406. {
  1407. return NULL;
  1408. }
  1409. //---------------------------
  1410. if (!pCStr)
  1411. {
  1412. pCStr = new CString();
  1413. m_arStrings[nRow] = pCStr;
  1414. }
  1415. return pCStr;
  1416. }
  1417. BOOL CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::InsertText(int nRow, int nPos,
  1418. LPCTSTR pcszText, BOOL bGrowArrayIfNeed,
  1419. TCHAR chLeftSpaceFiller)
  1420. {
  1421. ASSERT(nPos >= 0 && pcszText);
  1422. CString* pCStr = GetStrData(nRow, bGrowArrayIfNeed);
  1423. if (!pCStr || !pcszText && nPos < 0)
  1424. {
  1425. return FALSE;
  1426. }
  1427. int nStrLenC = (int)_tcsclen(*pCStr);
  1428. int nFillCount = nPos > nStrLenC ? nPos - nStrLenC : 0;
  1429. int nInsPos = (int)_tcsnbcnt(*pCStr, nPos);
  1430. if (nFillCount)
  1431. {
  1432. if (chLeftSpaceFiller != _T(''))
  1433. {
  1434. CString strFill(chLeftSpaceFiller, nFillCount);
  1435. *pCStr += strFill;
  1436. nInsPos = (int)_tcsnbcnt(*pCStr, nPos);
  1437. }
  1438. else
  1439. {
  1440. nInsPos = pCStr->GetLength();
  1441. }
  1442. }
  1443. INSERT_S(*pCStr, nInsPos, pcszText);
  1444. return TRUE;
  1445. }
  1446. BOOL CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::
  1447. DeleteText(int nRow, int nPos, int nCount)
  1448. {
  1449. ASSERT(nPos >= 0 && nCount > 0);
  1450. CString* pCStr = GetStrData(nRow, FALSE);
  1451. if (!pCStr || nPos < 0 || nCount <= 0)
  1452. {
  1453. return FALSE;
  1454. }
  1455. int nStrLen0 = pCStr->GetLength();
  1456. int nPosX = (int)_tcsnbcnt(*pCStr, nPos);
  1457. if (nPosX >= nStrLen0)
  1458. {
  1459. return FALSE;
  1460. }
  1461. int nStrLenC = (int)_tcsclen(*pCStr);
  1462. if (nCount > nStrLenC - nPos)
  1463. {
  1464. nCount = nStrLenC - nPos;
  1465. }
  1466. int nCountX = (int)_tcsnbcnt(((LPCTSTR)*pCStr) + nPosX, nCount);
  1467. DELETE_S(*pCStr, nPosX, nCountX);
  1468. return TRUE;
  1469. }
  1470. void CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::RemoveAllStrs()
  1471. {
  1472. m_arStrings.RemoveAll();
  1473. }
  1474. ////////////////////////////////////////////////////////////////////////////
  1475. //class CStringPtrArray : public CArray<CString*, CString*>
  1476. CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::
  1477. CStringPtrArray::CStringPtrArray()
  1478. {
  1479. }
  1480. CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::
  1481. CStringPtrArray::~CStringPtrArray()
  1482. {
  1483. RemoveAll();
  1484. }
  1485. void CXTPSyntaxEditBufferManager::CXTPSyntaxEditStringsManager::
  1486. CStringPtrArray::RemoveAll()
  1487. {
  1488. int nCount = (int)GetSize();
  1489. for (int i = 0; i < nCount; i++)
  1490. {
  1491. CString* pCStr = GetAt(i);
  1492. if (pCStr)
  1493. {
  1494. SetAt(i, NULL);
  1495. delete pCStr;
  1496. }
  1497. }
  1498. TBase::RemoveAll();
  1499. }