You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8678 lines
205 KiB
C++
8678 lines
205 KiB
C++
// XTPSyntaxEditCtrl.cpp
|
|
//
|
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Resource.h"
|
|
#include <imm.h>
|
|
#include <math.h>
|
|
|
|
// common includes
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPImageManager.h"
|
|
#include "Common/XTPNotifyConnection.h"
|
|
#include "Common/XTPSmartPtrInternalT.h"
|
|
#include "Common/XTPVC80Helpers.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPResourceManager.h"
|
|
|
|
// syntax editor includes
|
|
#include "XTPSyntaxEditDefines.h"
|
|
#include "XTPSyntaxEditStruct.h"
|
|
#include "XTPSyntaxEditDrawTextProcessor.h"
|
|
#include "XTPSyntaxEditSelection.h"
|
|
#include "XTPSyntaxEditUndoManager.h"
|
|
#include "XTPSyntaxEditLineMarksManager.h"
|
|
#include "XTPSyntaxEditLexPtrs.h"
|
|
#include "XTPSyntaxEditTextIterator.h"
|
|
#include "XTPSyntaxEditSectionManager.h"
|
|
#include "XTPSyntaxEditLexParser.h"
|
|
#include "XTPSyntaxEditLexColorFileReader.h"
|
|
#include "XTPSyntaxEditBufferManager.h"
|
|
#include "XTPSyntaxEditToolTipCtrl.h"
|
|
#include "XTPSyntaxEditAutoCompleteWnd.h"
|
|
#include "XTPSyntaxEditCtrl.h"
|
|
#include "XTPSyntaxEditPaintManager.h"
|
|
|
|
using namespace XTPSyntaxEditLexAnalyser;
|
|
|
|
|
|
#define XTP_IDC_EDIT_DRAG_MOVE 0xE12D
|
|
#define XTP_IDC_EDIT_DRAG_COPY 0xE12E
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Imm
|
|
|
|
|
|
class CXTPSyntaxEditCtrl::CImmWrapper
|
|
{
|
|
public:
|
|
CImmWrapper();
|
|
virtual ~CImmWrapper();
|
|
|
|
public:
|
|
BOOL ImmIsIME(HKL hKL = NULL);
|
|
|
|
XTP_HIMC ImmGetContext(HWND hWnd);
|
|
BOOL ImmReleaseContext(HWND hWnd, XTP_HIMC hIMC);
|
|
|
|
BOOL ImmSetCompositionWindow(XTP_HIMC hIMC, COMPOSITIONFORM* pCompForm);
|
|
BOOL ImmSetCompositionFont(XTP_HIMC hIMC, LOGFONT* plfFont);
|
|
public:
|
|
typedef BOOL (WINAPI *PFN_ImmIsIME)(HKL);
|
|
|
|
typedef XTP_HIMC (WINAPI *PFN_ImmGetContext)(HWND);
|
|
typedef BOOL (WINAPI *PFN_ImmReleaseContext)(HWND, XTP_HIMC);
|
|
|
|
typedef BOOL (WINAPI *PFN_ImmSetCompositionFont)(XTP_HIMC, LPLOGFONT); // A/W
|
|
typedef BOOL (WINAPI *PFN_ImmSetCompositionWindow)(XTP_HIMC, COMPOSITIONFORM*);
|
|
|
|
protected:
|
|
HMODULE m_hImmDll; // Handle to the imm32 dll.
|
|
|
|
PFN_ImmIsIME m_pfnImmIsIME;
|
|
PFN_ImmGetContext m_pfnImmGetContext;
|
|
PFN_ImmReleaseContext m_pfnImmReleaseContext;
|
|
PFN_ImmSetCompositionFont m_pfnImmSetCompositionFont;
|
|
PFN_ImmSetCompositionWindow m_pfnImmSetCompositionWindow;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//class _XTP_EXT_CLASS CXTPImmWrapper
|
|
#ifdef _UNICODE
|
|
#define XTP_PROC_NAME_AW(procName) procName "W"
|
|
#else
|
|
#define XTP_PROC_NAME_AW(procName) procName "A"
|
|
#endif
|
|
|
|
#define XTP_IMM_FNCALL(fnName, errRetVal) \
|
|
if (!m_pfn##fnName) \
|
|
return errRetVal; \
|
|
return m_pfn##fnName
|
|
|
|
CXTPSyntaxEditCtrl::CImmWrapper::CImmWrapper()
|
|
{
|
|
m_hImmDll = ::LoadLibrary(_T("imm32.dll"));
|
|
if (m_hImmDll)
|
|
{
|
|
m_pfnImmIsIME = (PFN_ImmIsIME)GetProcAddress(m_hImmDll, "ImmIsIME");
|
|
m_pfnImmGetContext = (PFN_ImmGetContext)GetProcAddress(m_hImmDll, "ImmGetContext");
|
|
m_pfnImmReleaseContext = (PFN_ImmReleaseContext)GetProcAddress(m_hImmDll, "ImmReleaseContext");
|
|
m_pfnImmSetCompositionFont = (PFN_ImmSetCompositionFont)GetProcAddress(m_hImmDll, XTP_PROC_NAME_AW("ImmSetCompositionFont"));
|
|
m_pfnImmSetCompositionWindow = (PFN_ImmSetCompositionWindow)GetProcAddress(m_hImmDll, "ImmSetCompositionWindow");
|
|
}
|
|
else
|
|
{
|
|
m_pfnImmIsIME = NULL;
|
|
m_pfnImmGetContext = NULL;
|
|
m_pfnImmReleaseContext = NULL;
|
|
m_pfnImmSetCompositionFont = NULL;
|
|
m_pfnImmSetCompositionWindow = NULL;
|
|
}
|
|
}
|
|
|
|
CXTPSyntaxEditCtrl::CImmWrapper::~CImmWrapper()
|
|
{
|
|
if (m_hImmDll)
|
|
{
|
|
::FreeLibrary(m_hImmDll);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CImmWrapper::ImmIsIME(HKL hKL)
|
|
{
|
|
ASSERT(m_pfnImmIsIME);
|
|
|
|
if (!m_pfnImmIsIME)
|
|
return FALSE;
|
|
|
|
if (hKL == NULL)
|
|
hKL = ::GetKeyboardLayout(0);
|
|
|
|
return m_pfnImmIsIME(hKL);
|
|
}
|
|
|
|
XTP_HIMC CXTPSyntaxEditCtrl::CImmWrapper::ImmGetContext(HWND hWnd)
|
|
{
|
|
ASSERT(m_pfnImmGetContext);
|
|
XTP_IMM_FNCALL(ImmGetContext, NULL)(hWnd);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CImmWrapper::ImmReleaseContext(HWND hWnd, XTP_HIMC hIMC)
|
|
{
|
|
ASSERT(m_pfnImmReleaseContext);
|
|
XTP_IMM_FNCALL(ImmReleaseContext, FALSE)(hWnd, hIMC);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CImmWrapper::ImmSetCompositionWindow(XTP_HIMC hIMC, COMPOSITIONFORM* pCompForm)
|
|
{
|
|
ASSERT(m_pfnImmReleaseContext);
|
|
XTP_IMM_FNCALL(ImmSetCompositionWindow, FALSE)(hIMC, pCompForm);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CImmWrapper::ImmSetCompositionFont(XTP_HIMC hIMC, LOGFONT* plfFont)
|
|
{
|
|
ASSERT(m_pfnImmReleaseContext);
|
|
XTP_IMM_FNCALL(ImmSetCompositionFont, FALSE)(hIMC, plfFont);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace XTPSyntaxEditLexAnalyser
|
|
{
|
|
CString DBG_TraceTB_StartEndCls(CXTPSyntaxEditLexTextBlock* pTB);
|
|
}
|
|
|
|
|
|
class CXTPSyntaxEditCtrl::CTextSearchCache
|
|
{
|
|
public:
|
|
CTextSearchCache();
|
|
void Update(int nCurrTopRow);
|
|
|
|
int nForTopRow;
|
|
CXTPSyntaxEditLexTextBlockPtr ptrTBStart;
|
|
};
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CScreenSearchBlock
|
|
//===========================================================================
|
|
class CXTPSyntaxEditCtrl::CScreenSearchBlock
|
|
{
|
|
public:
|
|
CScreenSearchBlock();
|
|
virtual ~CScreenSearchBlock();
|
|
CScreenSearchBlock(const CScreenSearchBlock& rSrc);
|
|
|
|
int nRowStart;
|
|
int nRowEnd;
|
|
DWORD dwLastAccessTime;
|
|
CXTPSyntaxEditLexTextBlockPtr ptrTBFirst;
|
|
};
|
|
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CScreenSearchCache
|
|
//===========================================================================
|
|
class CXTPSyntaxEditCtrl::CScreenSearchCache : public CArray<CXTPSyntaxEditCtrl::CScreenSearchBlock, CXTPSyntaxEditCtrl::CScreenSearchBlock&>
|
|
{
|
|
typedef CArray<CXTPSyntaxEditCtrl::CScreenSearchBlock, CXTPSyntaxEditCtrl::CScreenSearchBlock&> Base;
|
|
public:
|
|
DWORD m_dwLastRemoveOldTime;
|
|
|
|
CScreenSearchCache();
|
|
virtual ~CScreenSearchCache();
|
|
|
|
void RemoveAll();
|
|
void RemoveAt(int nIndex);
|
|
void RemoveOld(int nTimeOut_sec);
|
|
};
|
|
|
|
|
|
const int MARGIN_LENGTH = 20;
|
|
const int NODES_WIDTH = 10;
|
|
const int TEXT_LEFT_OFFSET = 4;
|
|
const UINT TIMER_SELECTION_ID = 100;
|
|
const UINT TIMER_SELECTION_TIME = 50;
|
|
const UINT TIMER_REDRAW_WHEN_PARSE = 200;
|
|
const UINT TIMER_AUTOSCROLL_ID = 110;
|
|
const UINT TIMER_AUTOSCROLL_TIME = 120;
|
|
|
|
|
|
enum XTPSyntaxEditFlags
|
|
{
|
|
xtpEditRedraw = 0x0001,
|
|
xtpEditForceRedraw = 0x0002,
|
|
xtpEditTextAsBlock = 0x0004,
|
|
xtpEditDispCol = 0x0008,
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPSyntaxEditOptions
|
|
|
|
CXTPSyntaxEditOptions::CXTPSyntaxEditOptions()
|
|
: m_bSyntaxColor(TRUE)
|
|
, m_bAutoIndent(TRUE)
|
|
, m_bSelMargin(TRUE)
|
|
, m_bLineNumbers(TRUE)
|
|
, m_bWideCaret(TRUE)
|
|
, m_bTabWithSpace(FALSE)
|
|
, m_bDrawNodes(TRUE)
|
|
, m_bEnableWhiteSpace(FALSE)
|
|
|
|
{
|
|
m_bReadOnly = FALSE;
|
|
m_bVirtualSpace = FALSE;
|
|
m_bHideCaret = FALSE;
|
|
m_bViewOnly = FALSE;
|
|
m_bEnableEditAccelerators = FALSE;
|
|
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPSyntaxEditCtrl
|
|
|
|
CXTPSyntaxEditCtrl::CXTPSyntaxEditCtrl()
|
|
: m_bVertScrollBar(TRUE)
|
|
, m_bHorzScrollBar(TRUE)
|
|
, m_bDragging(FALSE)
|
|
, m_bDroppable(FALSE)
|
|
, m_bTokensLoaded(FALSE)
|
|
, m_bIsScrollingEndRow(FALSE)
|
|
, m_bRightButtonDrag(FALSE)
|
|
, m_bIsSmartIndent(TRUE)
|
|
, m_bEnableOleDrag(FALSE)
|
|
, m_bCaseSensitive(TRUE)
|
|
, m_bScrolling(FALSE)
|
|
, m_bFocused(FALSE)
|
|
, m_bIsActive(FALSE)
|
|
, m_nTopCalculatedRow(-1)
|
|
, m_nBottomCalculatedRow(-1)
|
|
, m_nTopRow(1)
|
|
, m_nCurrentCol(1)
|
|
, m_nCurrentDocumentRow(1)
|
|
, m_nDispCol(1)
|
|
, m_nAutoIndentCol(0)
|
|
, m_nMarginLength(MARGIN_LENGTH)
|
|
, m_nLineNumLength(0)
|
|
, m_nNodesWidth(NODES_WIDTH)
|
|
, m_nEditbarLength(MARGIN_LENGTH + NODES_WIDTH)
|
|
, m_nCollapsedTextRowsCount(0)
|
|
, m_nWheelScroll(4)
|
|
, m_nAverageLineLen(XTP_EDIT_AVELINELEN)
|
|
, m_dwInsertPos(0)
|
|
, m_dwLastRedrawTime(0)
|
|
, m_ptPrevMouse(CPoint(0, 0))
|
|
, m_pBuffer(NULL)
|
|
, m_pParentWnd(NULL)
|
|
{
|
|
|
|
m_pOptions = new CXTPSyntaxEditOptions();
|
|
m_pSelection = new CXTPSyntaxEditSelection();
|
|
m_pDrawTextProcessor = new CXTPSyntaxEditDrawTextProcessor();
|
|
|
|
m_pSink = new CXTPNotifySink();
|
|
|
|
m_pSelection->m_pOwnerCtrl = this;
|
|
|
|
m_bCreateScrollbarOnParent = TRUE;
|
|
m_bAllowExpandCollapse = TRUE;
|
|
m_bActivateOnFocus = FALSE;
|
|
|
|
m_pImmWrapper = new CImmWrapper();
|
|
|
|
#ifndef _UNICODE
|
|
m_chPrevLeadByte = 0;
|
|
#endif
|
|
m_bIMEsupported = FALSE;
|
|
|
|
m_pPaintManeger = new CXTPSyntaxEditPaintManager();
|
|
|
|
GetRegValues();
|
|
RegisterWindowClass();
|
|
|
|
m_strDefaultCfgFilePath = GetModulePath() + XTP_EDIT_LEXPARSER_CFG_FILENAME;
|
|
|
|
m_nHScrollMaxWidth = 0;
|
|
m_bWndCreateInProgress = FALSE;
|
|
|
|
m_dwAutoScrollDirection = 0;
|
|
m_bDisableRedraw = FALSE;
|
|
|
|
m_pToolTip = new CXTPSyntaxEditToolTipCtrl();
|
|
m_pAutoComplete = new CXTPSyntaxEditAutoCompleteWnd();
|
|
|
|
m_fcCollapsable = new CTextSearchCache();
|
|
m_fcRowColors = new CTextSearchCache();
|
|
m_arOnScreenSchCache = new CScreenSearchCache();
|
|
|
|
m_pBuffer = new CXTPSyntaxEditBufferManager;
|
|
|
|
m_bUseMonitor = TRUE;
|
|
m_bConfigFileMode = TRUE;
|
|
|
|
m_sCustomTitle.Empty();
|
|
}
|
|
|
|
CXTPSyntaxEditCtrl::~CXTPSyntaxEditCtrl()
|
|
{
|
|
if (m_pBuffer && m_pBuffer->GetLexParser())
|
|
m_pBuffer->GetLexParser()->CloseParseThread();
|
|
|
|
m_pSink->UnadviseAll();
|
|
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
CMDTARGET_RELEASE(m_pBuffer);
|
|
|
|
DestroyWindow();
|
|
|
|
CMDTARGET_RELEASE(m_pPaintManeger);
|
|
|
|
SAFE_DELETE(m_pToolTip);
|
|
SAFE_DELETE(m_pAutoComplete);
|
|
|
|
SAFE_DELETE(m_fcCollapsable);
|
|
SAFE_DELETE(m_fcRowColors);
|
|
SAFE_DELETE(m_arOnScreenSchCache);
|
|
SAFE_DELETE(m_pImmWrapper);
|
|
SAFE_DELETE(m_pSelection);
|
|
SAFE_DELETE(m_pDrawTextProcessor);
|
|
|
|
CMDTARGET_RELEASE(m_pOptions);
|
|
|
|
m_pSink->Delete();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnFinalRelease()
|
|
{
|
|
CWnd::OnFinalRelease();
|
|
}
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPSyntaxEditCtrl, CWnd)
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPSyntaxEditCtrl, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPSyntaxEditCtrl)
|
|
ON_WM_PAINT()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_VSCROLL()
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_SYSKEYDOWN()
|
|
ON_WM_CHAR()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_CREATE()
|
|
ON_WM_SIZE()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_NCACTIVATE()
|
|
ON_WM_MOUSEACTIVATE()
|
|
ON_WM_KEYUP()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_CONTEXTMENU()
|
|
ON_WM_TIMER()
|
|
ON_WM_KILLFOCUS()
|
|
ON_WM_SHOWWINDOW()
|
|
ON_WM_ACTIVATE()
|
|
ON_WM_MOUSEWHEEL()
|
|
ON_WM_GETDLGCODE()
|
|
ON_WM_DESTROY()
|
|
ON_COMMAND(XTP_IDC_EDIT_DRAG_COPY, OnDragCopy)
|
|
ON_COMMAND(XTP_IDC_EDIT_DRAG_MOVE, OnDragMove)
|
|
//}}AFX_MSG_MAP
|
|
ON_MESSAGE(WM_SETTEXT, OnSetText)
|
|
ON_MESSAGE(WM_GETTEXT, OnGetText)
|
|
ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLen)
|
|
|
|
ON_MESSAGE(WM_GETFONT, OnGetFont)
|
|
ON_MESSAGE(WM_SETFONT, OnSetFont)
|
|
|
|
ON_MESSAGE(WM_INPUTLANGCHANGE, OnInputLanguage)
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPSyntaxEditCtrl message handlers
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetRegValues()
|
|
{
|
|
CWinApp* pWinApp = AfxGetApp();
|
|
if (pWinApp != NULL)
|
|
{
|
|
m_bVertScrollBar = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_VSCROLLBAR, m_bVertScrollBar);
|
|
m_bHorzScrollBar = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_HSCROLLBAR, m_bHorzScrollBar);
|
|
|
|
m_pOptions->m_bSyntaxColor = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_SYNTAXCOLOR, m_pOptions->m_bSyntaxColor);
|
|
m_pOptions->m_bAutoIndent = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_AUTOINDENT, m_pOptions->m_bAutoIndent);
|
|
m_pOptions->m_bSelMargin = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_SELMARGIN, m_pOptions->m_bSelMargin);
|
|
m_pOptions->m_bLineNumbers = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_LINENUMBERS, m_pOptions->m_bLineNumbers);
|
|
m_pOptions->m_bWideCaret = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_WIDECARET, m_pOptions->m_bWideCaret);
|
|
m_pOptions->m_bTabWithSpace = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_TABWITHSPACE, m_pOptions->m_bTabWithSpace);
|
|
m_pOptions->m_bVirtualSpace = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_VIRTUALSPACE, m_pOptions->m_bVirtualSpace);
|
|
m_pOptions->m_bDrawNodes = pWinApp->GetProfileInt(XTP_EDIT_REG_SETTINGS, XTP_EDIT_REG_COLLAPSIBLENODES, m_pOptions->m_bDrawNodes);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetValueInt(LPCTSTR lpszValue, int nNewValue, int& nRefValue, BOOL bUpdateReg)
|
|
{
|
|
nRefValue = nNewValue;
|
|
|
|
if (bUpdateReg)
|
|
{
|
|
CWinApp* pWinApp = AfxGetApp();
|
|
if (pWinApp != NULL)
|
|
{
|
|
if (pWinApp->WriteProfileInt(XTP_EDIT_REG_SETTINGS, lpszValue, nNewValue))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetValueBool(LPCTSTR lpszValue, BOOL bNewValue, BOOL& bRefValue, BOOL bUpdateReg)
|
|
{
|
|
bRefValue = bNewValue;
|
|
|
|
if (bUpdateReg)
|
|
{
|
|
CWinApp* pWinApp = AfxGetApp();
|
|
if (pWinApp != NULL)
|
|
{
|
|
if (pWinApp->WriteProfileInt(XTP_EDIT_REG_SETTINGS, lpszValue, (int)bNewValue))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetAutoIndent(BOOL bAutoIndent, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_AUTOINDENT, bAutoIndent, m_pOptions->m_bAutoIndent, bUpdateReg))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnPaint()
|
|
{
|
|
DWORD dwStartTime = ::GetTickCount();
|
|
|
|
CPaintDC dc(this); // device context for painting
|
|
CXTPClientRect rcClient(this);
|
|
|
|
//if ((!m_bChanged || m_bDisableRedraw) && m_bmpCache.GetSafeHandle() != 0)
|
|
if (m_bDisableRedraw && m_bmpCache.GetSafeHandle() != 0)
|
|
{
|
|
CXTPCompatibleDC memDC(&dc, &m_bmpCache);
|
|
dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY);
|
|
}
|
|
else
|
|
{
|
|
CDC memDC;
|
|
memDC.CreateCompatibleDC(&dc);
|
|
|
|
if (!m_bmpCache.m_hObject)
|
|
m_bmpCache.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
|
|
|
|
CXTPBitmapDC autoBitmap(&memDC, &m_bmpCache);
|
|
|
|
#ifdef _DEBUG
|
|
memDC.FillSolidRect(rcClient, 0xFF);
|
|
#endif
|
|
|
|
Draw(&memDC, rcClient);
|
|
|
|
if (!IsWindowEnabled())
|
|
{
|
|
XTPImageManager()->DisableBitmap(memDC, rcClient, XTP_EDIT_DISABLED_COLOR_LIGHT, XTP_EDIT_DISABLED_COLOR_DARK);
|
|
}
|
|
|
|
dc.BitBlt(0, 0, rcClient.right, rcClient.bottom, &memDC, 0, 0, SRCCOPY);
|
|
|
|
//m_bChanged = FALSE;
|
|
|
|
// Draw caret
|
|
CSize szCaret;
|
|
szCaret.cx = GetWideCaret() ? m_pDrawTextProcessor->GetTextMetrics().tmAveCharWidth : 2;
|
|
szCaret.cy = m_pDrawTextProcessor->GetRowHeight();
|
|
|
|
BOOL bVirtSpace = _IsVirtualSpaceActive() || m_nAutoIndentCol;
|
|
int nCol = m_nDispCol - 1;
|
|
BOOL bHideCaret = m_pOptions->m_bHideCaret || !m_bFocused;
|
|
CPoint ptCaret = m_pDrawTextProcessor->SetCaretPos(this, szCaret, max(0, GetCurrentVisibleRow() - 1), nCol,
|
|
bHideCaret, bVirtSpace);
|
|
|
|
// IME Support
|
|
if (m_bIMEsupported)
|
|
{
|
|
XTP_HIMC hIMC = m_pImmWrapper->ImmGetContext(m_hWnd);
|
|
if (hIMC)
|
|
{
|
|
COMPOSITIONFORM compForm;
|
|
::ZeroMemory(&compForm, sizeof(compForm));
|
|
|
|
compForm.dwStyle = CFS_POINT; //CFS_FORCE_POSITION
|
|
compForm.ptCurrentPos = ptCaret;
|
|
|
|
VERIFY(m_pImmWrapper->ImmSetCompositionWindow(hIMC, &compForm));
|
|
|
|
VERIFY(m_pImmWrapper->ImmReleaseContext(m_hWnd, hIMC));
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD dwEndTime = ::GetTickCount();
|
|
|
|
m_aveRedrawScreenTime.AddValue(::labs(dwEndTime - dwStartTime));
|
|
|
|
//TRACE(_T("aveRedrawScreenTime = %d ms \n"), (int)m_aveRedrawScreenTime.GetAverageValue(0));
|
|
}
|
|
|
|
AFX_STATIC void AFX_CDECL XTPSECollapsedBlockDeleteFn(void* pPtr)
|
|
{
|
|
XTP_EDIT_COLLAPSEDBLOCK* pBlock = (XTP_EDIT_COLLAPSEDBLOCK*)pPtr;
|
|
SAFE_DELETE(pBlock);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Draw(CDC *pDC, const CRect& rcRect)
|
|
{
|
|
ASSERT(pDC);
|
|
if (!pDC)
|
|
return;
|
|
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
// calculate rects
|
|
CRect rcBookMarks, rcLineNum, rcNodes, rcText;
|
|
CalcEditRects(&rcBookMarks, &rcLineNum, &rcNodes, &rcText, &rcRect);
|
|
|
|
// set text rect
|
|
m_pDrawTextProcessor->SetTextRect(rcText);
|
|
m_pDrawTextProcessor->SetTabSize(GetTabSize());
|
|
|
|
// Set Row Height
|
|
m_pDrawTextProcessor->RecalcRowHeight(pDC, GetPaintManager()->GetFont());
|
|
|
|
//--------------------------------------------------
|
|
m_fcCollapsable->Update(m_nTopRow);
|
|
m_fcRowColors->Update(m_nTopRow);
|
|
|
|
//-------------------
|
|
int nRowHeight = max(1, m_pDrawTextProcessor->GetRowHeight());
|
|
int nLinesCount = rcRect.Height() / nRowHeight + ((rcRect.Height() % nRowHeight) ? 1 : 0);
|
|
int nSkipLines = 0;
|
|
m_nCollapsedTextRowsCount = 0;
|
|
|
|
m_mapInternalRowBkColor.RemoveAll();
|
|
m_mapInternalRowForeColor.RemoveAll();
|
|
|
|
for (int nLine = 0; nLine < nLinesCount;)
|
|
{
|
|
int nTextRow = m_nTopRow + nLine + nSkipLines;
|
|
|
|
int nCollapsedRowsCount = 0;
|
|
DWORD dwCollapcedType = ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount);
|
|
nSkipLines += nCollapsedRowsCount;
|
|
|
|
//if (nCollapsedRowsCount)
|
|
// continue;
|
|
|
|
// Draw Line attributes (bookmark, number, node)
|
|
int nLineY0 = rcRect.top + m_pDrawTextProcessor->GetRowHeight() * nLine;
|
|
int nLineY1 = nLineY0 + m_pDrawTextProcessor->GetRowHeight();
|
|
|
|
if (GetSelMargin())
|
|
{
|
|
CRect rcLMark(rcBookMarks);
|
|
rcLMark.top = nLineY0;
|
|
rcLMark.bottom = nLineY1;
|
|
GetPaintManager()->DrawLineMarks(pDC, rcLMark, nTextRow, this);
|
|
}
|
|
|
|
if (GetLineNumbers())
|
|
{
|
|
CRect rcLNum(rcLineNum);
|
|
rcLNum.top = nLineY0;
|
|
rcLNum.bottom = nLineY1;
|
|
GetPaintManager()->DrawLineNumber(pDC, rcLNum, nTextRow, this);
|
|
}
|
|
|
|
if (GetCollapsibleNodes())
|
|
{
|
|
CRect rcNode, rcNodeFull;
|
|
GetLineNodeRect(nLine, rcNode, &rcNodeFull);
|
|
GetPaintManager()->DrawLineNode(pDC, rcNode, rcNodeFull, dwCollapcedType, nTextRow, this);
|
|
}
|
|
else
|
|
{
|
|
CRect rcGap(rcLineNum);
|
|
|
|
rcGap.top = nLineY0;
|
|
rcGap.bottom = nLineY1;
|
|
rcGap.left = rcLineNum.right;
|
|
rcGap.right = rcText.left;
|
|
|
|
pDC->FillSolidRect(&rcGap, GetPaintManager()->GetBackColorEx(this));
|
|
}
|
|
|
|
|
|
// D R A W T E X T /////////////////////////////////////////////
|
|
|
|
CRect rcTextLine(rcText);
|
|
rcTextLine.top = nLineY0;
|
|
rcTextLine.bottom = nLineY1;
|
|
|
|
GetPaintManager()->DrawLineTextEx(pDC, rcTextLine, nTextRow, nLine, this);
|
|
|
|
nLine++;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
GetPaintManager()->DrawCollapsedTextMarks(this, pDC);
|
|
//---------------------------------------------------------------------------
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::PrintPage(CDC *pDC, const CRect& rcRect, int nFlags) // returns printed rows count
|
|
{
|
|
int nPrintedRowsCount = 0;
|
|
|
|
ASSERT(pDC);
|
|
if (!pDC)
|
|
return 0;
|
|
|
|
BOOL bSelMargin_orig = m_pOptions->m_bSelMargin;
|
|
m_pOptions->m_bSelMargin = FALSE;
|
|
CalculateEditbarLength(pDC);
|
|
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
// calculate rects
|
|
CRect rcBookMarks, rcLineNum, rcNodes, rcText;
|
|
CalcEditRects(&rcBookMarks, &rcLineNum, &rcNodes, &rcText, &rcRect);
|
|
|
|
// set text rect
|
|
m_pDrawTextProcessor->SetTextRect(rcText);
|
|
m_pDrawTextProcessor->SetTabSize(GetTabSize());
|
|
|
|
// Set Row Height
|
|
m_pDrawTextProcessor->RecalcRowHeight(pDC, GetPaintManager()->GetFont());
|
|
|
|
//--------------------------------------------------
|
|
m_fcCollapsable->Update(m_nTopRow);
|
|
m_fcRowColors->Update(m_nTopRow);
|
|
|
|
//-------------------
|
|
int nRowHeight = max(1, m_pDrawTextProcessor->GetRowHeight());
|
|
int nLinesCount = rcRect.Height() / nRowHeight + ((rcRect.Height() % nRowHeight) ? 1 : 0);
|
|
int nSkipLines = 0;
|
|
m_nCollapsedTextRowsCount = 0;
|
|
|
|
int nNextLineY = 0;
|
|
|
|
m_mapInternalRowBkColor.RemoveAll();
|
|
m_mapInternalRowForeColor.RemoveAll();
|
|
|
|
|
|
for (int nLine = 0;
|
|
nLine < nLinesCount && nNextLineY + nRowHeight < rcText.Height();
|
|
nPrintedRowsCount++)
|
|
{
|
|
int nTextRow = m_nTopRow + nLine + nSkipLines;
|
|
|
|
int nCollapsedRowsCount = 0;
|
|
ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount);
|
|
nSkipLines += nCollapsedRowsCount;
|
|
|
|
// Draw Line attributes (bookmark, number, node)
|
|
int nLineY0 = rcRect.top + nNextLineY; //m_pDrawTextProcessor->GetRowHeight() * nLine;
|
|
int nLineY1 = nLineY0 + m_pDrawTextProcessor->GetRowHeight();
|
|
|
|
CRect rcTextLine(rcText);
|
|
rcTextLine.top = nLineY0;
|
|
rcTextLine.bottom = nLineY1;
|
|
|
|
// calculate is enough vertical space to print all line text
|
|
int nLineHeight = GetPaintManager()->PrintLineTextEx(pDC, rcTextLine, nTextRow, nLine,
|
|
this, nFlags);
|
|
if (nLineHeight < 0)
|
|
break;
|
|
|
|
// if (GetSelMargin())
|
|
// {
|
|
// CRect rcLMark(rcBookMarks);
|
|
// rcLMark.top = nLineY0;
|
|
// rcLMark.bottom = nLineY1;
|
|
// GetPaintManager()->DrawLineMarks(pDC, rcLMark, nTextRow, this);
|
|
// }
|
|
|
|
if (GetLineNumbers() && (nFlags & DT_CALCRECT) == 0)
|
|
{
|
|
CRect rcLNum(rcLineNum);
|
|
rcLNum.top = nLineY0;
|
|
rcLNum.bottom = nLineY1;
|
|
GetPaintManager()->DrawLineNumber(pDC, rcLNum, nTextRow, this);
|
|
}
|
|
|
|
// if (m_bDrawNodes)
|
|
// {
|
|
// CRect rcNode, rcNodeFull;
|
|
// GetLineNodeRect(nLine, rcNode, &rcNodeFull);
|
|
// GetPaintManager()->DrawLineNode(pDC, rcNode, rcNodeFull, dwCollapcedType, this);
|
|
// }
|
|
|
|
// D R A W T E X T /////////////////////////////////////////////
|
|
|
|
// if ((nFlags & DT_CALCRECT) == 0)
|
|
// nLineHeight = GetPaintManager()->PrintLineTextEx(pDC, rcTextLine, nTextRow,
|
|
// nLine, this, nFlags);
|
|
|
|
nNextLineY += nLineHeight;
|
|
|
|
nLine++;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
GetPaintManager()->DrawCollapsedTextMarks(this, pDC);
|
|
//---------------------------------------------------------------------------
|
|
|
|
m_pOptions->m_bSelMargin = bSelMargin_orig;
|
|
|
|
return nPrintedRowsCount;
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::UpdateRowInfoInternally(int nTextRow)
|
|
{
|
|
CClientDC wndDC(this);
|
|
CDC memDC;
|
|
memDC.CreateCompatibleDC(&wndDC);
|
|
|
|
int nDispRow = GetVisibleRow(nTextRow) - 1;
|
|
if (nDispRow > m_pDrawTextProcessor->GetRowsCount(TRUE) + 10)
|
|
nDispRow = m_pDrawTextProcessor->GetRowsCount(TRUE) + 10;
|
|
|
|
CRect rcTextLine;
|
|
CalcEditRects(NULL, NULL, NULL, &rcTextLine);
|
|
|
|
int nCollapsedRowsCount = 0;
|
|
ProcessCollapsedRowsBeroreDraw(nTextRow, nCollapsedRowsCount); // to update collapsed block info.
|
|
|
|
GetPaintManager()->DrawLineTextEx(&memDC, rcTextLine, nTextRow, nDispRow, this);
|
|
}
|
|
|
|
DWORD CXTPSyntaxEditCtrl::ProcessCollapsedRowsBeroreDraw(int nTextRow, int& rnSkipRowsCount)
|
|
{
|
|
rnSkipRowsCount = 0;
|
|
|
|
if (nTextRow > GetRowCount())
|
|
return XTP_EDIT_ROWNODE_NOTHING;
|
|
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
BOOL bIsRowCollapsed = HasRowMark(nTextRow, xtpEditLMT_Collapsed, &LMCoParam);
|
|
|
|
// retrieve row nodes
|
|
CXTPSyntaxEditRowsBlockArray arCoBlocks;
|
|
DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
|
|
|
|
GetCollapsableBlocksInfo(nTextRow, arCoBlocks);
|
|
|
|
BOOL bCollapsedProcessed = FALSE;
|
|
int nCount = (int)arCoBlocks.GetSize();
|
|
|
|
//-----------------------------------------
|
|
if (bIsRowCollapsed && nCount == 0)
|
|
{
|
|
GetLineMarksManager()->DeleteLineMark(nTextRow, xtpEditLMT_Collapsed);
|
|
}
|
|
|
|
//-----------------------------------------
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
|
|
if (coBlk.lcStart.nLine == nTextRow)
|
|
{
|
|
if (bIsRowCollapsed && !bCollapsedProcessed)
|
|
{
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk;
|
|
pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
if (!pCoDrawBlk)
|
|
{
|
|
pCoDrawBlk = new XTP_EDIT_COLLAPSEDBLOCK;
|
|
LMCoParam.SetPtr(pCoDrawBlk, XTPSECollapsedBlockDeleteFn);
|
|
}
|
|
pCoDrawBlk->collBlock = coBlk;
|
|
GetLineMarksManager()->SetLineMark(nTextRow,
|
|
xtpEditLMT_Collapsed, &LMCoParam);
|
|
|
|
m_arCollapsedTextRows.SetAtGrow(m_nCollapsedTextRowsCount, nTextRow);
|
|
m_nCollapsedTextRowsCount++;
|
|
|
|
bCollapsedProcessed = TRUE;
|
|
rnSkipRowsCount = max(1, coBlk.lcEnd.nLine - coBlk.lcStart.nLine);
|
|
|
|
dwType |= XTP_EDIT_ROWNODE_COLLAPSED;
|
|
}
|
|
else
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_EXPANDED;
|
|
}
|
|
}
|
|
|
|
BOOL bLastLineEnd = coBlk.lcEnd.nLine > nTextRow && nTextRow == GetRowCount();
|
|
if (coBlk.lcEnd.nLine == nTextRow || bLastLineEnd)
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_ENDMARK;
|
|
}
|
|
if (coBlk.lcStart.nLine < nTextRow)
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_NODEUP;
|
|
}
|
|
if (coBlk.lcEnd.nLine > nTextRow && !bCollapsedProcessed && !bLastLineEnd)
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_NODEDOWN;
|
|
}
|
|
// check whether to skip the row
|
|
if ((coBlk.lcStart.nLine < nTextRow) &&
|
|
(coBlk.lcEnd.nLine >= nTextRow))
|
|
{
|
|
if (HasRowMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed))
|
|
{
|
|
rnSkipRowsCount = max(1, coBlk.lcEnd.nLine - nTextRow);
|
|
}
|
|
}
|
|
}
|
|
|
|
return dwType;
|
|
}
|
|
|
|
CRect CXTPSyntaxEditCtrl::CalcEditRects(CRect* prcBookMarks, CRect* prcLineNum, CRect* prcNodes, CRect* prcText,
|
|
const CRect* prcClient) const
|
|
{
|
|
CRect rcClient(0, 0, 100, 100);
|
|
if (prcClient)
|
|
rcClient = *prcClient;
|
|
else if (m_hWnd)
|
|
GetClientRect(&rcClient);
|
|
|
|
// calculate rects
|
|
CRect rcBookMarks = rcClient;
|
|
rcBookMarks.right = rcBookMarks.left + (GetSelMargin() ? m_nMarginLength : 0);
|
|
|
|
CRect rcLineNum = rcClient;
|
|
rcLineNum.left = rcBookMarks.right;
|
|
rcLineNum.right = rcLineNum.left + (GetLineNumbers() ? m_nLineNumLength : 0);
|
|
|
|
CRect rcNodes = rcClient;
|
|
rcNodes.left = rcLineNum.right;
|
|
rcNodes.right = rcNodes.left + (GetCollapsibleNodes() ? m_nNodesWidth : 0);
|
|
|
|
CRect rcText = rcClient;
|
|
rcText.left += m_nEditbarLength;
|
|
|
|
//--------------------------------------------
|
|
if (prcBookMarks)
|
|
*prcBookMarks = rcBookMarks;
|
|
|
|
if (prcLineNum)
|
|
*prcLineNum = rcLineNum;
|
|
|
|
if (prcNodes)
|
|
*prcNodes = rcNodes;
|
|
|
|
if (prcText)
|
|
*prcText = rcText;
|
|
|
|
return rcClient;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::RegisterWindowClass(HINSTANCE hInstance /*= NULL*/)
|
|
{
|
|
return XTPDrawHelpers()->RegisterWndClass(hInstance,
|
|
XTP_EDIT_CLASSNAME_EDITCTRL, CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::PreCreateWindow(CREATESTRUCT& )
|
|
{
|
|
m_bWndCreateInProgress = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::PreSubclassWindow()
|
|
{
|
|
if (!m_bWndCreateInProgress)
|
|
{
|
|
// process only for SubclassWindow call
|
|
DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
|
|
|
|
m_bVertScrollBar = 0 != (dwStyle & WS_VSCROLL);
|
|
m_bHorzScrollBar = 0 != (dwStyle & WS_HSCROLL);
|
|
|
|
m_pParentWnd = GetParent();
|
|
|
|
_InitEditControl();
|
|
}
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
m_bWndCreateInProgress = FALSE;
|
|
|
|
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
if (!_InitEditControl())
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnDestroy()
|
|
{
|
|
if (m_pToolTip->GetSafeHwnd())
|
|
m_pToolTip->DestroyWindow();
|
|
|
|
if (m_pAutoComplete->GetSafeHwnd())
|
|
m_pAutoComplete->DestroyWindow();
|
|
|
|
m_pSink->UnadviseAll();
|
|
|
|
CWnd::OnDestroy();
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::Create(CWnd* pParentWnd, BOOL bHorzScroll, BOOL bVertScroll,
|
|
CXTPSyntaxEditBufferManager *pBuffer,
|
|
CCreateContext *lpCS, UINT nID)
|
|
{
|
|
if (pBuffer)
|
|
{
|
|
CMDTARGET_ADDREF(pBuffer);
|
|
|
|
CMDTARGET_RELEASE(m_pBuffer);
|
|
|
|
m_pBuffer = pBuffer;
|
|
}
|
|
|
|
//-------------------------------------------
|
|
m_bVertScrollBar = bVertScroll;
|
|
m_bHorzScrollBar = bHorzScroll;
|
|
|
|
DWORD dwStyle = (WS_CHILD | WS_VISIBLE);
|
|
|
|
if (m_bVertScrollBar && !IsCreateScrollbarOnParent())
|
|
dwStyle |= WS_VSCROLL;
|
|
|
|
if (m_bHorzScrollBar && !IsCreateScrollbarOnParent())
|
|
dwStyle |= WS_HSCROLL;
|
|
|
|
//-------------------------------------------
|
|
ASSERT_VALID(pParentWnd); // must be valid.
|
|
m_pParentWnd = pParentWnd;
|
|
|
|
BOOL bCreate = CWnd::CreateEx(WS_EX_ACCEPTFILES, XTP_EDIT_CLASSNAME_EDITCTRL, NULL,
|
|
dwStyle, CRect(0, 0, 100, 100), m_pParentWnd, nID, (LPVOID)lpCS);
|
|
|
|
if (!bCreate)
|
|
{
|
|
TRACE0("Failed to create edit window.\n");
|
|
}
|
|
|
|
return bCreate;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::_InitEditControl()
|
|
{
|
|
// create tip window
|
|
VERIFY(m_pToolTip->Create(this));
|
|
|
|
// Create AutoComplete window.
|
|
VERIFY(m_pAutoComplete->Create(this));
|
|
|
|
CRect rcText(0, 0, 3000, 2000);
|
|
m_pDrawTextProcessor->SetTextRect(rcText);
|
|
m_pDrawTextProcessor->SetTabSize(GetTabSize());
|
|
|
|
// create data manager if need
|
|
//if (!m_pBuffer)
|
|
// m_pBuffer = new CXTPSyntaxEditBufferManager;
|
|
|
|
CXTPSyntaxEditConfigurationManager* pMan = GetLexConfigurationManager();
|
|
if (pMan)
|
|
{
|
|
pMan->m_bUseMonitor = m_bUseMonitor;
|
|
pMan->m_bConfigFileMode = m_bConfigFileMode;
|
|
pMan->m_sIniSet = m_sIniSet;
|
|
|
|
if (!m_bConfigFileMode
|
|
&& !m_strSyntaxScheme.IsEmpty()
|
|
&& !m_strColorScheme.IsEmpty())
|
|
{
|
|
pMan->SetSyntaxAndColorScheme(&m_strSyntaxScheme, &m_strColorScheme);
|
|
}
|
|
}
|
|
|
|
if (!m_pBuffer)
|
|
return FALSE;
|
|
|
|
if (GetConfigFile().IsEmpty())
|
|
{
|
|
CString csCfgFilePath = GetDefaultCfgFilePath();
|
|
if (!SetConfigFile(csCfgFilePath))
|
|
{
|
|
// TRACE1("\n*** Could not locate config file '%s'.\n\n", (LPCTSTR)csCfgFilePath);
|
|
}
|
|
}
|
|
_UpdateIMEStatus();
|
|
|
|
SetCurCaretPos(1, 1, FALSE, FALSE);
|
|
|
|
// Advise to events
|
|
m_pSink->UnadviseAll();
|
|
|
|
CXTPNotifyConnection* ptrConnParser = m_pBuffer->GetLexParser()->GetConnection();
|
|
ASSERT(ptrConnParser);
|
|
if (ptrConnParser)
|
|
{
|
|
m_pSink->Advise(ptrConnParser, xtpEditOnParserStarted, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnParseEvent));
|
|
m_pSink->Advise(ptrConnParser, xtpEditOnTextBlockParsed, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnParseEvent));
|
|
m_pSink->Advise(ptrConnParser, xtpEditOnParserEnded, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnParseEvent));
|
|
}
|
|
|
|
CXTPNotifyConnection* ptrConnBufMan = m_pBuffer->GetConnection();
|
|
ASSERT(ptrConnBufMan);
|
|
if (ptrConnBufMan)
|
|
{
|
|
m_pSink->Advise(ptrConnBufMan, xtpEditClassSchWasChanged, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged));
|
|
m_pSink->Advise(ptrConnBufMan, xtpEditThemeWasChanged, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged));
|
|
m_pSink->Advise(ptrConnBufMan, xtpEditAllConfigWasChanged, CreateNotfySinkClassDelegate(this, &CXTPSyntaxEditCtrl::OnLexCfgWasChanged));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
UINT CXTPSyntaxEditCtrl::OnGetDlgCode()
|
|
{
|
|
return DLGC_WANTTAB | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTALLKEYS;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
UNREFERENCED_PARAMETER(pWnd);
|
|
UNREFERENCED_PARAMETER(nHitTest);
|
|
UNREFERENCED_PARAMETER(message);
|
|
|
|
CPoint pt;
|
|
::GetCursorPos(&pt);
|
|
ScreenToClient(&pt);
|
|
|
|
CXTPClientRect rcClient(this);
|
|
CRect rcText(rcClient);
|
|
rcText.left += m_nEditbarLength;
|
|
|
|
CRect rcBookmark(0, 0, GetSelMargin() ? m_nMarginLength : 0, rcClient.Height());
|
|
CRect rcLineNumAndNodes(rcBookmark.right, 0, m_nEditbarLength, rcClient.Height());
|
|
CXTPEmptyRect rcNode;
|
|
|
|
int nRow = 0, nCol = 0, nDispRow = 0;
|
|
RowColFromPoint(pt, &nRow, &nCol, &nDispRow);
|
|
|
|
if (GetCollapsibleNodes())
|
|
{
|
|
// calculate node icon rect
|
|
|
|
DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
|
|
if (GetRowNodes(nRow, dwType) && (dwType & (XTP_EDIT_ROWNODE_COLLAPSED | XTP_EDIT_ROWNODE_EXPANDED)) )
|
|
{
|
|
GetLineNodeRect(nDispRow-1, rcNode);
|
|
}
|
|
}
|
|
|
|
if (m_bDragging)
|
|
{
|
|
if (rcClient.PtInRect(pt))
|
|
{
|
|
if ((::GetKeyState(VK_CONTROL) & KF_UP) == 0)
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurMove());
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurCopy());
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurNO());
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
else if (rcText.PtInRect(pt))
|
|
{
|
|
if (m_pSelection->IsInSel_str(nRow, nCol-1) && !m_pSelection->bSelectingRunning
|
|
|| m_bRightButtonDrag)
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurArrow());
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (!GetBlockFromPt(pt))
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurIBeam());
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (rcBookmark.PtInRect(pt))
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurArrow());
|
|
return TRUE;
|
|
}
|
|
|
|
else if (rcNode.PtInRect(pt))
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurArrow());
|
|
return TRUE;
|
|
}
|
|
|
|
else if (rcLineNumAndNodes.PtInRect(pt))
|
|
{
|
|
SetCursor(GetPaintManager()->GetCurLine());
|
|
return TRUE;
|
|
}
|
|
|
|
SetCursor(GetPaintManager()->GetCurArrow());
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnSetText(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
|
|
LPCTSTR szText = (LPCTSTR)lParam;
|
|
SetText(szText);
|
|
|
|
return (LRESULT)TRUE;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnGetTextLen(WPARAM, LPARAM)
|
|
{
|
|
if (!GetEditBuffer())
|
|
return 0;
|
|
|
|
int nTextSize = 0;
|
|
int nRowsCount = GetRowCount();
|
|
for (int i = 1; i <= nRowsCount; i++)
|
|
{
|
|
nTextSize += GetEditBuffer()->GetLineTextLength(i, i < nRowsCount);
|
|
}
|
|
|
|
return (LRESULT)nTextSize;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnGetText(WPARAM wBufferSize, LPARAM lpBuffer)
|
|
{
|
|
if (wBufferSize == 0)
|
|
return OnGetTextLen(0, 0);
|
|
|
|
CMemFile memFile;
|
|
if (!GetText(memFile, (int)wBufferSize))
|
|
return 0;
|
|
|
|
void* pTextData = NULL;
|
|
void* pTextEnd = NULL;
|
|
|
|
UINT uBufferB = memFile.GetBufferPtr(CFile::bufferRead, (UINT)wBufferSize, &pTextData, &pTextEnd);
|
|
|
|
LPTSTR pDest = (LPTSTR)lpBuffer;
|
|
STRNCPY_S(pDest, wBufferSize, (LPCTSTR)pTextData, wBufferSize - 1);
|
|
pDest[wBufferSize-1] = _T('\0');
|
|
|
|
int nTextSize = (int)uBufferB/sizeof(TCHAR) - sizeof(TCHAR);
|
|
nTextSize = max(0, nTextSize);
|
|
nTextSize = min(nTextSize, (int)wBufferSize);
|
|
|
|
//ASSERT(nTextSize == (int)_tcslen(pDest));
|
|
|
|
return (LRESULT)nTextSize;
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetText(int nMaxLen) const
|
|
{
|
|
CMemFile memFile;
|
|
|
|
if (!GetText(memFile, nMaxLen))
|
|
return _T("");
|
|
|
|
void* pTextData = NULL;
|
|
void* pTextEnd = NULL;
|
|
|
|
memFile.GetBufferPtr(CFile::bufferRead, (UINT)nMaxLen, &pTextData, &pTextEnd);
|
|
|
|
if (pTextEnd)
|
|
{
|
|
TCHAR* pEnd = (TCHAR*)pTextEnd;
|
|
*(pEnd - 1) = _T('\0');
|
|
}
|
|
|
|
return CString((LPCTSTR)pTextData);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetText(CMemFile& memFile, int nMaxLen) const
|
|
{
|
|
if (!GetEditBuffer())
|
|
return FALSE;
|
|
|
|
CArchive ar(&memFile, CArchive::store);
|
|
|
|
BOOL bUnicode = (sizeof(TCHAR) == 2);
|
|
if (nMaxLen > 0)
|
|
nMaxLen = nMaxLen * sizeof(TCHAR);
|
|
|
|
|
|
GetEditBuffer()->SerializeEx(ar, bUnicode, FALSE, (UINT)-1, NULL, nMaxLen);
|
|
|
|
ar << (TCHAR)0;
|
|
|
|
ar.Close();
|
|
|
|
memFile.SeekToBegin();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetText(LPCTSTR pcszText)
|
|
{
|
|
if (!GetEditBuffer() || !pcszText)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
int nStrLenB = (int)_tcslen(pcszText) * sizeof(TCHAR);
|
|
CMemFile memFile((BYTE*)pcszText, nStrLenB);
|
|
memFile.SeekToBegin();
|
|
|
|
CArchive ar(&memFile, CArchive::load);
|
|
|
|
BOOL bUnicode = (sizeof(TCHAR) == 2);
|
|
GetEditBuffer()->SerializeEx(ar, bUnicode);
|
|
|
|
//---------------------------------------
|
|
RefreshColors();
|
|
RecalcScrollBars();
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
UNREFERENCED_PARAMETER(pScrollBar); UNREFERENCED_PARAMETER(nPos);
|
|
|
|
SCROLLINFO info;
|
|
ZeroMemory(&info, sizeof(SCROLLINFO));
|
|
info.cbSize = sizeof(SCROLLINFO);
|
|
info.fMask = SIF_ALL;
|
|
|
|
GetScrollInfo(SB_HORZ, &info);
|
|
|
|
int nStep = m_pDrawTextProcessor->GetTextMetrics().tmAveCharWidth;
|
|
|
|
int nCurrPos = m_pDrawTextProcessor->GetScrollXOffset(); //GetScrollPos(SB_HORZ);
|
|
|
|
switch (nSBCode)
|
|
{
|
|
case SB_LINELEFT:
|
|
nCurrPos -= nStep;
|
|
break;
|
|
case SB_LINERIGHT:
|
|
nCurrPos += nStep;
|
|
break;
|
|
case SB_PAGELEFT:
|
|
nCurrPos -= info.nPage;
|
|
break;
|
|
case SB_PAGERIGHT:
|
|
nCurrPos += info.nPage;
|
|
break;
|
|
case SB_LEFT:
|
|
nCurrPos = info.nMin;
|
|
break;
|
|
case SB_RIGHT:
|
|
nCurrPos = info.nMax;
|
|
case SB_ENDSCROLL:
|
|
return;
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
{
|
|
nCurrPos = nPos;
|
|
int nDelta = ((nCurrPos % nStep) >= nStep/2 ? 1 : 0);
|
|
nCurrPos = (nCurrPos / nStep + nDelta) * nStep;
|
|
ASSERT(nCurrPos <= info.nMax);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
nCurrPos = max(0, nCurrPos);
|
|
|
|
SetScrollPos(SB_HORZ, nCurrPos);
|
|
m_pDrawTextProcessor->SetScrollXOffset(nCurrPos);
|
|
|
|
if (m_bFocused)
|
|
{
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
UNREFERENCED_PARAMETER(nPos);
|
|
UNREFERENCED_PARAMETER(pScrollBar);
|
|
|
|
SCROLLINFO info;
|
|
ZeroMemory(&info, sizeof(SCROLLINFO));
|
|
info.cbSize = sizeof(SCROLLINFO);
|
|
info.fMask = SIF_ALL;
|
|
|
|
GetScrollInfo(SB_VERT, &info);
|
|
|
|
int iMin = 0, iMax = 0;
|
|
GetScrollRange(SB_VERT, &iMin, &iMax);
|
|
|
|
int iPos = GetScrollPos(SB_VERT);
|
|
BOOL bChanged = FALSE;
|
|
|
|
switch (nSBCode) {
|
|
case SB_LINEDOWN:
|
|
bChanged = ShiftCurrentVisibleRowDown(1);
|
|
if (bChanged)
|
|
SetScrollPos(SB_VERT, iPos + 1);
|
|
break;
|
|
case SB_LINEUP:
|
|
bChanged = ShiftCurrentVisibleRowUp(1);
|
|
if (bChanged)
|
|
SetScrollPos(SB_VERT, iPos - 1);
|
|
break;
|
|
case SB_PAGEUP:
|
|
bChanged = ShiftCurrentVisibleRowUp(info.nPage);
|
|
if (bChanged)
|
|
SetScrollPos(SB_VERT, max(1, iPos - info.nPage));
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
bChanged = ShiftCurrentVisibleRowDown(info.nPage);
|
|
if (bChanged)
|
|
SetScrollPos(SB_VERT, (iPos + info.nPage));
|
|
break;
|
|
case SB_TOP:
|
|
SetScrollPos(SB_VERT, iMin);
|
|
SetCurrentDocumentRow(iMin);
|
|
m_nCurrentCol = m_nDispCol = 1;
|
|
bChanged = TRUE;
|
|
break;
|
|
case SB_BOTTOM:
|
|
SetScrollPos(SB_VERT, iMax);
|
|
SetCurrentDocumentRow(iMax);
|
|
m_nCurrentCol = m_nDispCol = 1;
|
|
bChanged = TRUE;
|
|
break;
|
|
case SB_THUMBTRACK:
|
|
{
|
|
SCROLLINFO si;
|
|
ZeroMemory(&si, sizeof(SCROLLINFO));
|
|
si.cbSize = sizeof(SCROLLINFO);
|
|
si.fMask = SIF_TRACKPOS;
|
|
|
|
if (GetScrollInfo(SB_VERT, &si))
|
|
{
|
|
int nShift = si.nTrackPos - GetVisibleRowsCount(m_nTopRow);
|
|
if (nShift > 0)
|
|
{
|
|
bChanged = ShiftCurrentVisibleRowDown(nShift);
|
|
}
|
|
else if (nShift < 0)
|
|
{
|
|
bChanged = ShiftCurrentVisibleRowUp(-nShift);
|
|
}
|
|
SetScrollPos(SB_VERT, si.nTrackPos);
|
|
}
|
|
}
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
int nTopDocRow = GetDocumentRow(1);
|
|
int nBottomDocRow = GetDocumentRow(GetRowPerPage());
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
if (nCurDocRow >= nTopDocRow && nCurDocRow <= nBottomDocRow)
|
|
{
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
if (bChanged)
|
|
{
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
|
|
RecalcScrollBars();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
|
|
|
|
#ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
|
|
if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, TRUE, nChar))
|
|
return;
|
|
#endif
|
|
|
|
if (nChar == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
|
|
|
|
#ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
|
|
if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, TRUE, nChar))
|
|
return;
|
|
#endif
|
|
|
|
if (nChar == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_pToolTip->Hide();
|
|
|
|
if (m_bDragging || m_bRightButtonDrag || m_pSelection->bSelectingRunning /* || m_bSelectionStarted*/)
|
|
{
|
|
OnSetCursor(0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
BOOL bCtrlKey = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
|
|
BOOL bShiftKey = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
|
|
|
|
BOOL bUpdateAll = FALSE;
|
|
int nTopRow_prev = m_nTopRow;
|
|
int nDispCol_prev = m_nDispCol;
|
|
int nTextRow_prev = GetCurrentDocumentRow();
|
|
int nRowCount_prev = GetRowCount();
|
|
CXTPSyntaxEditSelection selData_prev = *m_pSelection;
|
|
|
|
switch (nChar)
|
|
{
|
|
case VK_UP:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (GetCurrentDocumentRow() < 1)
|
|
{
|
|
// Do nothing
|
|
}
|
|
else if (bCtrlKey)
|
|
{
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol) ;
|
|
|
|
ShiftCurrentVisibleRowUp(1, TRUE);
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
|
|
}
|
|
else if (GetCurrentDocumentRow() >= 1)
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey)
|
|
{
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_nDispCol); //m_pSelection->GetNormalEnd_disp().nCol);
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE);
|
|
}
|
|
|
|
MoveCurrentVisibleRowUp(1);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
}
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (bCtrlKey)
|
|
{
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol) ;
|
|
|
|
ShiftCurrentVisibleRowDown(1, TRUE);
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE);
|
|
|
|
}
|
|
else if (GetCurrentDocumentRow() <= GetRowCount())
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey)
|
|
{
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_nDispCol); //m_pSelection->GetNormalEnd_disp().nCol);
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE, TRUE);
|
|
}
|
|
|
|
MoveCurrentVisibleRowDown(1);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_LEFT:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the selection begin
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalStart_disp().nCol);
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalStart_disp().nCol, FALSE/*, FALSE*/);
|
|
break;
|
|
}
|
|
|
|
if (!bCtrlKey)
|
|
{
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
if ((nCurDocRow > 1 && m_nCurrentCol >= 1) ||
|
|
(nCurDocRow == 1 && m_nCurrentCol > 1))
|
|
{
|
|
m_nCurrentCol--;
|
|
}
|
|
|
|
if (m_nCurrentCol < 1 && nCurDocRow > 1)
|
|
{
|
|
if (_IsVirtualSpaceActive())
|
|
m_nCurrentCol = 1;
|
|
else
|
|
MoveCurrentVisibleRowUp(1);
|
|
}
|
|
|
|
LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
|
|
if (m_nCurrentCol < 1)
|
|
m_nCurrentCol = (int)_tcsclen(szText) + 1;
|
|
|
|
m_nDispCol = CalcDispCol(szText, m_nCurrentCol);
|
|
}
|
|
else
|
|
{
|
|
// This will modify Current Row, m_nCurrentCol, m_nDispCol
|
|
FindWord(XTP_EDIT_FINDWORD_PREV);
|
|
}
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the end of the selection
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol);
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
break;
|
|
}
|
|
|
|
if (!bCtrlKey)
|
|
{
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
LPCTSTR szText = GetLineText(nCurDocRow);
|
|
const int nTextLen = (int)_tcsclen(szText);
|
|
if (m_nCurrentCol > nTextLen && (nCurDocRow < GetRowCount()) && !_IsVirtualSpaceActive())
|
|
{
|
|
MoveCurrentVisibleRowDown(1);
|
|
m_nCurrentCol = 1;
|
|
}
|
|
else if (m_nCurrentCol <= nTextLen || _IsVirtualSpaceActive())
|
|
{
|
|
m_nCurrentCol++;
|
|
}
|
|
|
|
m_nDispCol = CalcDispCol(szText, m_nCurrentCol);
|
|
}
|
|
else
|
|
{
|
|
FindWord(XTP_EDIT_FINDWORD_NEXT);
|
|
}
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
break;
|
|
|
|
case VK_HOME:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the selection begin
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol);
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
if (bCtrlKey)
|
|
{
|
|
SetCurrentDocumentRow(1);
|
|
EnsureVisibleRow(1);
|
|
SetCurCaretPos(1, 1, FALSE/*, FALSE*/);
|
|
}
|
|
else
|
|
{
|
|
LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
|
|
|
|
// find number of tabs and spaces from the left
|
|
int iCol = 1;
|
|
LPCTSTR szPtr = szText;
|
|
|
|
while (szPtr)
|
|
{
|
|
if (*szPtr == _T('\t') || *szPtr == _T(' '))
|
|
iCol++;
|
|
else
|
|
break;
|
|
|
|
szPtr = _tcsinc(szPtr);
|
|
}
|
|
|
|
if (m_nCurrentCol == iCol)
|
|
{
|
|
//m_nCurrentCol = 1;
|
|
//m_nDispCol = 1;
|
|
SetCurCaretPos(GetCurrentDocumentRow(), 1, FALSE/*, FALSE*/);
|
|
}
|
|
else
|
|
{
|
|
m_nDispCol = CalcDispCol(szText, iCol);
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
}
|
|
}
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
break;
|
|
case VK_END:
|
|
{
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the end of the selection
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol);
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
if (bCtrlKey)
|
|
{
|
|
SetCurrentDocumentRow(GetRowCount());
|
|
EnsureVisibleRow(GetRowCount());
|
|
}
|
|
|
|
LPCTSTR szText = GetLineText(GetCurrentDocumentRow());
|
|
int nLenC = (int)_tcsclen(szText);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), CalcDispCol(szText, nLenC + 1),
|
|
FALSE/*, FALSE*/);
|
|
}
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
break;
|
|
case VK_PRIOR:
|
|
m_nAutoIndentCol = 0;
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the selection begin
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol);
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
int iRowPerPage = GetRowPerPage();
|
|
|
|
if ((m_nTopRow - iRowPerPage) < 1)
|
|
{
|
|
SetCurrentDocumentRow(1);
|
|
EnsureVisibleRow(1);
|
|
}
|
|
else
|
|
{
|
|
MoveCurrentVisibleRowUp(iRowPerPage);
|
|
}
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_NEXT:
|
|
m_nAutoIndentCol = 0;
|
|
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (!bShiftKey && m_pSelection->IsSelExist())
|
|
{
|
|
// move cursor to the end of the selection
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol);
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
int iRowPerPage = GetRowPerPage();
|
|
|
|
if ((m_nTopRow + iRowPerPage) > GetRowCount())
|
|
{
|
|
SetCurrentDocumentRow(GetRowCount());
|
|
EnsureVisibleRow(GetRowCount());
|
|
}
|
|
else
|
|
{
|
|
MoveCurrentVisibleRowDown(iRowPerPage);
|
|
}
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
|
|
if (bShiftKey)
|
|
m_pSelection->SetEnd_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
else
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_DELETE:
|
|
{
|
|
BOOL bDeleted = TRUE;
|
|
|
|
if (m_pSelection->IsSelExist() && !bCtrlKey)
|
|
{
|
|
bDeleted = DeleteSelection();
|
|
}
|
|
else if (!bCtrlKey)
|
|
{
|
|
if (GetAutoIndent() && m_nAutoIndentCol > 0)
|
|
{
|
|
CString strInsertText(
|
|
CString(_T('\t'), m_nInsertTabCount) +
|
|
CString(_T(' '), m_nInsertSpaceCount));
|
|
|
|
int iNewDispCol = (m_nInsertTabCount * GetTabSize()) + m_nInsertSpaceCount + 1;
|
|
int iNewCol = m_nInsertTabCount + m_nInsertSpaceCount + 1;
|
|
//**----------------------
|
|
OnBeforeEditChanged(GetCurrentDocumentRow(), 1);
|
|
|
|
m_pBuffer->InsertText(strInsertText, GetCurrentDocumentRow(), 1);
|
|
|
|
OnEditChanged(GetCurrentDocumentRow(), 1, GetCurrentDocumentRow(), iNewCol, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
m_nCurrentCol = iNewCol;
|
|
m_nDispCol = iNewDispCol;
|
|
|
|
m_nAutoIndentCol = 0;
|
|
}
|
|
|
|
bDeleted = DeleteChar(GetCurrentDocumentRow(), m_nCurrentCol, xtpEditDelPosAfter);
|
|
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
else
|
|
{
|
|
BOOL bSelectionExist = m_pSelection->IsSelExist();
|
|
int nDelFlags = 0;
|
|
|
|
if (bSelectionExist)
|
|
{
|
|
nDelFlags |= xtpEditForceRedraw;
|
|
DeleteSelection();
|
|
}
|
|
|
|
int iStartRow = GetCurrentDocumentRow();
|
|
int iStartCol = m_nCurrentCol;
|
|
|
|
FindWord(XTP_EDIT_FINDWORD_NEXT);
|
|
|
|
int iEndRow = GetCurrentDocumentRow();
|
|
int iEndCol = m_nCurrentCol;
|
|
|
|
DeleteBuffer(iStartRow, iStartCol, iEndRow, iEndCol, nDelFlags);
|
|
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (bSelectionExist)
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
}
|
|
|
|
bUpdateAll = TRUE;
|
|
|
|
m_nAutoIndentCol = 0;
|
|
}
|
|
|
|
break;
|
|
case VK_BACK:
|
|
if (m_nAutoIndentCol > 0)
|
|
{
|
|
if (m_nInsertSpaceCount == 0)
|
|
m_nInsertTabCount--;
|
|
else
|
|
m_nInsertSpaceCount--;
|
|
|
|
if (m_nInsertTabCount || m_nInsertSpaceCount)
|
|
{
|
|
m_nAutoIndentCol = (m_nInsertTabCount * GetTabSize()) + m_nInsertSpaceCount + 1;
|
|
m_nDispCol = m_nAutoIndentCol;
|
|
}
|
|
else
|
|
{
|
|
m_nAutoIndentCol = 0;
|
|
m_nDispCol = 1;
|
|
}
|
|
}
|
|
else if (!bCtrlKey)
|
|
{
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
DeleteSelection();
|
|
}
|
|
else
|
|
{
|
|
DeleteChar(GetCurrentDocumentRow(), m_nCurrentCol, xtpEditDelPosBefore);
|
|
}
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
else
|
|
{
|
|
BOOL bSelectionExist = m_pSelection->IsSelExist();
|
|
|
|
if (bSelectionExist)
|
|
{
|
|
DeleteSelection();
|
|
}
|
|
|
|
int iStartRow = GetCurrentDocumentRow();
|
|
int iStartCol = m_nCurrentCol;
|
|
|
|
FindWord(XTP_EDIT_FINDWORD_PREV);
|
|
|
|
int iEndRow = GetCurrentDocumentRow();
|
|
int iEndCol = m_nCurrentCol;
|
|
|
|
DeleteBuffer(iStartRow, iStartCol, iEndRow, iEndCol);
|
|
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (bSelectionExist)
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
|
|
}
|
|
|
|
bUpdateAll = TRUE;
|
|
|
|
break;
|
|
case VK_INSERT:
|
|
{
|
|
NotifyParent(XTP_EDIT_NM_INSERTKEY);
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
|
|
SetOverwriteMode(!m_pBuffer->GetOverwriteFlag());
|
|
}
|
|
break;
|
|
case VK_SPACE:
|
|
if (bCtrlKey)
|
|
{
|
|
CPoint pt(CWnd::GetCaretPos());
|
|
pt.y += m_pDrawTextProcessor->GetRowHeight();
|
|
ClientToScreen(&pt);
|
|
|
|
CString strText(GetLineText(GetCurrentDocumentRow()));
|
|
int nTextPos = m_nCurrentCol - 2;
|
|
|
|
CString strSearch;
|
|
//NON-COVERED CASE <<
|
|
if (m_pAutoComplete->m_strDelims.IsEmpty())
|
|
m_pAutoComplete->m_strDelims = _T(" \t");
|
|
//NON-COVERED CASE <<
|
|
while (strText.GetLength() > 0 && nTextPos >= 0 && m_pAutoComplete->m_strDelims.Find(strText.GetAt(nTextPos)) < 0)
|
|
{
|
|
strSearch = strText.GetAt(nTextPos--) + strSearch;
|
|
}
|
|
SetAutoCompleteList();
|
|
m_pAutoComplete->Show(pt, strSearch);
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
BOOL bChanged = nTopRow_prev != m_nTopRow || nDispCol_prev != m_nDispCol ||
|
|
nTextRow_prev != GetCurrentDocumentRow() || nRowCount_prev != GetRowCount() ||
|
|
selData_prev != *m_pSelection;
|
|
if (bChanged)
|
|
{
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
if (nTopRow_prev != m_nTopRow)
|
|
RecalcScrollBars();
|
|
|
|
DWORD dwUpdate = (XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
|
|
|
|
if (bUpdateAll)
|
|
dwUpdate |= XTP_EDIT_UPDATE_DIAG;
|
|
|
|
UpdateScrollPos(dwUpdate);
|
|
}
|
|
|
|
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
if (m_bDragging || m_bRightButtonDrag)
|
|
{
|
|
OnSetCursor(0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
NotifySelInit();
|
|
|
|
BOOL bAltKey = (::GetKeyState(VK_MENU) & KF_UP) != 0;
|
|
BOOL bCtrlKey = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
|
|
BOOL bShiftKey = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
|
|
CString strCurCRLF = m_pBuffer->GetCurCRLF();
|
|
LPCTSTR szCurCRLF = strCurCRLF;
|
|
|
|
BOOL bProcessed = FALSE;
|
|
|
|
if (nChar == VK_TAB && !bCtrlKey)
|
|
{
|
|
if (bShiftKey)
|
|
bProcessed = DecreaseIndent();
|
|
else
|
|
bProcessed = IncreaseIndent();
|
|
}
|
|
|
|
if (!bProcessed && (bCtrlKey && !bAltKey) && nChar == 0x0C) // 0x0C is 'l' or 'L'
|
|
{
|
|
// Delete the entire line or the selection
|
|
DeleteSelectedLines(GetCurrentDocumentRow());
|
|
}
|
|
else if (nChar != VK_BACK && nChar != VK_ESCAPE && !(bCtrlKey && !bAltKey) && !bProcessed)
|
|
{
|
|
if (!CanEditDoc())
|
|
{
|
|
return;
|
|
}
|
|
BOOL bModified = FALSE;
|
|
//**----------------------
|
|
OnBeforeEditChanged(GetCurrentDocumentRow(), m_nCurrentCol);
|
|
//**----------------------
|
|
|
|
int nChainActionCount = 1;
|
|
BOOL bRedraw = FALSE;
|
|
BOOL bPrevOverwriteMode = m_pBuffer->GetOverwriteFlag();
|
|
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
if (!m_pBuffer->GetOverwriteFlag() || (m_pBuffer->GetOverwriteFlag() && nChar != VK_RETURN))
|
|
{
|
|
BOOL bRes = DeleteSelection();
|
|
bModified |= bRes;
|
|
|
|
nChainActionCount = 2;
|
|
bRedraw = TRUE;
|
|
m_pBuffer->SetOverwriteFlag(FALSE);
|
|
}
|
|
}
|
|
|
|
TCHAR szText[3];
|
|
szText[0] = (TCHAR)nChar;
|
|
szText[1] = NULL;
|
|
|
|
// DBCS Support (specially for IME)
|
|
#ifndef _UNICODE
|
|
//if (m_bIsImeEnabled)
|
|
if (isleadbyte((int)nChar) && m_chPrevLeadByte == 0)
|
|
{
|
|
// do not process lead byte. just remember it and exit.
|
|
m_chPrevLeadByte = (BYTE)nChar;
|
|
return;
|
|
}
|
|
|
|
if (m_chPrevLeadByte)
|
|
{
|
|
szText[0] = (TCHAR)m_chPrevLeadByte;
|
|
szText[1] = (TCHAR)nChar;
|
|
szText[2] = NULL;
|
|
}
|
|
m_chPrevLeadByte = 0;
|
|
#endif
|
|
|
|
if (nChar == _T('\r'))
|
|
{
|
|
lstrcpy(szText, szCurCRLF);
|
|
szText[2] = NULL;
|
|
|
|
// here we should expand collapsed block if we are on it
|
|
if (GetLineMarksManager()->HasRowMark(GetCurrentDocumentRow(), xtpEditLMT_Collapsed))
|
|
{
|
|
GetLineMarksManager()->DeleteLineMark(GetCurrentDocumentRow(), xtpEditLMT_Collapsed);
|
|
}
|
|
}
|
|
|
|
int iNewDispCol = m_nDispCol;
|
|
int iNewCol = m_nCurrentCol;
|
|
int iNewRow = GetCurrentDocumentRow();
|
|
int iEditRowFrom = iNewRow;
|
|
int iEditRowTo = iNewRow;
|
|
|
|
CString strTextToIns;
|
|
|
|
// Create text to insert
|
|
BOOL bCanProcess =
|
|
CreateInsertText(szText,
|
|
strTextToIns,
|
|
iNewRow,
|
|
iNewCol,
|
|
iNewDispCol,
|
|
iEditRowFrom,
|
|
iEditRowTo,
|
|
nChainActionCount);
|
|
|
|
BOOL bGroupInsMode = FALSE;
|
|
|
|
if (!bPrevOverwriteMode)
|
|
{
|
|
static LPCTSTR szSeps = _T(" [{()}];.,\t\r\n\"");
|
|
|
|
if (_tcschr(szSeps, (TCHAR)nChar))
|
|
bGroupInsMode = FALSE;
|
|
else
|
|
bGroupInsMode = TRUE;
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(bGroupInsMode);
|
|
}
|
|
else
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
if (bCanProcess)
|
|
{
|
|
int nInsCol = m_nCurrentCol;
|
|
if (nChar == VK_RETURN && m_nAutoIndentCol)
|
|
nInsCol = min(m_nCurrentCol, m_pBuffer->GetLineTextLengthC(GetCurrentDocumentRow()) + 1);
|
|
|
|
BOOL bInsRes = m_pBuffer->InsertText(strTextToIns, GetCurrentDocumentRow(), nInsCol, TRUE);
|
|
bModified |= bInsRes;
|
|
|
|
if (nChainActionCount > 1)
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_TYPING);
|
|
}
|
|
}
|
|
|
|
//m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
m_pBuffer->SetOverwriteFlag(bPrevOverwriteMode);
|
|
|
|
//**----------------------
|
|
OnEditChanged(GetCurrentDocumentRow(), m_nCurrentCol, iNewRow, iNewCol, xtpEditActInsert);
|
|
//**----------------------
|
|
BOOL bInsAt0 = (m_nCurrentCol == 1) || GetLineText(GetCurrentDocumentRow()).GetLength() == 0;
|
|
|
|
m_nCurrentCol = iNewCol;
|
|
m_nDispCol = iNewDispCol;
|
|
|
|
SetCurrentDocumentRow(iNewRow);
|
|
|
|
BOOL bNewRow = FALSE;
|
|
|
|
if (nChar == VK_RETURN)
|
|
bNewRow = TRUE;
|
|
|
|
UINT nAction = XTP_EDIT_EDITACTION_MODIFYROW;
|
|
|
|
if (bNewRow)
|
|
nAction |= XTP_EDIT_EDITACTION_INSERTROW;
|
|
|
|
if (bNewRow && bInsAt0)
|
|
nAction |= XTP_EDIT_EDITACTION_INSERTROW_NEW;
|
|
|
|
|
|
NotifyEditChanged(iEditRowFrom, iEditRowTo, nAction);
|
|
|
|
// if (nChar == VK_RETURN)
|
|
// {
|
|
// DoAutoIndentIfNeed(nDispCol_prev);
|
|
// }
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
RecalcScrollBars();
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
UpdateScrollPos();
|
|
|
|
if (bModified)
|
|
SetDocModified();
|
|
|
|
}
|
|
else if (!bProcessed && nChar == VK_ESCAPE)
|
|
{
|
|
Unselect();
|
|
UpdateScrollPos();
|
|
}
|
|
|
|
// AutoComplete Processing
|
|
if (m_pAutoComplete->IsOpenTag((TCHAR)nChar))
|
|
{
|
|
CPoint pt(CWnd::GetCaretPos());
|
|
pt.y += m_pDrawTextProcessor->GetRowHeight();
|
|
ClientToScreen(&pt);
|
|
SetAutoCompleteList();
|
|
m_pAutoComplete->Show(pt);
|
|
}
|
|
|
|
CWnd::OnChar(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
|
|
|
|
#ifdef XTP_SYNTAXEDIT_SITENOTIFY_KEY
|
|
if (!XTP_SYNTAXEDIT_SITENOTIFY_KEY(this, FALSE, nChar))
|
|
return;
|
|
#endif
|
|
|
|
if (nChar == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_bDragging)
|
|
{
|
|
OnSetCursor(0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetCurPos(int nTextRow, int nDispCol, BOOL bRemainSelected, BOOL bForceVisible)
|
|
{
|
|
if (nTextRow > GetRowCount())
|
|
nTextRow = GetRowCount();
|
|
|
|
//reset autoindent
|
|
m_nAutoIndentCol = 0;
|
|
|
|
CString strText = GetLineText(nTextRow);
|
|
|
|
// validate col
|
|
m_nCurrentCol = CalcAbsCol(strText, nDispCol);
|
|
m_nDispCol = CalcDispCol(strText, m_nCurrentCol);
|
|
|
|
if (!bRemainSelected && m_pSelection->IsSelExist())
|
|
{
|
|
m_pSelection->Reset_disp(nTextRow, m_nDispCol);
|
|
}
|
|
|
|
SetCurCaretPos(nTextRow, m_nDispCol, TRUE, bForceVisible);
|
|
|
|
if (::IsWindow(m_hWnd) || m_hWnd)
|
|
{
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
else
|
|
InvalidateAll();
|
|
|
|
UpdateScrollPos(XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetCurCaretPos(int nTextRow, int nDispCol, BOOL bRowColNotify, BOOL bEnsureVisible)
|
|
{
|
|
if (!::IsWindow(m_hWnd) || !m_hWnd)
|
|
return;
|
|
|
|
if (bEnsureVisible)
|
|
_EnsureVisible(nTextRow, nDispCol);
|
|
|
|
int nDispRow = GetVisibleRow(nTextRow);
|
|
if (nDispRow > m_pDrawTextProcessor->GetRowsCount(TRUE) + 10)
|
|
nDispRow = m_pDrawTextProcessor->GetRowsCount(TRUE) + 10;
|
|
|
|
if (m_nAutoIndentCol > 0)
|
|
nDispCol = m_nAutoIndentCol;
|
|
int nCol = max(0, nDispCol - 1);
|
|
|
|
m_nDispCol = nCol + 1;
|
|
m_nCurrentCol = CalcAbsCol(nTextRow, m_nDispCol);
|
|
SetCurrentDocumentRow(nTextRow);
|
|
|
|
if (bRowColNotify)
|
|
NotifyCurRowCol(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
//TRACE(_T("CXTPSyntaxEditCtrl::SetCurCaretPos(%d, %d) \n"), nDispRow, nDispCol);
|
|
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::_EnsureVisible(int nTextRow, int nDispCol/*, BOOL bRedraw*/)
|
|
{
|
|
BOOL bVScrolled = EnsureVisibleRow(nTextRow);
|
|
|
|
nDispCol = nDispCol;
|
|
if (m_nAutoIndentCol > 0)
|
|
nDispCol = m_nAutoIndentCol;
|
|
|
|
int nDispRow = GetVisibleRow(nTextRow);
|
|
|
|
BOOL bHScrolled = EnsureVisibleCol(nDispRow, nDispCol);
|
|
|
|
// BOOL bVirtSpace = _IsVirtualSpaceActive() || m_nAutoIndentCol;
|
|
// m_nCurrentCol = m_pDrawTextProcessor->DispPosToStrPos(nDispRow - 1, m_nDispCol-1, bVirtSpace) + 1;
|
|
|
|
if (bVScrolled || bHScrolled /*|| bRedraw*/)
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::EnsureVisibleRow(int nTextRow)
|
|
{
|
|
int nPrevTopRow = m_nTopRow;
|
|
|
|
int nDispRowsCount = m_pDrawTextProcessor->GetRowsCount(FALSE);
|
|
int nCurPageMaxTextRow = GetDocumentRow(nDispRowsCount);
|
|
|
|
if (nDispRowsCount == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (nTextRow > nCurPageMaxTextRow)
|
|
{
|
|
m_nTopRow += nTextRow - nCurPageMaxTextRow;
|
|
}
|
|
else if (nTextRow < m_nTopRow)
|
|
{
|
|
m_nTopRow = max (1, nTextRow);
|
|
}
|
|
|
|
if (GetVertScrollBar() /*&& nPrevTopRow != m_nTopRow*/)
|
|
{
|
|
BOOL bEnableVertScrl = (CalculateVisibleRow(1, GetRowCount()) > nDispRowsCount);
|
|
|
|
EnableScrollBarCtrl(SB_VERT, bEnableVertScrl);
|
|
if (bEnableVertScrl)
|
|
SetScrollPos(SB_VERT, CalculateVisibleRow(1, m_nTopRow));
|
|
}
|
|
|
|
return nPrevTopRow != m_nTopRow;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::EnsureVisibleCol(int nDispRow, int nDispCol)
|
|
{
|
|
int nTextRow = GetDocumentRow(nDispRow);
|
|
UpdateRowInfoInternally(nTextRow);
|
|
|
|
int nColWidth = 0;
|
|
int nColPos = m_pDrawTextProcessor->GetColPosX(nDispRow - 1, nDispCol, &nColWidth, IsEnabledVirtualSpace());
|
|
int nOffsetX = m_pDrawTextProcessor->GetScrollXOffset();
|
|
|
|
CRect rcText = m_pDrawTextProcessor->GetTextRect();
|
|
int nNewScrollOffset = -1;
|
|
|
|
if (nColPos - max(14, nColWidth * 2) < rcText.left)
|
|
{
|
|
nNewScrollOffset = max(0, nOffsetX - (rcText.left - nColPos )- nColWidth * 15);
|
|
}
|
|
else if (nColPos + nColWidth >= rcText.right)
|
|
{
|
|
nNewScrollOffset = nOffsetX + (nColPos + nColWidth) - rcText.right + min(rcText.Width()/3, nColWidth * 15);
|
|
}
|
|
|
|
if (nNewScrollOffset >= 0)
|
|
{
|
|
SetScrollPos(SB_HORZ, nNewScrollOffset);
|
|
m_pDrawTextProcessor->SetScrollXOffset(nNewScrollOffset);
|
|
}
|
|
|
|
return nNewScrollOffset >= 0;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcDispCol(int nTextRow, int nActualCol) const
|
|
{
|
|
CString strLine = GetLineText(nTextRow);
|
|
return CalcDispCol(strLine, nActualCol);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcAbsCol(int nTextRow, int nDispCol) const
|
|
{
|
|
CString strLine = GetLineText(nTextRow);
|
|
return CalcAbsCol(strLine, nDispCol);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcDispCol(LPCTSTR szText, int nActualCol) const
|
|
{
|
|
int iDispCol = 0;
|
|
int nAbsCol = 1;
|
|
|
|
for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
|
|
{
|
|
if (nAbsCol >= nActualCol)
|
|
break;
|
|
|
|
if (*pcszChar == _T('\t'))
|
|
{
|
|
// Now calculate tab size
|
|
iDispCol += (GetTabSize() - (iDispCol % GetTabSize()));
|
|
}
|
|
#ifdef XTP_FIXED
|
|
else if (isleadbyte( *pcszChar ))
|
|
// multi byte character : DisplayLength 2
|
|
iDispCol += 2;
|
|
#endif
|
|
else
|
|
iDispCol++;
|
|
|
|
nAbsCol++;
|
|
}
|
|
|
|
iDispCol++;
|
|
|
|
if (nAbsCol < nActualCol)
|
|
{
|
|
if (_IsVirtualSpaceActive())
|
|
iDispCol += nActualCol - nAbsCol;
|
|
else
|
|
iDispCol++;
|
|
}
|
|
|
|
return iDispCol;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcAbsCol(LPCTSTR szText, int iDispCol) const
|
|
{
|
|
int nAbsCol = 0;
|
|
int nDispColCalc = 0;
|
|
|
|
for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
|
|
{
|
|
if (nDispColCalc >= iDispCol)
|
|
break;
|
|
|
|
//if (szText[i] == _T('\t'))
|
|
if (*pcszChar == _T('\t'))
|
|
nDispColCalc += (GetTabSize() - (nDispColCalc % GetTabSize()));
|
|
#ifdef XTP_FIXED
|
|
else if (isleadbyte( *pcszChar ))
|
|
// multi byte character : DisplayLength 2
|
|
nDispColCalc += 2;
|
|
#endif
|
|
else
|
|
nDispColCalc++;
|
|
|
|
nAbsCol++;
|
|
}
|
|
|
|
if (nDispColCalc < iDispCol)
|
|
{
|
|
if (_IsVirtualSpaceActive())
|
|
nAbsCol += iDispCol - nDispColCalc;
|
|
else
|
|
nAbsCol++;
|
|
}
|
|
|
|
if (nAbsCol == 0)
|
|
nAbsCol = 1;
|
|
|
|
return nAbsCol;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcValidDispCol(LPCTSTR szText, int iCol) const
|
|
{
|
|
int iDispCol = 0;
|
|
|
|
for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
|
|
{
|
|
if (iDispCol >= iCol-1)
|
|
break;
|
|
|
|
if (*pcszChar == _T('\t'))
|
|
{
|
|
// Now calculate tab size
|
|
iDispCol += (GetTabSize() - (iDispCol % GetTabSize()));
|
|
}
|
|
#ifdef XTP_FIXED
|
|
else if (isleadbyte(*pcszChar))
|
|
// multi byte character : DisplayLength 2
|
|
iDispCol += 2;
|
|
#endif
|
|
else
|
|
iDispCol++;
|
|
}
|
|
|
|
return ++iDispCol;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalcMaximumWidth(LPCTSTR szText)
|
|
{
|
|
int iMaxWidth = 1;
|
|
|
|
for (LPCTSTR pcszChar = szText; pcszChar && *pcszChar; pcszChar = _tcsinc(pcszChar))
|
|
{
|
|
if (*pcszChar == _T('\t'))
|
|
{
|
|
// Now calculate tab size
|
|
iMaxWidth += ((GetTabSize() + 1) - (iMaxWidth - ((iMaxWidth / GetTabSize()) * GetTabSize())));
|
|
}
|
|
#ifdef XTP_FIXED
|
|
else if (isleadbyte(*pcszChar))
|
|
// multi byte character : DisplayLength 2
|
|
iMaxWidth += 2;
|
|
#endif
|
|
else
|
|
iMaxWidth++;
|
|
}
|
|
|
|
return iMaxWidth;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::GetLineNodeRect(int nRow, CRect& rcNode, CRect* prcNodeFull) const
|
|
{
|
|
// calculate node rect
|
|
CRect rcNodes, rcText;
|
|
CalcEditRects(NULL, NULL, &rcNodes, &rcText);
|
|
|
|
int nRowHeight = m_pDrawTextProcessor->GetRowHeight();
|
|
int nYPos = rcNodes.top + nRow * nRowHeight;
|
|
|
|
rcNode = rcNodes;
|
|
rcNode.top = nYPos + (nRowHeight - m_nNodesWidth) / 2;
|
|
rcNode.bottom = rcNode.top + m_nNodesWidth - 1;
|
|
|
|
if (prcNodeFull)
|
|
{
|
|
prcNodeFull->left = rcNodes.left;
|
|
prcNodeFull->right = rcText.left;
|
|
prcNodeFull->top = nYPos;
|
|
prcNodeFull->bottom = nYPos + nRowHeight;
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::ProcessCollapsedTextEx(CDC* pDC, XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk,
|
|
const XTP_EDIT_TEXTBLOCK& txtBlk,
|
|
CRect& rcCoBlk)
|
|
{
|
|
if (!pCoDrawBlk)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
if (txtBlk.nPos < pCoDrawBlk->collBlock.lcStart.nCol)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ProcessCollapsedText(pDC, pCoDrawBlk, rcCoBlk);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ProcessCollapsedText(CDC* pDC, XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk,
|
|
CRect& rcCoBlk)
|
|
{
|
|
CString strText = pCoDrawBlk->collBlock.strCollapsedText; // "[..]"
|
|
|
|
CXTPFontDC fontDC(pDC, GetPaintManager()->GetFont());
|
|
|
|
rcCoBlk.right = rcCoBlk.left + pDC->GetTextExtent(strText).cx + 3;
|
|
pCoDrawBlk->rcCollMark = rcCoBlk;
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetCollapsedText(XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk, int nMaxLinesCount) const
|
|
{
|
|
if (!pCoDrawBlk || !m_pBuffer)
|
|
{
|
|
ASSERT(FALSE);
|
|
return _T("");
|
|
}
|
|
CString strCoText;
|
|
|
|
int nLine1 = pCoDrawBlk->collBlock.lcStart.nLine;
|
|
int nLine2 = pCoDrawBlk->collBlock.lcEnd.nLine;
|
|
int nLine2max = min(nLine2, nLine1 + nMaxLinesCount-1);
|
|
|
|
int nCol1 = pCoDrawBlk->collBlock.lcStart.nCol;
|
|
int nCol2 = pCoDrawBlk->collBlock.lcEnd.nCol;
|
|
|
|
for (int nLine = nLine1; nLine <= nLine2max; nLine++)
|
|
{
|
|
CString strTmp = m_pBuffer->GetLineText(nLine);
|
|
int nTextLen = strTmp.GetLength();
|
|
|
|
if (nTextLen)
|
|
{
|
|
if (nLine == nLine2)
|
|
{
|
|
ASSERT(nCol2 < nTextLen+2);
|
|
nCol2 = max(0, min(nCol2, nTextLen-1));
|
|
strTmp = strTmp.Left(nCol2+1);
|
|
}
|
|
|
|
if (nLine == nLine1)
|
|
{
|
|
nTextLen = strTmp.GetLength();
|
|
ASSERT(nCol1 < nTextLen+2);
|
|
|
|
if (nCol1 < nTextLen)
|
|
{
|
|
strTmp = strTmp.Mid(nCol1);
|
|
}
|
|
else
|
|
{
|
|
strTmp.Empty();
|
|
}
|
|
}
|
|
}
|
|
if (!strCoText.IsEmpty())
|
|
{
|
|
strCoText += _T("\r\n");
|
|
}
|
|
strCoText += strTmp;
|
|
}
|
|
|
|
return strCoText;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::ExpandChars(CDC* pDC, LPCTSTR pszChars, int nCurPos, CString& strBuffer)
|
|
{
|
|
int nTabSize = GetTabSize();
|
|
|
|
const int nLength = (int)_tcslen(pszChars);
|
|
if (nLength == 0)
|
|
return 0;
|
|
|
|
int nActualOffset = nCurPos;
|
|
int I;
|
|
for (I = 0; I < nLength; I++)
|
|
{
|
|
if (pszChars[I] == _T('\t'))
|
|
nActualOffset += (nTabSize - nActualOffset % nTabSize);
|
|
else
|
|
nActualOffset ++;
|
|
}
|
|
|
|
int nActualLength = nActualOffset - nCurPos;
|
|
|
|
for (I = 0; I < nLength; I++)
|
|
{
|
|
if (pszChars[I] == _T('\t'))
|
|
{
|
|
int nSpaces = nTabSize - (nCurPos % nTabSize);
|
|
|
|
BOOL bFirstChar = TRUE;
|
|
while (nSpaces > 0)
|
|
{
|
|
if (bFirstChar && IsEnabledWhiteSpace() && !pDC->IsPrinting())
|
|
{
|
|
strBuffer += (TCHAR)(unsigned char)0xBB;
|
|
bFirstChar = FALSE;
|
|
}
|
|
else
|
|
strBuffer += _T(' ');
|
|
|
|
nSpaces--;
|
|
nCurPos++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsEnabledWhiteSpace() && pszChars[I] == _T(' ') && !pDC->IsPrinting())
|
|
strBuffer += (TCHAR)(unsigned char)0xB7;
|
|
else
|
|
strBuffer += pszChars[I];
|
|
|
|
nCurPos++;
|
|
}
|
|
}
|
|
|
|
return nActualLength;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
if (IsViewOnly() && !m_bAllowExpandCollapse)
|
|
return;
|
|
|
|
if (!IsViewOnly())
|
|
{
|
|
SetFocus();
|
|
|
|
// Manage AutoCompleteView
|
|
if (m_pAutoComplete->IsActive())
|
|
{
|
|
CRect rcACcomplete;
|
|
m_pAutoComplete->GetWindowRect(&rcACcomplete);
|
|
ScreenToClient(&rcACcomplete);
|
|
if (rcACcomplete.PtInRect(point))
|
|
return;
|
|
else
|
|
m_pAutoComplete->Hide();
|
|
}
|
|
|
|
m_bDragging = FALSE;
|
|
m_bRightButtonDrag = FALSE;
|
|
m_nAutoIndentCol = 0;
|
|
|
|
m_pSelection->bSelectingRunning = FALSE;
|
|
|
|
if (m_pSelection->IsSelExist())
|
|
Invalidate(FALSE);
|
|
|
|
NotifySelInit();
|
|
|
|
SetCapture();
|
|
}
|
|
|
|
BOOL bCtrlKey = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
|
|
BOOL bShiftKey = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
|
|
BOOL bAltKey = (::GetKeyState(VK_MENU) & KF_UP) != 0;
|
|
|
|
CXTPClientRect rcClient(this);
|
|
|
|
CRect rcBookmark, rcLineNum, rcNodes, rcText;
|
|
rcClient.bottom = rcClient.top + m_pDrawTextProcessor->GetRowHeight() * m_pDrawTextProcessor->GetRowsCount(FALSE);
|
|
CalcEditRects(&rcBookmark, &rcLineNum, &rcNodes, &rcText, &rcClient);
|
|
|
|
CRect rcLineNumAndNodes(rcLineNum);
|
|
rcLineNumAndNodes.right = rcNodes.right;
|
|
|
|
int nNewRow = 0, nNewCol = 0, nNewDispRow = 0, nNewDispCol = 0;
|
|
RowColFromPoint(point, &nNewRow, &nNewCol, &nNewDispRow, &nNewDispCol);
|
|
BOOL bSelFromLeftBar = rcLineNumAndNodes.PtInRect(point);
|
|
|
|
// TRACE(_T("*** OnLButtonDown. RowColFromPoint: nNewRow=%d, nNewCol=%d, nNewDispRow=%d, nNewDispCol=%d \n"),
|
|
// nNewRow, nNewCol, nNewDispRow, nNewDispCol);
|
|
if (!IsViewOnly())
|
|
{
|
|
if (GetCurrentDocumentRow() != nNewRow || m_nDispCol != nNewDispCol)
|
|
{
|
|
// reset undo buffer group mode processing
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
}
|
|
|
|
if (rcBookmark.PtInRect(point))
|
|
{
|
|
m_pSelection->Reset_disp(nNewRow, nNewDispCol);
|
|
|
|
if (!NotifyMarginLBtnClick(nNewRow, nNewDispRow))
|
|
{
|
|
AddRemoveBreakPoint(nNewRow);
|
|
SetCurPos(nNewRow, 1);
|
|
}
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
|
|
return;
|
|
}
|
|
}
|
|
if (!IsViewOnly() || (IsViewOnly() && m_bAllowExpandCollapse))
|
|
{
|
|
if (GetCollapsibleNodes() && rcNodes.PtInRect(point))
|
|
{
|
|
CXTPEmptyRect rcNode;
|
|
|
|
DWORD dwType = XTP_EDIT_ROWNODE_NOTHING;
|
|
if (GetRowNodes(nNewRow, dwType) && (dwType & (XTP_EDIT_ROWNODE_COLLAPSED | XTP_EDIT_ROWNODE_EXPANDED)))
|
|
{
|
|
GetLineNodeRect(nNewDispRow-1, rcNode);
|
|
}
|
|
|
|
if (rcNode.PtInRect(point) && m_pBuffer)
|
|
{
|
|
m_pSelection->Reset_disp(m_pSelection->GetEnd_disp().nLine, m_pSelection->GetEnd_disp().nCol);
|
|
|
|
// expand/collapse a node
|
|
CollapseExpandBlock(nNewRow);
|
|
SetCurPos(nNewRow, 1);
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (!IsViewOnly())
|
|
{
|
|
if (rcText.PtInRect(point) && m_pSelection->IsInSel_disp(nNewRow, nNewDispCol))
|
|
{
|
|
m_pSelection->bSelectingRunning = FALSE;
|
|
|
|
if (!m_bEnableOleDrag)
|
|
m_bDragging = TRUE;
|
|
else
|
|
NotifyParent(XTP_EDIT_NM_STARTOLEDRAG);
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
|
|
return;
|
|
}
|
|
|
|
if (bAltKey)
|
|
{
|
|
m_pSelection->Reset_disp(nNewRow, nNewDispCol);
|
|
m_pSelection->bSelectingRunning = TRUE;
|
|
m_pSelection->bBlockSelectionMode = TRUE;
|
|
}
|
|
else if (bShiftKey)
|
|
{
|
|
m_pSelection->SetEnd_disp(nNewRow, nNewDispCol);
|
|
|
|
m_pSelection->bSelectingRunning = TRUE;
|
|
m_pSelection->bBlockSelectionMode = FALSE;
|
|
m_pSelection->bWordSelectionMode = bCtrlKey;
|
|
}
|
|
else
|
|
{
|
|
m_pSelection->Reset_disp(nNewRow, nNewDispCol);
|
|
m_pSelection->bSelectingRunning = TRUE;
|
|
m_pSelection->bWordSelectionMode = bCtrlKey;
|
|
if (bSelFromLeftBar)
|
|
m_pSelection->nSelStartTextRowFromLeftBar = m_pSelection->GetStart_str().nLine;
|
|
}
|
|
|
|
// TRACE(_T("Selection: (row=%d, strPos=%d, DispCol=%d)-(row=%d, strPos=%d, DispCol=%d) \n"),
|
|
// m_pSelection->GetStart_str().nLine, m_pSelection->GetStart_str().nCol, m_pSelection->GetStart_disp().nCol,
|
|
// m_pSelection->GetEnd_str().nLine, m_pSelection->GetEnd_str().nCol, m_pSelection->GetEnd_disp().nCol);
|
|
|
|
if (m_pSelection->bWordSelectionMode)
|
|
{
|
|
XTP_EDIT_LINECOL lcWord1, lcWord2;
|
|
BOOL bOverSpace = FALSE;
|
|
|
|
UINT nFindDir = m_pSelection->IsSelNormal() ? XTP_EDIT_FINDWORD_NEXT : XTP_EDIT_FINDWORD_PREV;
|
|
BOOL bFind = FindWordEx_str(nFindDir, m_pSelection->GetEnd_str(), lcWord1, lcWord2, bOverSpace);
|
|
// TRACE(_T("1-FindWordEx_str = %d (%d, %d - %d, %d)"), bFind,
|
|
// lcWord1.nLine, lcWord1.nCol, lcWord2.nLine, lcWord2.nCol);
|
|
|
|
if (bFind && lcWord1.IsValidData() && lcWord1 != m_pSelection->GetNormalStart_str())
|
|
{
|
|
if (m_pSelection->IsSelNormal())
|
|
m_pSelection->SetStart_str(lcWord1.nLine, lcWord1.nCol-1);
|
|
else
|
|
m_pSelection->SetEnd_str(lcWord1.nLine, lcWord1.nCol-1);
|
|
}
|
|
|
|
if (lcWord2.IsValidData() && lcWord2 != m_pSelection->GetNormalEnd_str())
|
|
{
|
|
if (m_pSelection->IsSelNormal())
|
|
m_pSelection->SetEnd_str(lcWord2.nLine, lcWord2.nCol-1);
|
|
else
|
|
m_pSelection->SetStart_str(lcWord2.nLine, lcWord2.nCol-1);
|
|
}
|
|
}
|
|
|
|
SetCurrentDocumentRow(nNewRow);
|
|
m_nDispCol = m_pSelection->GetEnd_disp().nCol;
|
|
m_nCurrentCol = m_pSelection->GetEnd_str().nCol + 1;
|
|
|
|
SetCurCaretPos(m_pSelection->GetEnd_disp().nLine, m_nDispCol, TRUE, FALSE);
|
|
|
|
if (m_pSelection->bSelectingRunning)
|
|
SetTimer(TIMER_SELECTION_ID, TIMER_SELECTION_TIME, NULL);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDOWN, nFlags, point);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
if (IsViewOnly())
|
|
return;
|
|
|
|
KillTimer(TIMER_SELECTION_ID);
|
|
|
|
int nRow = ProcessCollapsedBlockDblClick(point);
|
|
if (nRow > 0)
|
|
{
|
|
// close tooltip.
|
|
ShowCollapsedToolTip(CPoint(0, 0));
|
|
}
|
|
else
|
|
{
|
|
// Select the word
|
|
SelectWord(point);
|
|
}
|
|
|
|
CWnd::OnLButtonDblClk(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONDBLCLICK, nFlags, point);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
if (IsViewOnly())
|
|
return;
|
|
|
|
if (!GetCapture() || GetCapture() != this || GetFocus() != this)
|
|
return;
|
|
|
|
if (GetCapture() == this)
|
|
ReleaseCapture();
|
|
|
|
int nNewRow = 0, nNewCol = 0, nNewDispRow = 0, nNewDispCol = 0;
|
|
BOOL bRowCol = RowColFromPoint(point, &nNewRow, &nNewCol, &nNewDispRow, &nNewDispCol);
|
|
|
|
if (bRowCol && m_pSelection->IsInSel_disp(nNewRow, nNewDispCol) &&
|
|
!m_pSelection->bSelectingRunning && !m_bDragging) // dragging
|
|
{
|
|
m_pSelection->Reset_disp(m_pSelection->GetStart_disp().nLine, m_pSelection->GetStart_disp().nCol);
|
|
}
|
|
else
|
|
{
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
m_pSelection->bSelectingRunning = FALSE;
|
|
KillTimer(TIMER_SELECTION_ID);
|
|
|
|
m_dwAutoScrollDirection = 0;
|
|
KillTimer(TIMER_AUTOSCROLL_ID);
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
if (m_bDragging)
|
|
{
|
|
if (m_bDroppable)
|
|
{
|
|
BOOL bCtrlKey = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
|
|
CopyOrMoveText(bCtrlKey);
|
|
}
|
|
else
|
|
{
|
|
m_pSelection->Reset_disp(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
}
|
|
|
|
m_bDragging = FALSE;
|
|
m_bDroppable = FALSE;
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
CWnd::OnLButtonUp(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_LBUTTONUP, nFlags, point);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (IsViewOnly())
|
|
return;
|
|
|
|
if (m_bDragging || m_bRightButtonDrag)
|
|
{
|
|
m_bDragging = TRUE;
|
|
|
|
CXTPClientRect rcWnd(this);
|
|
|
|
if (rcWnd.PtInRect(point))
|
|
{
|
|
int nNewRow = 0, nNewCol = 0, nNewDispCol = 0;
|
|
RowColFromPoint(point, &nNewRow, &nNewCol, NULL, &nNewDispCol);
|
|
//TRACE(_T("DropPOS: nNewRow=%d, nNewCol=%d, nNewDispCol=%d \n"), nNewRow, nNewCol, nNewDispCol);
|
|
|
|
if (nNewRow != m_ptDropPos.y || nNewDispCol != m_ptDropPos.x)
|
|
{
|
|
m_nDispCol = nNewDispCol;
|
|
m_ptDropPos.x = m_nDispCol;
|
|
m_ptDropPos.y = nNewRow;
|
|
|
|
//SetCurrentDocumentRow(nNewRow);
|
|
SetCurCaretPos(m_ptDropPos.y, m_ptDropPos.x, FALSE, FALSE);
|
|
}
|
|
|
|
m_bDroppable = !m_pSelection->IsInSel_disp(m_ptDropPos.y, m_ptDropPos.x);
|
|
|
|
OnSetCursor(0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
m_bDroppable = FALSE;
|
|
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO));
|
|
}
|
|
}
|
|
// else if (m_pSelection->bSelectingRunning)
|
|
// {
|
|
// OnTimer(TIMER_SELECTION_ID);
|
|
// }
|
|
|
|
ShowCollapsedToolTip(point);
|
|
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_MOUSEMOVE, nFlags, point);
|
|
}
|
|
|
|
XTP_EDIT_COLLAPSEDBLOCK* CXTPSyntaxEditCtrl::GetBlockFromPt(const CPoint& ptMouse) const
|
|
{
|
|
// enumerate all collapsed blocks coordinates
|
|
// to find the one where mouse into
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = NULL;
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
int nActualRow = 0;
|
|
|
|
for (int i = 0; i < m_nCollapsedTextRowsCount; i++)
|
|
{
|
|
int nRow = m_arCollapsedTextRows[i];
|
|
|
|
if (nRow <= nActualRow)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!HasRowMark(nRow, xtpEditLMT_Collapsed, &LMCoParam))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// get count of collapsed rows under this row
|
|
int nHiddenRows = 0;
|
|
if (!GetCollapsedBlockLen(nRow, nHiddenRows))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
nActualRow = nRow + nHiddenRows;
|
|
|
|
// get collapsed block pointer
|
|
pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
|
|
if (!pCoDrawBlk)
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
|
|
CRect crCollapsed(pCoDrawBlk->rcCollMark);
|
|
|
|
if (crCollapsed.PtInRect(ptMouse))
|
|
{
|
|
return pCoDrawBlk;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::ProcessCollapsedBlockDblClick(const CPoint& ptMouse)
|
|
{
|
|
// Find required collapsed block by coordinates
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = GetBlockFromPt(ptMouse);
|
|
if (pCoDrawBlk)
|
|
{
|
|
int nRow = pCoDrawBlk->collBlock.lcStart.nLine;
|
|
CollapseExpandBlock(nRow);
|
|
return nRow;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
AFX_STATIC CString AFX_CDECL TrimLeftIndent(const CString& csText)
|
|
{
|
|
CString csTrimmedText(csText);
|
|
int nLastLine = csTrimmedText.ReverseFind('\n');
|
|
CString csTrimText(csTrimmedText.Right(csTrimmedText.GetLength() - nLastLine).SpanIncluding(_T("\n \t")));
|
|
csTrimmedText.Replace(csTrimText, _T("\n"));
|
|
return csTrimmedText;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ShowCollapsedToolTip(const CPoint& ptMouse)
|
|
{
|
|
if (ptMouse == m_ptPrevMouse)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Find required collapsed block by coordinates
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = GetBlockFromPt(ptMouse);
|
|
if (pCoDrawBlk)
|
|
{
|
|
m_ptPrevMouse = ptMouse;
|
|
|
|
// set tooltip rect
|
|
CRect rcTip(ptMouse, ptMouse);
|
|
rcTip.right += 200;
|
|
rcTip.bottom += 200;
|
|
rcTip += CSize(18, 18);
|
|
ClientToScreen(&rcTip);
|
|
m_pToolTip->SetHoverRect(rcTip);
|
|
|
|
// set tooltip text
|
|
CString strToolText(GetCollapsedText(pCoDrawBlk));
|
|
m_pToolTip->Activate(TrimLeftIndent(strToolText));
|
|
}
|
|
|
|
// Then Hide Tip if it is displayed for some other block
|
|
if (ptMouse != m_ptPrevMouse)
|
|
{
|
|
m_pToolTip->Hide();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_bDragging = FALSE;
|
|
m_nAutoIndentCol = 0;
|
|
|
|
KillTimer(TIMER_SELECTION_ID);
|
|
|
|
int iRow, iCol;
|
|
RowColFromPoint(point, &iRow, &iCol);
|
|
|
|
// if (!m_pSelection->IsSelExist() || !m_pSelection->IsInSel_str(iRow, iCol))
|
|
if (!m_pSelection->IsSelExist()
|
|
|| !m_pSelection->IsInSel_str(iRow, iCol-1))
|
|
// iCol-1: otherwise selection was cleared with click on the last character
|
|
// but retained when clicking one character in front of the selection!
|
|
{
|
|
LPCTSTR szLineText = GetLineText(iRow);
|
|
|
|
//SetCurrentDocumentRow(iRow);
|
|
|
|
m_nDispCol = CalcDispCol(szLineText, iCol);
|
|
m_nCurrentCol = CalcAbsCol(szLineText, iCol);
|
|
|
|
SetCurCaretPos(iRow, m_nDispCol);
|
|
//Unselect();
|
|
m_pSelection->Reset_disp(iRow, m_nDispCol);
|
|
|
|
NotifySelInit();
|
|
}
|
|
|
|
|
|
SetCapture();
|
|
|
|
if (m_pSelection->IsSelExist() && m_pSelection->IsInSel_str(iRow, iCol))
|
|
{
|
|
m_bRightButtonDrag = TRUE;
|
|
|
|
if (m_bEnableOleDrag)
|
|
{
|
|
NotifyParent(XTP_EDIT_NM_STARTOLEDRAG);
|
|
}
|
|
}
|
|
|
|
// if (!m_pSelection->IsSelExist() && !m_bEnableOleDrag)
|
|
// {
|
|
// RowColFromPoint(point, &iRow, &iCol);
|
|
|
|
// // SetCurPos will determine valid column
|
|
// SetCurPos(iRow, iCol);
|
|
// }
|
|
|
|
CWnd::OnRButtonDown(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_RBUTTONDOWN, nFlags, point);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnRButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
CWnd::OnRButtonUp(nFlags, point);
|
|
NotifyMouseEvent(XTP_EDIT_NM_RBUTTONUP, nFlags, point);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Scroll(int x, int y)
|
|
{
|
|
m_bScrolling = TRUE;
|
|
|
|
if (y > 0)
|
|
ShiftCurrentVisibleRowDown(y);
|
|
else if (y < 0)
|
|
ShiftCurrentVisibleRowUp(-y);
|
|
|
|
if (x)
|
|
{
|
|
SCROLLINFO info;
|
|
ZeroMemory(&info, sizeof(SCROLLINFO));
|
|
info.cbSize = sizeof(SCROLLINFO);
|
|
info.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_HORZ, &info);
|
|
|
|
int nStep = m_pDrawTextProcessor->GetTextMetrics().tmAveCharWidth;
|
|
|
|
int nCurrPos = m_pDrawTextProcessor->GetScrollXOffset();
|
|
nCurrPos += x * nStep;
|
|
nCurrPos = max(0, nCurrPos);
|
|
|
|
// TRACE(_T("SCROLL.X. from %d -> %d \n"), (int)m_pDrawTextProcessor->GetScrollXOffset(), nCurrPos);
|
|
|
|
SetScrollPos(SB_HORZ, nCurrPos);
|
|
m_pDrawTextProcessor->SetScrollXOffset(nCurrPos);
|
|
}
|
|
|
|
//RecalcVertScrollPos();
|
|
//RecalcHorzScrollPos();
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
RecalcScrollBars();
|
|
|
|
int nTopDocRow = GetDocumentRow(1);
|
|
int nBottomDocRow = GetDocumentRow(GetRowPerPage());
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
|
|
if (nCurDocRow >= nTopDocRow && nCurDocRow <= nBottomDocRow)
|
|
{
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
|
|
DWORD dwUpdate = 0;
|
|
|
|
if (y != 0)
|
|
dwUpdate |= XTP_EDIT_UPDATE_HORZ;
|
|
|
|
if (x != 0)
|
|
dwUpdate |= XTP_EDIT_UPDATE_VERT;
|
|
|
|
|
|
if (dwUpdate != 0)
|
|
UpdateScrollPos(dwUpdate);
|
|
|
|
|
|
m_bScrolling = FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::RowColFromPoint(CPoint pt, int *pRow, int *pCol,
|
|
int *pDispRow, int *pDispCol, BOOL bVirtualSpace)
|
|
{
|
|
if (bVirtualSpace < 0)
|
|
bVirtualSpace = _IsVirtualSpaceActive();
|
|
|
|
int nDispRow0 = 0, nDispCol0 = 0;
|
|
|
|
if (!m_pDrawTextProcessor->HitTestRow(pt.y, nDispRow0))
|
|
{
|
|
nDispRow0 = pt.y < m_pDrawTextProcessor->GetTextRect().top ? 0 : m_pDrawTextProcessor->GetRowsCount(FALSE) - 1;
|
|
}
|
|
|
|
int nRow = GetDocumentRow(nDispRow0 + 1);
|
|
|
|
if (nRow < 1 || nRow > GetRowCount())
|
|
nRow = nRow < 1 ? 1 : GetRowCount();
|
|
|
|
nDispRow0 = GetVisibleRow(nRow) - 1;
|
|
|
|
UpdateRowInfoInternally(nRow); // to ensure than x positions are valid
|
|
|
|
BOOL bRet = m_pDrawTextProcessor->ColFromXPos(nDispRow0, pt.x, nDispCol0, bVirtualSpace);
|
|
if (!bRet)
|
|
{
|
|
if (pt.x < m_pDrawTextProcessor->GetTextRect().left)
|
|
{
|
|
nDispCol0 = 0;
|
|
}
|
|
else if (pt.x > m_pDrawTextProcessor->GetTextRect().right)
|
|
{
|
|
int nX1 = max(0, m_pDrawTextProcessor->GetTextRect().right - 1);
|
|
m_pDrawTextProcessor->ColFromXPos(nDispRow0, nX1, nDispCol0, bVirtualSpace);
|
|
}
|
|
}
|
|
int nCol0 = m_pDrawTextProcessor->DispPosToStrPos(nDispRow0, nDispCol0, bVirtualSpace);
|
|
// to align to TABs positions
|
|
nDispCol0 = m_pDrawTextProcessor->StrPosToDispPos(nDispRow0, nCol0, bVirtualSpace);
|
|
|
|
if (pRow)
|
|
*pRow = nRow;
|
|
|
|
if (pCol)
|
|
*pCol = nCol0 + 1;
|
|
|
|
if (pDispRow)
|
|
*pDispRow = nDispRow0 + 1;
|
|
|
|
if (pDispCol)
|
|
*pDispCol = nDispCol0 + 1;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CWnd::OnSize(nType, cx, cy);
|
|
|
|
if (m_bmpCache.m_hObject)
|
|
m_bmpCache.DeleteObject();
|
|
|
|
if (!GetPaintManager()->GetFont()->GetSafeHandle())
|
|
return;
|
|
|
|
CRect rcText;
|
|
CalcEditRects(NULL, NULL, NULL, &rcText);
|
|
|
|
m_pDrawTextProcessor->SetTextRect(rcText);
|
|
|
|
RecalcVertScrollPos();
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
RecalcHorzScrollPos();
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetScrollPos(int nBar) const
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->GetScrollPos(nBar);
|
|
}
|
|
|
|
return CWnd::GetScrollPos(nBar);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->GetScrollRange(nBar, lpMinPos, lpMaxPos);
|
|
}
|
|
else
|
|
{
|
|
CWnd::GetScrollRange(nBar, lpMinPos, lpMaxPos);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect, LPCRECT lpClipRect)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->ScrollWindow(xAmount, yAmount, lpRect, lpClipRect);
|
|
}
|
|
else
|
|
{
|
|
CWnd::ScrollWindow(xAmount, yAmount, lpRect, lpClipRect);
|
|
}
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, CRgn *prgnUpdate, LPRECT lpRectUpdate, UINT flags)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->ScrollWindowEx(dx, dy, lpRectScroll, lpRectClip, prgnUpdate, lpRectUpdate, flags);
|
|
}
|
|
|
|
return CWnd::ScrollWindowEx(dx, dy, lpRectScroll, lpRectClip, prgnUpdate, lpRectUpdate, flags);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, UINT nMask)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->GetScrollInfo(nBar, lpScrollInfo, nMask);
|
|
}
|
|
|
|
return CWnd::GetScrollInfo(nBar, lpScrollInfo, nMask);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetScrollLimit(int nBar)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->GetScrollLimit(nBar);
|
|
}
|
|
|
|
return CWnd::GetScrollLimit(nBar);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->SetScrollInfo(nBar, lpScrollInfo, bRedraw);
|
|
}
|
|
|
|
return CWnd::SetScrollInfo(nBar, lpScrollInfo, bRedraw);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::SetScrollPos(int nBar, int nPos, BOOL bRedraw)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->SetScrollPos(nBar, nPos, bRedraw);
|
|
}
|
|
|
|
return CWnd::SetScrollPos(nBar, nPos, bRedraw);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->SetScrollRange(nBar, nMinPos, nMaxPos, bRedraw);
|
|
}
|
|
else
|
|
{
|
|
CWnd::SetScrollRange(nBar, nMinPos, nMaxPos, bRedraw);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ShowScrollBar(UINT nBar, BOOL bShow)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->ShowScrollBar(nBar, bShow);
|
|
}
|
|
else
|
|
{
|
|
CWnd::ShowScrollBar(nBar, bShow);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::EnableScrollBarCtrl(int nBar, BOOL bEnable)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->EnableScrollBarCtrl(nBar, bEnable);
|
|
|
|
DWORD dwScrollBar = (nBar == SB_HORZ) ? WS_HSCROLL : 0;
|
|
dwScrollBar |= (nBar == SB_VERT) ? WS_VSCROLL : 0;
|
|
dwScrollBar |= (nBar == SB_BOTH) ? (WS_HSCROLL | WS_VSCROLL) : 0;
|
|
|
|
_EnableScrollBarNotify((DWORD)dwScrollBar, bEnable ? (DWORD)dwScrollBar : 0);
|
|
}
|
|
else
|
|
{
|
|
CWnd::EnableScrollBarCtrl(nBar, bEnable);
|
|
}
|
|
}
|
|
|
|
CScrollBar* CXTPSyntaxEditCtrl::GetScrollBarCtrl(int nBar) const
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
return pParentWnd->GetScrollBarCtrl(nBar);
|
|
}
|
|
|
|
return CWnd::GetScrollBarCtrl(nBar);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RepositionBars(UINT nIDFirst, UINT nIDLast, UINT nIDLeftOver, UINT nFlag, LPRECT lpRectParam, LPCRECT lpRectClient, BOOL bStretch)
|
|
{
|
|
CWnd* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && IsCreateScrollbarOnParent())
|
|
{
|
|
pParentWnd->RepositionBars(nIDFirst, nIDLast, nIDLeftOver, nFlag, lpRectParam, lpRectClient, bStretch);
|
|
}
|
|
else
|
|
{
|
|
CWnd::RepositionBars(nIDFirst, nIDLast, nIDLeftOver, nFlag, lpRectParam, lpRectClient, bStretch);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DeleteSelection()
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
return TRUE;
|
|
|
|
int nFlags = (m_pSelection->bBlockSelectionMode ? xtpEditTextAsBlock : 0) | xtpEditDispCol;
|
|
|
|
if (!DeleteBuffer(m_pSelection->GetNormalStart_disp().nLine, m_pSelection->GetNormalStart_disp().nCol,
|
|
m_pSelection->GetNormalEnd_disp().nLine, m_pSelection->GetNormalEnd_disp().nCol,
|
|
nFlags))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_pSelection->Reset_disp(m_pSelection->GetNormalStart_disp().nLine, m_pSelection->GetNormalStart_disp().nCol);
|
|
|
|
SetCurrentDocumentRow(m_pSelection->GetNormalStart_disp().nLine);
|
|
EnsureVisibleRow(GetCurrentDocumentRow());
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_pSelection->GetStart_disp().nCol);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DeleteBuffer(int iRowFrom, int iColFrom, int iRowTo, int iColTo,
|
|
int nFlags )
|
|
{
|
|
int iTempRow1 = iRowFrom, iTempRow2 = iRowTo;
|
|
int iTempCol1 = iColFrom, iTempCol2 = iColTo;
|
|
|
|
if (iTempRow2 < iTempRow1)
|
|
{
|
|
iRowFrom = iTempRow2;
|
|
iColFrom = iTempCol2;
|
|
iRowTo = iTempRow1;
|
|
iColTo = iTempCol1;
|
|
}
|
|
else if (iTempRow1 == iTempRow2)
|
|
{
|
|
iColFrom = min(iTempCol1, iTempCol2);
|
|
iColTo = max(iTempCol1, iTempCol2);
|
|
}
|
|
|
|
if ((nFlags & xtpEditTextAsBlock) &&
|
|
(iColTo < iColFrom))
|
|
{
|
|
// swap them
|
|
int nTemp = iColTo;
|
|
iColTo = iColFrom;
|
|
iColFrom = nTemp;
|
|
}
|
|
|
|
if (!CanEditDoc())
|
|
{
|
|
return FALSE;
|
|
}
|
|
BOOL bDispCol = (nFlags & xtpEditDispCol) != 0;
|
|
int nColFrom_str = bDispCol ? CalcAbsCol(iRowFrom, iColFrom) : iColFrom;
|
|
int nColTo_str = bDispCol ? CalcAbsCol(iRowTo, iColTo) : iColTo;
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(iRowFrom, nColFrom_str);
|
|
//**----------------------
|
|
|
|
ASSERT((nFlags & xtpEditTextAsBlock) && bDispCol || !(nFlags & xtpEditTextAsBlock));
|
|
|
|
if ((nFlags & xtpEditTextAsBlock) && iRowFrom != iRowTo)
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(TRUE);
|
|
|
|
for (int i = iRowFrom; i <= iRowTo; i++)
|
|
{
|
|
m_pBuffer->DeleteText(i, iColFrom, i, iColTo, TRUE, bDispCol);
|
|
}
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_DELETE_TEXT_BLOCK);
|
|
}
|
|
else
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
m_pBuffer->DeleteText(iRowFrom, iColFrom, iRowTo, iColTo, TRUE, bDispCol);
|
|
}
|
|
|
|
LPCTSTR szLineText = GetLineText(iRowFrom);
|
|
SetCurrentDocumentRow(iRowFrom);
|
|
m_nCurrentCol = nColFrom_str;
|
|
m_nDispCol = CalcDispCol(szLineText, m_nCurrentCol);
|
|
|
|
//**----------------------
|
|
OnEditChanged(iRowFrom, nColFrom_str, iRowTo, nColTo_str, xtpEditActDelete);
|
|
//**----------------------
|
|
|
|
UINT uFlags = XTP_EDIT_EDITACTION_DELETEROW | XTP_EDIT_EDITACTION_MODIFYROW;
|
|
|
|
NotifyEditChanged(iRowFrom, iRowTo, uFlags);
|
|
|
|
SetDocModified();
|
|
|
|
RecalcScrollBars();
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (nFlags & xtpEditRedraw)
|
|
{
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DeleteChar(int iRow, int iCol, XTPSyntaxEditDeletePos pos)
|
|
{
|
|
CString strText;
|
|
|
|
int iRowTo = iRow, iColTo = iCol;
|
|
|
|
if (pos == xtpEditDelPosAfter) // If deleting using DEL key
|
|
{
|
|
GetLineText(iRow, strText);
|
|
|
|
int nLineLen = (int)_tcsclen(strText);
|
|
|
|
if (iCol > nLineLen)
|
|
{
|
|
iRowTo = iRow + 1;
|
|
iColTo = 1;
|
|
|
|
if (iRowTo > GetRowCount())
|
|
return FALSE;
|
|
|
|
int nColFrom = nLineLen + 1;
|
|
int nAdditionalTabs = 0;
|
|
int nDispCol2 = CalcDispCol(strText, iCol);
|
|
int nDispCol0 = CalcDispCol(strText, nColFrom);
|
|
|
|
int nDC = nDispCol0 + GetTabSize() - (nDispCol0 -1) % GetTabSize();
|
|
if (nDC <= nDispCol2)
|
|
nAdditionalTabs++;
|
|
else
|
|
nDC = nDispCol0;
|
|
|
|
for (; nDC + GetTabSize() <= nDispCol2; nDC += GetTabSize())
|
|
nAdditionalTabs++;
|
|
|
|
int nAdditionalSpaces = max(0, nDispCol2 - nDC);
|
|
|
|
CString strTabs = CString(_T('\t'), nAdditionalTabs) + CString(_T(' '), nAdditionalSpaces);
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(iRow, nColFrom);
|
|
|
|
XTP_EDIT_LINECOL lcFinal;
|
|
m_pBuffer->InsertText(strTabs, iRow, nColFrom, TRUE, &lcFinal);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_FORMAT);
|
|
|
|
OnEditChanged(iRow, nColFrom, iRow, lcFinal.nCol, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
iCol = lcFinal.nCol;
|
|
}
|
|
else
|
|
iColTo++;
|
|
}
|
|
else // If deleting using back space
|
|
{
|
|
if (iCol == 1)
|
|
{
|
|
if (iRow > 1)
|
|
{
|
|
iRow--;
|
|
// if we are in the end of collapsed block, expand it...
|
|
CXTPSyntaxEditRowsBlockArray arCoBlocks;
|
|
GetCollapsableBlocksInfo(iRow, arCoBlocks);
|
|
int nCount = (int)arCoBlocks.GetSize();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
|
|
if (coBlk.lcEnd.nLine == iRow) // Expand!
|
|
{
|
|
if (HasRowMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed))
|
|
GetLineMarksManager()->DeleteLineMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed);
|
|
}
|
|
}
|
|
|
|
//GetLineText(iRow, strText);
|
|
//iCol = (int)_tcsclen(strText) + 1;
|
|
iCol = m_pBuffer->GetLineTextLengthC(iRow) + 1;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
iCol--;
|
|
}
|
|
|
|
if (!DeleteBuffer(iRow, iCol, iRowTo, iColTo))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DoUndoRedo(int nActionsCount, BOOL bUndoRedo)
|
|
{
|
|
CWaitCursor wait;
|
|
|
|
if (!CanEditDoc())
|
|
return FALSE;
|
|
|
|
CXTPSyntaxEditUndoRedoManager* pUndoMgr = m_pBuffer->GetUndoRedoManager();
|
|
if (!pUndoMgr)
|
|
return FALSE;
|
|
|
|
m_pSelection->Reset_disp(m_pSelection->GetEnd_disp().nLine, m_pSelection->GetEnd_disp().nCol);
|
|
|
|
m_nAutoIndentCol = 0;
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
XTP_EDIT_LINECOL lcTotalFrom = XTP_EDIT_LINECOL::MAXPOS;
|
|
XTP_EDIT_LINECOL lcTotalTo = XTP_EDIT_LINECOL::MINPOS;
|
|
|
|
for (int nAction = 0; nAction < nActionsCount; nAction++)
|
|
{
|
|
XTP_EDIT_LINECOL lcFrom, lcTo;
|
|
|
|
// perform undo
|
|
int nEditAction = bUndoRedo ?
|
|
pUndoMgr->DoUndo(lcFrom, lcTo, this) :
|
|
pUndoMgr->DoRedo(lcFrom, lcTo, this);
|
|
|
|
// perform some total calculations
|
|
lcTotalFrom = min(lcTotalFrom, lcFrom);
|
|
lcTotalTo = max(lcTotalTo, lcTo);
|
|
|
|
// TODO: ???????????????????????????????????
|
|
// send update notifications
|
|
|
|
// Commented out to eliminate double call of OnEditChanged that
|
|
// leads to improper calculation of collapsible blocks borders
|
|
// if (nEditAction & XTP_EDIT_EDITACTION_INSERTTEXT)
|
|
// {
|
|
// OnEditChanged(lcFrom, lcTo, xtpEditActInsert);
|
|
// }
|
|
// else if (nEditAction & XTP_EDIT_EDITACTION_DELETETEXT)
|
|
// {
|
|
// OnEditChanged(lcFrom, lcTo, xtpEditActDelete);
|
|
// }
|
|
|
|
NotifyEditChanged(lcFrom.nLine, lcTo.nLine, nEditAction);
|
|
}
|
|
|
|
int nRowsAffected = lcTotalTo.nLine - lcTotalFrom.nLine;
|
|
|
|
m_nDispCol = CalcDispCol(GetCurrentDocumentRow(), m_nCurrentCol);
|
|
|
|
RecalcScrollBars();
|
|
|
|
if (GetCurrentDocumentRow() > GetRowCount())
|
|
{
|
|
SetCurrentDocumentRow(GetRowCount());
|
|
m_nCurrentCol = m_nDispCol = 1;
|
|
}
|
|
|
|
nCurDocRow = GetCurrentDocumentRow();
|
|
|
|
if (nActionsCount > 1)
|
|
{
|
|
ValidateCol(nCurDocRow, m_nDispCol, m_nCurrentCol);
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
nCurDocRow = GetCurrentDocumentRow();
|
|
if ((nCurDocRow > 0 && m_nCurrentCol > 0) ||
|
|
!(nRowsAffected == 0 && nActionsCount == 1))
|
|
{
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol);
|
|
}
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
|
|
UpdateScrollPos();
|
|
|
|
SetDocModified(m_pBuffer->IsModified());
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::Undo(int nActionsCount)
|
|
{
|
|
if (CanUndo())
|
|
{
|
|
return DoUndoRedo(nActionsCount, TRUE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::Redo(int nActionsCount)
|
|
{
|
|
if (CanRedo())
|
|
{
|
|
return DoUndoRedo(nActionsCount, FALSE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CanUndo() const
|
|
{
|
|
if (m_pBuffer && m_pBuffer->GetUndoRedoManager())
|
|
return CanEditDoc() && m_pBuffer->GetUndoRedoManager()->CanUndo();
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CanRedo() const
|
|
{
|
|
if (m_pBuffer && m_pBuffer->GetUndoRedoManager())
|
|
return CanEditDoc() && m_pBuffer->GetUndoRedoManager()->CanRedo();
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Cut()
|
|
{
|
|
if (IsViewOnly())
|
|
return;
|
|
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
Copy();
|
|
|
|
DeleteSelection();
|
|
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Copy()
|
|
{
|
|
if (IsViewOnly())
|
|
return;
|
|
|
|
if (!m_pSelection->IsSelExist())
|
|
return;
|
|
|
|
CWaitCursor wait;
|
|
|
|
if (!OpenClipboard())
|
|
{
|
|
#ifdef _DEBUG
|
|
LPVOID lpMsgBuf;
|
|
::FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
::GetLastError(),
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
// Process any inserts in lpMsgBuf.
|
|
// ...
|
|
// Display the string.
|
|
AfxMessageBox((LPCTSTR)lpMsgBuf, MB_OK | MB_ICONINFORMATION );
|
|
|
|
// Free the buffer.
|
|
::LocalFree( lpMsgBuf );
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
// prepare clipboard
|
|
::EmptyClipboard();
|
|
|
|
// retrieve the text string from buffer
|
|
CMemFile file(CalcAveDataSize(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_str().nLine));
|
|
|
|
BOOL bRes = m_pBuffer->GetBuffer(m_pSelection->GetNormalStart_disp(),
|
|
m_pSelection->GetNormalEnd_disp(), file,
|
|
m_pSelection->bBlockSelectionMode, TRUE);
|
|
if (!bRes)
|
|
return;
|
|
|
|
// Copy the buffer to clipboard
|
|
DWORD dwBytes = (DWORD)file.GetLength();
|
|
BYTE *pBytes = file.Detach();
|
|
|
|
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwBytes + sizeof(TCHAR));
|
|
if (!hMem)
|
|
return;
|
|
LPVOID lpSource = (LPVOID)::GlobalLock(hMem);
|
|
if (!lpSource)
|
|
return;
|
|
|
|
MEMCPY_S(lpSource, pBytes, dwBytes);
|
|
::ZeroMemory(((BYTE *)lpSource + dwBytes), sizeof(TCHAR));
|
|
free(pBytes);
|
|
|
|
UINT uCodePage = m_pBuffer->GetCodePage();
|
|
|
|
#ifdef _UNICODE
|
|
// Determine the byte requirement
|
|
int nLen = ::WideCharToMultiByte(uCodePage, 0, (LPWSTR)lpSource, -1, NULL, 0, NULL, NULL);
|
|
|
|
HGLOBAL hMBCSMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (nLen + 2)); // Maximum number of bytes is dwBytes
|
|
if (!hMBCSMem)
|
|
{
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
LPSTR lpMBCSSource = (LPSTR)::GlobalLock(hMBCSMem);
|
|
if (!lpMBCSSource)
|
|
return;
|
|
|
|
int nBytes = ::WideCharToMultiByte(uCodePage, 0, (LPWSTR)lpSource, -1, lpMBCSSource, nLen, NULL, NULL);
|
|
|
|
ASSERT(nBytes <= (int)dwBytes);
|
|
|
|
lpMBCSSource[nBytes] = _T('\0');
|
|
|
|
::GlobalUnlock(hMem);
|
|
::GlobalUnlock(hMBCSMem);
|
|
|
|
// lpSource is Unicode text
|
|
::SetClipboardData(CF_UNICODETEXT, hMem);
|
|
::SetClipboardData(CF_TEXT, hMBCSMem);
|
|
::SetClipboardData(CF_OEMTEXT, hMBCSMem);
|
|
#else
|
|
int nUBytes = (dwBytes + 2) * sizeof(WCHAR);
|
|
HGLOBAL hUnicodeMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, nUBytes);
|
|
if (!hUnicodeMem)
|
|
{
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
LPWSTR lpWSource = (LPWSTR)::GlobalLock(hUnicodeMem);
|
|
if (!lpWSource)
|
|
{
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
|
|
int nLen = ::MultiByteToWideChar(uCodePage, 0, (LPCSTR)lpSource, -1, lpWSource, nUBytes);
|
|
|
|
ASSERT(nLen <= (int)(nUBytes / sizeof(WCHAR)));
|
|
|
|
lpWSource[nLen] = _T('\0');
|
|
|
|
::GlobalUnlock(hMem);
|
|
::GlobalUnlock(hUnicodeMem);
|
|
|
|
// lpSource is MBCS text
|
|
::SetClipboardData(CF_TEXT, hMem);
|
|
::SetClipboardData(CF_OEMTEXT, hMem);
|
|
::SetClipboardData(CF_UNICODETEXT, hUnicodeMem);
|
|
#endif
|
|
|
|
if (m_pSelection->bBlockSelectionMode)
|
|
{
|
|
HGLOBAL hMem_BLK = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
|
|
if (!hMem_BLK)
|
|
{
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
BYTE* pMem_BLK = (BYTE*)::GlobalLock(hMem_BLK);
|
|
if (pMem_BLK)
|
|
{
|
|
*pMem_BLK = 1;
|
|
}
|
|
::GlobalUnlock(hMem_BLK);
|
|
|
|
CLIPFORMAT uCF_MSDEVColumnSelect = (CLIPFORMAT)::RegisterClipboardFormat(XTP_EDIT_CFMSDEVCOLSEL);
|
|
::SetClipboardData(uCF_MSDEVColumnSelect, hMem_BLK);
|
|
}
|
|
|
|
CloseClipboard();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Paste()
|
|
{
|
|
CWaitCursor wait;
|
|
|
|
if (!OpenClipboard())
|
|
return;
|
|
|
|
BOOL bCBTextIsBlock = FALSE;
|
|
CLIPFORMAT uCF_MSDEVColumnSelect = (CLIPFORMAT)::RegisterClipboardFormat(XTP_EDIT_CFMSDEVCOLSEL);
|
|
HANDLE hMem_TextBlok = ::GetClipboardData(uCF_MSDEVColumnSelect);
|
|
if (hMem_TextBlok)
|
|
{
|
|
int nSize = (int)::GlobalSize(hMem_TextBlok);
|
|
BYTE* arColBlk = (BYTE*)::GlobalLock(hMem_TextBlok);
|
|
if (arColBlk && nSize)
|
|
{
|
|
bCBTextIsBlock = TRUE;
|
|
//TRACE(_T("MSDEVColumnSelect data [size=%d] = %d \n"), nSize, (int)arColBlk[0]);
|
|
}
|
|
}
|
|
|
|
#ifdef _UNICODE
|
|
HANDLE hMem = ::GetClipboardData(CF_UNICODETEXT);
|
|
#else
|
|
HANDLE hMem = ::GetClipboardData(CF_TEXT);
|
|
#endif
|
|
|
|
if (!hMem)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LPTSTR szData = (LPTSTR)::GlobalLock(hMem);
|
|
BOOL bReplace = GetTabWithSpace();
|
|
BOOL bOverwrite = m_pBuffer->GetOverwriteFlag();
|
|
|
|
SetTabWithSpace(FALSE);
|
|
m_pBuffer->SetOverwriteFlag(FALSE);
|
|
|
|
if (bCBTextIsBlock)
|
|
{
|
|
InsertTextBlock(szData, GetCurrentDocumentRow(), m_nCurrentCol, m_pSelection->IsSelExist());
|
|
}
|
|
else
|
|
{
|
|
InsertString(szData, GetCurrentDocumentRow(), m_nCurrentCol, m_pSelection->IsSelExist());
|
|
}
|
|
|
|
SetTabWithSpace(bReplace);
|
|
m_pBuffer->SetOverwriteFlag(bOverwrite);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_PASTE);
|
|
|
|
::GlobalUnlock(hMem);
|
|
|
|
CloseClipboard();
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
SetDocModified();
|
|
|
|
UpdateScrollPos(XTP_EDIT_UPDATE_HORZ|XTP_EDIT_UPDATE_VERT);
|
|
|
|
UpdateWindow();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetRowText(int nRow, LPCTSTR pcszText, BOOL bCanUndo)
|
|
{
|
|
if (!m_pBuffer)
|
|
return;
|
|
|
|
int nRowLen = m_pBuffer->GetLineTextLengthC(nRow, FALSE);
|
|
if (nRowLen)
|
|
{
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRow, 1);
|
|
//**----------------------
|
|
|
|
if (bCanUndo)
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
m_pBuffer->DeleteText(nRow, 1, nRow, nRowLen + 1, bCanUndo, FALSE);
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActDelete);
|
|
//**----------------------
|
|
}
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRow, 1);
|
|
//**----------------------
|
|
|
|
if (bCanUndo)
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
//XTP_EDIT_LINECOL finalLC;
|
|
m_pBuffer->InsertText(pcszText, nRow, 1, bCanUndo);//finalLC);
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_MODIFYROW);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::InsertRow(int nRow, LPCTSTR pcszText, BOOL bCanUndo)
|
|
{
|
|
if (!m_pBuffer)
|
|
return;
|
|
|
|
CString strLine = pcszText;
|
|
strLine += m_pBuffer->GetCurCRLF();
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRow, 1);
|
|
//**----------------------
|
|
|
|
if (bCanUndo)
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
//XTP_EDIT_LINECOL finalLC;
|
|
m_pBuffer->InsertText(pcszText, nRow, 1, bCanUndo);//finalLC);
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_INSERTROW);
|
|
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RemoveRow(int nRow, BOOL bCanUndo)
|
|
{
|
|
if (!m_pBuffer)
|
|
return;
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRow, 1);
|
|
//**----------------------
|
|
|
|
if (bCanUndo)
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
m_pBuffer->RemoveLine(nRow, bCanUndo);
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRow, 1, nRow + 1, 1, xtpEditActDelete);
|
|
//**----------------------
|
|
|
|
NotifyEditChanged(nRow, nRow, XTP_EDIT_EDITACTION_DELETEROW);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnSetFocus(CWnd* pOldWnd)
|
|
{
|
|
CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
|
|
|
|
// TRACE (_T("CXTPSyntaxEditCtrl::OnSetFocus. this=%x, pOldWnd=%x \n"), this, pOldWnd);
|
|
|
|
::DestroyCaret();
|
|
|
|
m_bFocused = TRUE;
|
|
|
|
Invalidate(FALSE);
|
|
|
|
RestoreCursor();
|
|
NotifyCurRowCol(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (m_bActivateOnFocus)
|
|
SetActive(TRUE);
|
|
|
|
UpdateWindow();
|
|
|
|
CWnd::OnSetFocus(pOldWnd);
|
|
|
|
#ifdef XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS
|
|
XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS(this, this, TRUE)
|
|
#endif
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
CXTPSmartPtrInternalT<CCmdTarget> ptrThisLock(this, TRUE);
|
|
|
|
CWnd::OnKillFocus(pNewWnd);
|
|
|
|
::DestroyCaret();
|
|
|
|
m_pAutoComplete->Hide();
|
|
m_bFocused = FALSE;
|
|
|
|
if (m_bActivateOnFocus)
|
|
SetActive(FALSE);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
#ifdef XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS
|
|
XTP_SYNTAXEDIT_SITENOTIFY_ONFOCUS(this, this, FALSE)
|
|
#endif
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::OnNcActivate(BOOL bActive)
|
|
{
|
|
return CWnd::OnNcActivate(bActive);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
|
|
{
|
|
// SetFocus();
|
|
|
|
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::IsSelectionExist() const
|
|
{
|
|
return m_pSelection->IsSelExist();
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::SelectAll()
|
|
{
|
|
int nLastRow = GetRowCount();
|
|
LPCTSTR szLineText = GetLineText(nLastRow);
|
|
const int nEndCol = (int)_tcsclen(szLineText) + 1;
|
|
|
|
SetCurrentDocumentRow(nLastRow);
|
|
m_nCurrentCol = nEndCol;
|
|
m_nDispCol = CalcDispCol(szLineText, m_nCurrentCol);
|
|
|
|
m_pSelection->Reset_disp(1, 1);
|
|
m_pSelection->SetEnd_disp(nLastRow, m_nDispCol);
|
|
|
|
m_nAutoIndentCol = 0;
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetFontIndirect(LPLOGFONT pLogfont, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
GetPaintManager()->CreateFontIndirect(pLogfont, bUpdateReg);
|
|
|
|
CWindowDC dc(NULL);
|
|
CXTPFontDC fontDC(&dc, GetPaintManager()->GetFont());
|
|
|
|
m_pDrawTextProcessor->RecalcRowHeight(&dc, GetPaintManager()->GetFont());
|
|
|
|
if (m_hWnd && ::IsWindow(m_hWnd))
|
|
{
|
|
//m_pToolTip->SetFont(GetPaintManager()->GetFontToolTip());
|
|
|
|
CalculateEditbarLength();
|
|
|
|
Invalidate(FALSE);
|
|
|
|
_UpdateIMEStatus();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::_UpdateIMEStatus()
|
|
{
|
|
m_bIMEsupported = m_pImmWrapper->ImmIsIME();
|
|
|
|
if (!m_bIMEsupported || !m_hWnd || !::IsWindow(m_hWnd))
|
|
return;
|
|
|
|
// IME Support
|
|
|
|
XTP_HIMC hIMC = m_pImmWrapper->ImmGetContext(m_hWnd);
|
|
if (hIMC)
|
|
{
|
|
LOGFONT lfFont;
|
|
::ZeroMemory(&lfFont, sizeof(lfFont));
|
|
|
|
BOOL bFont = GetPaintManager()->GetFont()->GetLogFont(&lfFont);
|
|
ASSERT(bFont);
|
|
if (bFont)
|
|
{
|
|
VERIFY(m_pImmWrapper->ImmSetCompositionFont(hIMC, &lfFont));
|
|
}
|
|
|
|
VERIFY(m_pImmWrapper->ImmReleaseContext(m_hWnd, hIMC));
|
|
}
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnGetFont(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
return (LRESULT)GetPaintManager()->GetFont()->GetSafeHandle();
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnSetFont(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HFONT hFont = (HFONT)wParam;
|
|
|
|
LOGFONT lfFont;
|
|
LOGFONT *pLF = NULL; // set the default font if hFont == NULL
|
|
|
|
if (hFont)
|
|
{
|
|
::ZeroMemory(&lfFont, sizeof(LOGFONT));
|
|
|
|
if (!::GetObject(hFont, sizeof(LOGFONT), &lfFont))
|
|
{
|
|
ASSERT(FALSE);
|
|
return 0;
|
|
}
|
|
|
|
pLF = &lfFont;
|
|
}
|
|
|
|
SetFontIndirect(pLF, FALSE);
|
|
|
|
if (LOWORD(lParam))
|
|
UpdateWindow();
|
|
|
|
//Default();
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::OnInputLanguage(WPARAM, LPARAM)
|
|
{
|
|
_UpdateIMEStatus();
|
|
|
|
if (m_bIMEsupported)
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
|
|
Default();
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetDocModified(BOOL bModified)
|
|
{
|
|
XTP_EDIT_NMHDR_DOCMODIFIED dm;
|
|
|
|
// NMHDR codes
|
|
dm.nmhdr.code = XTP_EDIT_NM_SETDOCMODIFIED;
|
|
dm.nmhdr.hwndFrom = m_hWnd;
|
|
dm.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// modified flag
|
|
dm.bModified = bModified;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)dm.nmhdr.idFrom, (LPARAM)&dm);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::InsertString(LPCTSTR szText, int iRow, int iCol, BOOL bDeleteSelection)
|
|
{
|
|
if (!CanEditDoc())
|
|
return;
|
|
|
|
int nPrevRow = GetCurrentDocumentRow();
|
|
|
|
if (nPrevRow != iRow)
|
|
SetCurrentDocumentRow(iRow);
|
|
m_nCurrentCol = iCol;
|
|
|
|
if (bDeleteSelection)
|
|
DeleteSelection();
|
|
|
|
// At first determine what type of CRLF it has
|
|
const int nTextLen = (int)_tcsclen(szText);
|
|
|
|
if (nTextLen == 0)
|
|
return;
|
|
|
|
int nRowFrom = GetCurrentDocumentRow();
|
|
int nColFrom = m_nCurrentCol;
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRowFrom, nColFrom);
|
|
//**----------------------
|
|
|
|
if (GetAutoIndent() && m_nAutoIndentCol > 0)
|
|
{
|
|
CString strInsertText(
|
|
CString(_T('\t'), m_nInsertTabCount) +
|
|
CString(_T(' '), m_nInsertSpaceCount));
|
|
|
|
m_pBuffer->InsertText(strInsertText, GetCurrentDocumentRow(), m_nCurrentCol);
|
|
|
|
m_nCurrentCol = m_nInsertTabCount + m_nInsertSpaceCount + 1;
|
|
|
|
m_nAutoIndentCol = 0;
|
|
}
|
|
|
|
|
|
XTP_EDIT_LINECOL finalLC;
|
|
BOOL bInsRes = m_pBuffer->InsertText(szText, GetCurrentDocumentRow(),
|
|
m_nCurrentCol, TRUE, &finalLC);
|
|
|
|
if (bDeleteSelection)
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
|
|
if (bInsRes)
|
|
{
|
|
SetCurrentDocumentRow(finalLC.nLine);
|
|
m_nCurrentCol = finalLC.nCol;
|
|
|
|
m_nDispCol = CalcDispCol(GetLineText(finalLC.nLine), m_nCurrentCol);
|
|
}
|
|
|
|
RecalcScrollBars();
|
|
|
|
UINT nAction = XTP_EDIT_EDITACTION_MODIFYROW;
|
|
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
if (nCurDocRow > nPrevRow)
|
|
nAction |= XTP_EDIT_EDITACTION_INSERTROW;
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRowFrom, nColFrom, nCurDocRow, m_nCurrentCol, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
NotifyEditChanged(nPrevRow, nCurDocRow, nAction);
|
|
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::InsertTextBlock(LPCTSTR szText, int iRow, int iCol, BOOL bDeleteSelection)
|
|
{
|
|
if (!CanEditDoc())
|
|
return;
|
|
|
|
int nPrevRow = GetCurrentDocumentRow();
|
|
|
|
if (nPrevRow != iRow)
|
|
{
|
|
SetCurrentDocumentRow(iRow);
|
|
}
|
|
m_nCurrentCol = iCol;
|
|
|
|
if (bDeleteSelection)
|
|
{
|
|
DeleteSelection();
|
|
}
|
|
|
|
// At first determine what type of CRLF it has
|
|
const int nTextLen = (int)_tcsclen(szText);
|
|
|
|
if (nTextLen == 0)
|
|
return;
|
|
|
|
int nRowFrom = GetCurrentDocumentRow();
|
|
int nColFrom = m_nCurrentCol;
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nRowFrom, nColFrom);
|
|
//**----------------------
|
|
|
|
XTP_EDIT_LINECOL finalLC;
|
|
BOOL bInsRes = m_pBuffer->InsertTextBlock(szText, GetCurrentDocumentRow(),
|
|
iCol, TRUE, &finalLC);
|
|
UNREFERENCED_PARAMETER(bInsRes);
|
|
|
|
if (bDeleteSelection)
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
|
|
RecalcScrollBars();
|
|
|
|
UINT nAction = XTP_EDIT_EDITACTION_MODIFYROW;
|
|
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
if (nCurDocRow > nPrevRow)
|
|
nAction |= XTP_EDIT_EDITACTION_INSERTROW;
|
|
|
|
//**----------------------
|
|
OnEditChanged(nRowFrom, nColFrom, nCurDocRow, m_nCurrentCol, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
NotifyEditChanged(nPrevRow, nCurDocRow, nAction);
|
|
|
|
SetCurCaretPos(nCurDocRow, m_nDispCol, FALSE/*, FALSE*/);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::UpdateScrollPos(DWORD dwUpdate/* = XTP_EDIT_UPDATE_ALL*/)
|
|
{
|
|
if (!::IsWindow(m_hWnd))
|
|
return;
|
|
|
|
XTP_EDIT_NMHDR_SETSCROLLPOS ssp;
|
|
|
|
// NMHDR codes
|
|
ssp.nmhdr.code = XTP_EDIT_NM_UPDATESCROLLPOS;
|
|
ssp.nmhdr.hwndFrom = m_hWnd;
|
|
ssp.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// Update flag
|
|
ssp.dwUpdate = dwUpdate;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)ssp.nmhdr.idFrom, (LPARAM)&ssp);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::_EnableScrollBarNotify(DWORD dwScrollBar, DWORD dwState)
|
|
{
|
|
ASSERT(dwScrollBar != 0 && (dwScrollBar & (WS_VSCROLL|WS_HSCROLL)) != 0);
|
|
|
|
XTP_EDIT_NMHDR_ENABLESCROLLBAR nmEScroll;
|
|
|
|
// NMHDR codes
|
|
nmEScroll.nmhdr.code = XTP_EDIT_NM_ENABLESCROLLBAR;
|
|
nmEScroll.nmhdr.hwndFrom = m_hWnd;
|
|
nmEScroll.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// Update flag
|
|
nmEScroll.dwScrollBar = dwScrollBar;
|
|
nmEScroll.dwState = dwState;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)nmEScroll.nmhdr.idFrom, (LPARAM)&nmEScroll);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetOverwriteMode(BOOL bOverwriteMode)
|
|
{
|
|
if (bOverwriteMode != m_pBuffer->GetOverwriteFlag() )
|
|
{
|
|
m_pBuffer->SetOverwriteFlag(bOverwriteMode);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE/*, FALSE*/);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
UNREFERENCED_PARAMETER(pDC);
|
|
return TRUE;
|
|
}
|
|
|
|
XTP_EDIT_LINECOL CXTPSyntaxEditCtrl::_SubtractSelSizeFromPos(XTP_EDIT_LINECOL lcDispPos)
|
|
{
|
|
XTP_EDIT_LINECOL lcStart = m_pSelection->GetNormalStart_disp();
|
|
XTP_EDIT_LINECOL lcEnd = m_pSelection->GetNormalEnd_disp();
|
|
|
|
if (lcDispPos <= lcStart)
|
|
return lcDispPos;
|
|
|
|
if (lcDispPos < lcEnd && !m_pSelection->bBlockSelectionMode)
|
|
{
|
|
ASSERT(FALSE);
|
|
lcDispPos = lcEnd;
|
|
}
|
|
|
|
if (m_pSelection->bBlockSelectionMode)
|
|
{
|
|
if (lcDispPos.nLine >= lcStart.nLine && lcDispPos.nLine <= lcEnd.nLine)
|
|
{
|
|
if (lcDispPos.nCol >= lcEnd.nCol)
|
|
lcDispPos.nCol -= lcEnd.nCol - lcStart.nCol;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lcEnd.nLine != lcStart.nLine)
|
|
lcDispPos.nLine -= lcEnd.nLine - lcStart.nLine;
|
|
|
|
if (lcEnd.nLine == lcDispPos.nLine)
|
|
{
|
|
if (lcEnd.nLine == lcStart.nLine)
|
|
{
|
|
ASSERT(lcDispPos.nCol >= lcEnd.nCol);
|
|
lcDispPos.nCol -= lcEnd.nCol - lcStart.nCol;
|
|
}
|
|
else
|
|
{
|
|
lcDispPos.nCol -= lcEnd.nCol;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return lcDispPos;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CopyOrMoveText(BOOL bCopy)
|
|
{
|
|
if (!m_pSelection->IsSelExist() || m_pSelection->IsInSel_disp(m_ptDropPos.y, m_ptDropPos.x))
|
|
return;
|
|
|
|
CMemFile memfile(CalcAveDataSize(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_str().nLine));
|
|
|
|
BOOL bRes = m_pBuffer->GetBuffer(m_pSelection->GetNormalStart_disp(),
|
|
m_pSelection->GetNormalEnd_disp(), memfile,
|
|
m_pSelection->bBlockSelectionMode);
|
|
if (!bRes)
|
|
return;
|
|
|
|
memfile.Write((const void *)_T("\0"), sizeof(TCHAR));
|
|
BYTE *pBytes = memfile.Detach();
|
|
|
|
CString strDropText = (LPTSTR)pBytes;
|
|
free(pBytes);
|
|
|
|
// First insert the text
|
|
if (m_ptDropPos.y > GetRowCount())
|
|
m_ptDropPos.y = GetRowCount();
|
|
|
|
XTP_EDIT_LINECOL lcDropPos_disp = XTP_EDIT_LINECOL::MakeLineCol(m_ptDropPos.y, m_ptDropPos.x);
|
|
BOOL bBlockSelectionMode = m_pSelection->bBlockSelectionMode;
|
|
|
|
if (!bCopy)
|
|
{
|
|
if (!(lcDropPos_disp < m_pSelection->GetNormalStart_disp()))
|
|
{
|
|
lcDropPos_disp = _SubtractSelSizeFromPos(lcDropPos_disp);
|
|
}
|
|
DeleteSelection(); // reset current selection
|
|
}
|
|
|
|
CString strText;
|
|
m_pBuffer->GetLineText(lcDropPos_disp.nLine, strText);
|
|
int nAbsDropCol = CalcAbsCol(strText, lcDropPos_disp.nCol);
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(lcDropPos_disp.nLine, nAbsDropCol);
|
|
//**----------------------
|
|
|
|
BOOL bReplace = GetTabWithSpace();
|
|
SetTabWithSpace(FALSE);
|
|
|
|
XTP_EDIT_LINECOL finalLC;
|
|
BOOL bInsRes = FALSE;
|
|
if (bBlockSelectionMode)
|
|
{
|
|
bInsRes = m_pBuffer->InsertTextBlock(strDropText, lcDropPos_disp.nLine, nAbsDropCol,
|
|
TRUE, &finalLC);
|
|
}
|
|
else
|
|
{
|
|
bInsRes = m_pBuffer->InsertText(strDropText, lcDropPos_disp.nLine, nAbsDropCol,
|
|
TRUE, &finalLC);
|
|
}
|
|
|
|
SetTabWithSpace(bReplace);
|
|
|
|
if (!bCopy)
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_MOVE);
|
|
}
|
|
else
|
|
{
|
|
// It's a drag copy
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_COPY);
|
|
}
|
|
|
|
m_pSelection->Reset_str(lcDropPos_disp.nLine, nAbsDropCol - 1);
|
|
m_pSelection->SetEnd_str(finalLC.nLine, finalLC.nCol - 1);
|
|
m_pSelection->bBlockSelectionMode = bBlockSelectionMode;
|
|
|
|
int nRowFrom = m_pSelection->GetNormalStart_str().nLine;
|
|
int nRowTo = m_pSelection->GetNormalEnd_str().nLine;
|
|
//**----------------------
|
|
OnEditChanged(nRowFrom, m_pSelection->GetNormalStart_str().nCol + 1,
|
|
nRowTo, m_pSelection->GetNormalEnd_str().nCol + 1, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
CalculateEditbarLength();
|
|
|
|
SetCurCaretPos(m_pSelection->GetEnd_disp().nLine, m_pSelection->GetEnd_disp().nCol);
|
|
|
|
SetDocModified();
|
|
|
|
//**----------------------
|
|
// OnEditChanged(nRowFrom, m_pSelection->GetNormalStart_str().nCol,
|
|
// nRowTo, m_pSelection->GetNormalEnd_str().nCol, xtpEditActInsert);
|
|
//**----------------------
|
|
|
|
UINT nAction = (XTP_EDIT_EDITACTION_MODIFYROW | XTP_EDIT_EDITACTION_INSERTROW);
|
|
NotifyEditChanged(nRowFrom, nRowTo, nAction);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
|
|
{
|
|
if (GetCapture() == this)
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
|
|
if (m_bRightButtonDrag && m_bDragging && m_bDroppable)
|
|
{
|
|
HandleDrop(FALSE);
|
|
}
|
|
else
|
|
{
|
|
CXTPClientRect rcWnd(this);
|
|
ClientToScreen(&rcWnd);
|
|
|
|
m_bDragging = FALSE;
|
|
|
|
if (point.x < 0 || point.y < 0) //keyboard ContextMenu button pressed
|
|
{
|
|
::GetCaretPos(&point);
|
|
ClientToScreen(&point);
|
|
if (point.x < 0 || point.y < 0)
|
|
point = rcWnd.CenterPoint();
|
|
}
|
|
if (m_pParentWnd && rcWnd.PtInRect(point))
|
|
{
|
|
CWnd::HideCaret();
|
|
m_pParentWnd->SendMessage(WM_CONTEXTMENU, (WPARAM)pWnd->GetSafeHwnd(), (LPARAM)MAKELONG(point.x, point.y));
|
|
CWnd::ShowCaret();
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
|
|
m_bRightButtonDrag = FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnDragCopy()
|
|
{
|
|
CopyOrMoveText(TRUE);
|
|
m_bRightButtonDrag = FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnDragMove()
|
|
{
|
|
CopyOrMoveText(FALSE);
|
|
m_bRightButtonDrag = FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RestoreCursor()
|
|
{
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetInternalRowBkColor(int nRow, COLORREF crBack)
|
|
{
|
|
m_mapInternalRowBkColor[nRow] = crBack;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetInternalRowColor(int nRow, COLORREF clrFront)
|
|
{
|
|
m_mapInternalRowForeColor[nRow] = clrFront;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetRowBkColor(int nRow, COLORREF crBack)
|
|
{
|
|
CXTPSyntaxEditRowColorMap& mapRowBkColor = m_pOptions->m_mapRowBkColor;
|
|
|
|
if (nRow == -1)
|
|
{
|
|
if (mapRowBkColor.GetCount() == 0)
|
|
return;
|
|
|
|
mapRowBkColor.RemoveAll();
|
|
}
|
|
else
|
|
{
|
|
if (crBack == RGB(255, 255, 255) || crBack == COLORREF_NULL)
|
|
mapRowBkColor.RemoveKey(nRow);
|
|
else
|
|
mapRowBkColor[nRow] = crBack;
|
|
}
|
|
|
|
InvalidateAll();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetRowColor(int nRow, COLORREF clrFront)
|
|
{
|
|
CXTPSyntaxEditRowColorMap& mapRowColor = m_pOptions->m_mapRowForeColor;
|
|
|
|
if (nRow == -1)
|
|
{
|
|
if (mapRowColor.GetCount() == 0)
|
|
return;
|
|
|
|
mapRowColor.RemoveAll();
|
|
}
|
|
else
|
|
{
|
|
if (clrFront == RGB(0, 0, 0) || clrFront == COLORREF_NULL)
|
|
mapRowColor.RemoveKey(nRow);
|
|
else
|
|
mapRowColor[nRow] = clrFront;
|
|
}
|
|
|
|
InvalidateAll();
|
|
}
|
|
|
|
COLORREF CXTPSyntaxEditCtrl::GetRowColor(int nRow) const
|
|
{
|
|
COLORREF clrFront;
|
|
|
|
if (m_mapInternalRowForeColor.Lookup(nRow, clrFront))
|
|
{
|
|
return clrFront;
|
|
}
|
|
|
|
if (m_pOptions->m_mapRowForeColor.Lookup(nRow, clrFront))
|
|
{
|
|
return clrFront;
|
|
}
|
|
|
|
return COLORREF_NULL;
|
|
}
|
|
|
|
COLORREF CXTPSyntaxEditCtrl::GetRowBkColor(int nRow) const
|
|
{
|
|
COLORREF crBack;
|
|
|
|
if (m_mapInternalRowBkColor.Lookup(nRow, crBack))
|
|
{
|
|
return crBack;
|
|
}
|
|
|
|
if (m_pOptions->m_mapRowBkColor.Lookup(nRow, crBack))
|
|
{
|
|
return crBack;
|
|
}
|
|
|
|
return COLORREF_NULL;
|
|
}
|
|
|
|
|
|
const CXTPSyntaxEditCtrl& CXTPSyntaxEditCtrl::operator=(const CXTPSyntaxEditCtrl& src)
|
|
{
|
|
if (::IsWindow(src.m_hWnd))
|
|
{
|
|
SetCurrentDocumentRow(src.m_nCurrentDocumentRow);
|
|
m_nCurrentCol = src.m_nCurrentCol;
|
|
m_nDispCol = src.m_nDispCol;
|
|
}
|
|
|
|
|
|
CalculateEditbarLength();
|
|
|
|
|
|
CMDTARGET_RELEASE(m_pOptions);
|
|
m_pOptions = src.m_pOptions;
|
|
CMDTARGET_ADDREF(m_pOptions);
|
|
|
|
|
|
RecalcScrollBars();
|
|
|
|
SetScrollPos(SB_HORZ, 0);
|
|
m_pDrawTextProcessor->SetScrollXOffset(0);
|
|
|
|
SetPaintManager(src.GetPaintManager());
|
|
CMDTARGET_ADDREF(m_pPaintManeger);
|
|
|
|
|
|
return *this;
|
|
}
|
|
|
|
CWnd * CXTPSyntaxEditCtrl::GetEffectiveParent() const
|
|
{
|
|
CWnd *pScrollWnd = GetParent();
|
|
|
|
if (GetParent())
|
|
{
|
|
pScrollWnd = GetParent();
|
|
|
|
if (!IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
|
|
{
|
|
pScrollWnd = GetParent();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pScrollWnd = const_cast<CXTPSyntaxEditCtrl *>(this);
|
|
}
|
|
|
|
return pScrollWnd;
|
|
}
|
|
|
|
DWORD CXTPSyntaxEditCtrl::GetAutoscrollDirection(int* pnCols, int* pnRows)
|
|
{
|
|
CPoint ptCursor;
|
|
GetCursorPos(&ptCursor);
|
|
ScreenToClient(&ptCursor);
|
|
|
|
CRect rcText = m_pDrawTextProcessor->GetTextRect();
|
|
int nAutoZoneY = min(m_pDrawTextProcessor->GetRowHeight(), rcText.Height()/4);
|
|
int nAutoZoneX2 = min(m_pDrawTextProcessor->GetTextMetrics().tmAveCharWidth, rcText.Width()/4);
|
|
|
|
DWORD dwDirection = 0;
|
|
|
|
int nScrollX = 0, nScrollY = 0;
|
|
|
|
if (ptCursor.y < rcText.top + nAutoZoneY)
|
|
{
|
|
dwDirection += xtpTop;
|
|
nScrollY = -1 - (rcText.top + nAutoZoneY - ptCursor.y) / (nAutoZoneY / 2);
|
|
}
|
|
if (ptCursor.y > rcText.bottom - nAutoZoneY)
|
|
{
|
|
dwDirection += xtpBottom;
|
|
nScrollY = 1 + (ptCursor.y - rcText.bottom + nAutoZoneY) / (nAutoZoneY / 2);
|
|
}
|
|
if (ptCursor.x < rcText.left)
|
|
{
|
|
dwDirection += xtpLeft;
|
|
nScrollX = -1 - (rcText.left - ptCursor.x) / (nAutoZoneX2 / 2);
|
|
}
|
|
if (ptCursor.x > rcText.right - nAutoZoneX2)
|
|
{
|
|
dwDirection += xtpRight;
|
|
nScrollX = 1 + (ptCursor.x - rcText.right + nAutoZoneX2) / (nAutoZoneX2 / 2);
|
|
}
|
|
|
|
if (pnCols)
|
|
*pnCols = nScrollX;
|
|
|
|
if (pnRows)
|
|
*pnRows = nScrollY;
|
|
|
|
return dwDirection;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnTimer(UINT_PTR nIDEvent)
|
|
{
|
|
if (nIDEvent == TIMER_AUTOSCROLL_ID)
|
|
{
|
|
int nScrollX = 0, nScrollY = 0;
|
|
m_dwAutoScrollDirection = GetAutoscrollDirection(&nScrollX, &nScrollY);
|
|
|
|
if (nScrollX || nScrollY)
|
|
{
|
|
Scroll(nScrollX, nScrollY);
|
|
|
|
OnTimer(TIMER_SELECTION_ID);
|
|
//UpdateWindow();
|
|
}
|
|
|
|
BOOL bLButton = (::GetKeyState(VK_LBUTTON) & KF_UP) == KF_UP;
|
|
|
|
if (!m_dwAutoScrollDirection || !bLButton)
|
|
{
|
|
m_dwAutoScrollDirection = 0;
|
|
KillTimer(TIMER_AUTOSCROLL_ID);
|
|
}
|
|
}
|
|
else if (nIDEvent == TIMER_SELECTION_ID)
|
|
{
|
|
if ((::GetKeyState(VK_LBUTTON) & KF_UP) == 0)
|
|
{
|
|
m_pSelection->bSelectingRunning = FALSE;
|
|
|
|
KillTimer(TIMER_SELECTION_ID);
|
|
return;
|
|
}
|
|
|
|
CPoint ptCursor;
|
|
GetCursorPos(&ptCursor);
|
|
ScreenToClient(&ptCursor);
|
|
|
|
BOOL bIsAutoScrollTimer = !!m_dwAutoScrollDirection;
|
|
|
|
m_dwAutoScrollDirection = GetAutoscrollDirection();
|
|
if (m_dwAutoScrollDirection)
|
|
{
|
|
if (!bIsAutoScrollTimer)
|
|
SetTimer(TIMER_AUTOSCROLL_ID, TIMER_AUTOSCROLL_TIME, NULL);
|
|
}
|
|
else
|
|
{
|
|
m_dwAutoScrollDirection = 0;
|
|
KillTimer(TIMER_AUTOSCROLL_ID);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
CRect rcBookmark, rcLineNum, rcNodes, rcText;
|
|
CalcEditRects(&rcBookmark, &rcLineNum, &rcNodes, &rcText);
|
|
CRect rcLineNumAndNodes(rcLineNum);
|
|
rcLineNumAndNodes.right = rcNodes.right;
|
|
|
|
int nNewRow = 0, nNewCol = 0, nNewDispRow = 0, nNewDispCol = 0;
|
|
BOOL bVirtualSpace = m_pSelection->IsbBlockSelectionMode() ? TRUE : -1;
|
|
RowColFromPoint(ptCursor, &nNewRow, &nNewCol, &nNewDispRow, &nNewDispCol, bVirtualSpace);
|
|
|
|
BOOL bSelFromLeftBar = rcLineNumAndNodes.PtInRect(ptCursor);
|
|
|
|
if (bSelFromLeftBar && m_pSelection->nSelStartTextRowFromLeftBar)
|
|
{
|
|
if (nNewRow >= m_pSelection->nSelStartTextRowFromLeftBar)
|
|
{
|
|
nNewRow++;
|
|
m_pSelection->SetStart_str(m_pSelection->nSelStartTextRowFromLeftBar, 0);
|
|
}
|
|
else
|
|
{
|
|
m_pSelection->SetStart_str(m_pSelection->nSelStartTextRowFromLeftBar+1, 0);
|
|
}
|
|
}
|
|
|
|
int nEndRow_prev = m_pSelection->GetEnd_disp().nLine;
|
|
int nEndDispCol_prev = m_pSelection->GetEnd_disp().nCol;
|
|
|
|
if (nEndRow_prev != nNewRow || nEndDispCol_prev != nNewDispCol)
|
|
{
|
|
// TRACE(_T("OnTimer.sel. RowColFromPoint: nNewRow=%d, nNewCol=%d, nNewDispRow=%d, nNewDispCol=%d \n"),
|
|
// nNewRow, nNewCol, nNewDispRow, nNewDispCol);
|
|
|
|
m_pSelection->SetEnd_disp(nNewRow, nNewDispCol);
|
|
|
|
if (m_pSelection->bWordSelectionMode)
|
|
{
|
|
XTP_EDIT_LINECOL lcWord1, lcWord2;
|
|
BOOL bOverSpace = FALSE;
|
|
|
|
UINT nFindDir = m_pSelection->IsSelNormal() ? XTP_EDIT_FINDWORD_NEXT : XTP_EDIT_FINDWORD_PREV;
|
|
BOOL bFind = FindWordEx_str(nFindDir, m_pSelection->GetEnd_str(), lcWord1, lcWord2, bOverSpace);
|
|
//TRACE(_T("2-FindWordEx_str = %d (%d, %d - %d, %d)"), bFind,
|
|
// lcWord1.nLine, lcWord1.nCol, lcWord2.nLine, lcWord2.nCol);
|
|
|
|
XTP_EDIT_LINECOL& lcWordEnd = m_pSelection->IsSelNormal() ? lcWord2 : lcWord1;
|
|
lcWordEnd.nCol--;
|
|
|
|
if (bFind && lcWordEnd.IsValidData() && lcWordEnd != m_pSelection->GetEnd_str())
|
|
{
|
|
m_pSelection->SetEnd_str(lcWordEnd.nLine, lcWordEnd.nCol);
|
|
}
|
|
}
|
|
|
|
SetCurrentDocumentRow(nNewRow);
|
|
m_nDispCol = m_pSelection->GetEnd_disp().nCol;
|
|
m_nCurrentCol = m_pSelection->GetEnd_str().nCol + 1;
|
|
|
|
int nCaretLine = m_pSelection->GetEnd_disp().nLine;
|
|
if (bSelFromLeftBar && m_pSelection->GetEnd_disp() >= m_pSelection->GetStart_disp())
|
|
nCaretLine = max(1, nCaretLine - 1);
|
|
|
|
SetCurCaretPos(nCaretLine, m_nDispCol, FALSE, FALSE);
|
|
|
|
//TRACE(_T("Selection: (row=%d, strPos=%d, DispCol=%d)-(row=%d, strPos=%d, DispCol=%d) \n"),
|
|
// m_pSelection->GetStart_str().nLine, m_pSelection->GetStart_str().nCol, m_pSelection->GetStart_disp().nCol,
|
|
// m_pSelection->GetEnd_str().nLine, m_pSelection->GetEnd_str().nCol, m_pSelection->GetEnd_disp().nCol);
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
else if (nIDEvent == TIMER_REDRAW_WHEN_PARSE)
|
|
{
|
|
KillTimer(TIMER_REDRAW_WHEN_PARSE);
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::Select(int nRow1, int nDispCol1, int nRow2, int nDispCol2, BOOL bRedraw)
|
|
{
|
|
if (nRow1 < 1 || nRow1 > GetRowCount())
|
|
return FALSE;
|
|
|
|
if (nRow2 < 1 || nRow2 > GetRowCount())
|
|
return FALSE;
|
|
|
|
m_pSelection->Reset_disp(nRow1, nDispCol1);
|
|
m_pSelection->SetEnd_disp(nRow2, nDispCol2);
|
|
|
|
SetCurrentDocumentRow(m_pSelection->GetNormalEnd_disp().nLine);
|
|
m_nDispCol = m_pSelection->GetNormalEnd_disp().nCol;
|
|
m_nCurrentCol = m_pSelection->GetNormalEnd_str().nCol + 1;
|
|
|
|
if (bRedraw)
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::Unselect()
|
|
{
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
m_pSelection->Reset_disp(m_pSelection->GetEnd_disp().nLine,
|
|
m_pSelection->GetEnd_disp().nCol);
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::ReplaceSel(LPCTSTR szNewText)
|
|
{
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
SetCurrentDocumentRow(m_pSelection->GetNormalStart_disp().nLine);
|
|
m_nDispCol = m_pSelection->GetNormalStart_disp().nCol;
|
|
m_nCurrentCol = m_pSelection->GetNormalStart_str().nCol + 1; //CalcAbsCol(GetLineText(m_pSelection->GetNormalStart_disp().nLine), m_nDispCol);
|
|
}
|
|
|
|
BOOL bOverwriteMode = m_pBuffer->GetOverwriteFlag();
|
|
m_pBuffer->SetOverwriteFlag(FALSE);
|
|
|
|
InsertString(szNewText, GetCurrentDocumentRow(), m_nCurrentCol, TRUE);
|
|
|
|
m_pBuffer->SetOverwriteFlag(bOverwriteMode);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::ReplaceAll(LPCTSTR szFindText, LPCTSTR szReplaceText,
|
|
BOOL bMatchWholeWord, BOOL bMatchCase)
|
|
{
|
|
int nMatchFound = 0;
|
|
|
|
if (_tcsclen(szFindText) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int iTopRow = GetTopRow();
|
|
int iCurRow = GetCurRow();
|
|
int iCurCol = GetCurCol();
|
|
|
|
SetCurPos(1, 1, FALSE, FALSE);
|
|
|
|
CWaitCursor wait;
|
|
|
|
BOOL bFirst = TRUE;
|
|
|
|
while (GetCurRow() <= GetRowCount())
|
|
{
|
|
BOOL bFound = Find(szFindText,
|
|
bMatchWholeWord, bMatchCase,
|
|
TRUE, FALSE);
|
|
|
|
if (bFound)
|
|
{
|
|
ReplaceSel(szReplaceText);
|
|
if (!bFirst)
|
|
GetEditBuffer()->GetUndoRedoManager()->ChainLastCommand();
|
|
}
|
|
else
|
|
break;
|
|
|
|
bFirst = FALSE;
|
|
|
|
nMatchFound++;
|
|
}
|
|
|
|
if (!bFirst)
|
|
GetEditBuffer()->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_REPLACE_ALL);
|
|
|
|
SetTopRow(iTopRow);
|
|
SetCurPos(iCurRow, iCurCol);
|
|
|
|
return nMatchFound;
|
|
}
|
|
|
|
|
|
BOOL CXTPSyntaxEditCtrl::Find(LPCTSTR szText, BOOL bMatchWholeWord, BOOL bMatchCase, BOOL bSearchDown,
|
|
BOOL bRedraw, int nStartRow, int nStartCol)
|
|
{
|
|
// First check the current row
|
|
CString strLineText;
|
|
|
|
int iStartCol = m_nCurrentCol;
|
|
int iStartRow = GetCurrentDocumentRow();
|
|
|
|
int nTopRow = m_nTopRow;
|
|
int nBottomRow = GetDocumentRow(GetRowPerPage());
|
|
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
if (bSearchDown)
|
|
{
|
|
iStartCol = m_pSelection->GetNormalEnd_str().nCol + 1; // m_ptEndSel.x;
|
|
iStartRow = m_pSelection->GetNormalEnd_str().nLine; // m_ptEndSel.y;
|
|
}
|
|
else
|
|
{
|
|
iStartCol = m_pSelection->GetNormalStart_str().nCol + 1; // m_ptStartSel.x;
|
|
iStartRow = m_pSelection->GetNormalStart_str().nLine; // m_ptStartSel.y;
|
|
}
|
|
}
|
|
|
|
iStartCol = nStartCol < 0 ? iStartCol : nStartCol;
|
|
iStartRow = nStartRow < 0 ? iStartRow : nStartRow;
|
|
|
|
m_pBuffer->GetLineText(iStartRow, strLineText);
|
|
|
|
BOOL bResult = MatchText(iStartRow, strLineText, szText, iStartCol, bMatchWholeWord, bMatchCase, bSearchDown, bRedraw);
|
|
|
|
if (bResult)
|
|
return TRUE;
|
|
|
|
if (bSearchDown)
|
|
{
|
|
for (int i = (iStartRow + 1); i <= GetRowCount(); i++)
|
|
{
|
|
m_pBuffer->GetLineText(i, strLineText);
|
|
|
|
bResult = MatchText(i, strLineText, szText, 0, bMatchWholeWord, bMatchCase, TRUE, bRedraw);
|
|
|
|
if (bResult)
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = (iStartRow - 1); i >= 1; i--)
|
|
{
|
|
m_pBuffer->GetLineText(i, strLineText);
|
|
|
|
bResult = MatchText(i, strLineText, szText, (int)_tcsclen(strLineText) + 1, bMatchWholeWord, bMatchCase, FALSE, bRedraw);
|
|
|
|
if (bResult)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bResult)
|
|
{
|
|
if (m_pSelection->GetStart_str().nLine > nBottomRow)
|
|
{
|
|
ShiftCurrentVisibleRowDown(2 * GetRowPerPage() / 3);
|
|
}
|
|
else if (m_pSelection->GetStart_str().nLine < nTopRow)
|
|
{
|
|
ShiftCurrentVisibleRowUp(GetRowPerPage() / 3);
|
|
}
|
|
|
|
SetCurCaretPos(m_pSelection->GetNormalEnd_disp().nLine, m_pSelection->GetNormalEnd_disp().nCol);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::MatchText(int nRow, LPCTSTR szLineText, LPCTSTR szMatchText, int nStartPos, BOOL bMatchWholeWord, BOOL bMatchCase, BOOL bSearchForward, BOOL bRedraw)
|
|
{
|
|
BOOL bMatched = FALSE;
|
|
|
|
#ifdef XTP_FIXED
|
|
const int nLen = (int) _tcslen(szLineText);
|
|
const int nSearchLen = (int) _tcslen(szMatchText);
|
|
#else
|
|
const int nLen = (int) _tcsclen(szLineText);
|
|
const int nSearchLen = (int) _tcsclen(szMatchText);
|
|
#endif
|
|
|
|
static LPCTSTR szSeps = _T("() \t<>{}:;,.=%\"'!@#$^&*-\\|[]/?");
|
|
#ifdef XTP_FIXED
|
|
int count = 0;
|
|
int temp = 0;
|
|
for (count = 0; count < nStartPos - 1; count ++)
|
|
{
|
|
if (isleadbyte( szLineText[temp] ))
|
|
temp += 2;
|
|
else
|
|
temp++;
|
|
}
|
|
nStartPos = temp;
|
|
#endif
|
|
|
|
if (bSearchForward)
|
|
{
|
|
for (int i = nStartPos; i <= (nLen - nSearchLen + 1); i++)
|
|
{
|
|
int nFound = -1;
|
|
if (bMatchCase)
|
|
nFound = _tcsncmp((szLineText + i - 1), szMatchText, nSearchLen);
|
|
else
|
|
nFound = _tcsnicmp((szLineText + i - 1), szMatchText, nSearchLen);
|
|
|
|
bMatched = (nFound == 0);
|
|
|
|
if (bMatchWholeWord && nFound == 0)
|
|
{
|
|
BOOL bSepAfter = FALSE;
|
|
BOOL bSepBefore = FALSE;
|
|
|
|
if ((i - 1 + nSearchLen) >= nLen)
|
|
{
|
|
bSepAfter = TRUE;
|
|
}
|
|
else
|
|
{
|
|
LPCTSTR pcszTextAfter = (szLineText + i - 1) + nSearchLen;
|
|
bSepAfter = (_tcschr(szSeps, *pcszTextAfter) != 0);
|
|
}
|
|
|
|
if (i == 1)
|
|
bSepBefore = TRUE;
|
|
else
|
|
bSepBefore = (_tcschr(szSeps, *(szLineText + i - 2)) != 0);
|
|
|
|
if (!bSepAfter || !bSepBefore)
|
|
bMatched = FALSE;
|
|
}
|
|
|
|
if (bMatched)
|
|
{
|
|
#ifdef XTP_FIXED
|
|
LPTSTR buffer = (LPTSTR)malloc( sizeof( TCHAR ) * ( nLen + 1 ) );
|
|
memcpy( buffer, szLineText, sizeof( TCHAR ) * ( nLen + 1 ) );
|
|
buffer[nLen] = '\0';
|
|
buffer[i + nSearchLen - 1] = '\0';
|
|
int nDispCol2 = _tcsclen( buffer );
|
|
buffer[i - 1] = '\0';
|
|
int nDispCol1 = _tcsclen( buffer );
|
|
nDispCol1 = CalcDispCol(szLineText, nDispCol1 + 1 );
|
|
nDispCol2 = CalcDispCol(szLineText, nDispCol2 + 1 );
|
|
Select(nRow, nDispCol1, nRow, nDispCol2, bRedraw);
|
|
free( buffer );
|
|
#else
|
|
int nDispCol1 = CalcDispCol(szLineText, i);
|
|
int nDispCol2 = CalcDispCol(szLineText, (i + nSearchLen));
|
|
Select(nRow, nDispCol1, nRow, nDispCol2, bRedraw);
|
|
#endif
|
|
m_nDispCol = nDispCol2;
|
|
m_nCurrentCol = (i + nSearchLen);
|
|
SetCurCaretPos(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = (nStartPos-nSearchLen); i >= 1 ; i--)
|
|
{
|
|
int nFound = -1;
|
|
if (bMatchCase)
|
|
nFound = _tcsncmp((szLineText + i - 1), szMatchText, nSearchLen);
|
|
else
|
|
nFound = _tcsnicmp((szLineText + i - 1), szMatchText, nSearchLen);
|
|
|
|
bMatched = (nFound == 0);
|
|
|
|
if (bMatchWholeWord && nFound == 0)
|
|
{
|
|
BOOL bSepAfter = FALSE;
|
|
BOOL bSepBefore = FALSE;
|
|
|
|
if ((i - 1 + nSearchLen) >= nLen)
|
|
{
|
|
bSepAfter = TRUE;
|
|
}
|
|
else
|
|
{
|
|
LPCTSTR pcszTextAfter = (szLineText + i - 1) + nSearchLen;
|
|
bSepAfter = (_tcschr(szSeps, *pcszTextAfter) != 0);
|
|
}
|
|
|
|
if (i == 1)
|
|
bSepBefore = TRUE;
|
|
else
|
|
bSepBefore = (_tcschr(szSeps, *(szLineText + i - 2)) != 0);
|
|
|
|
if (!bSepAfter || !bSepBefore)
|
|
bMatched = FALSE;
|
|
}
|
|
|
|
if (bMatched)
|
|
{
|
|
LPTSTR buffer = (LPTSTR)malloc( sizeof(TCHAR) * (nLen + 1) );
|
|
memcpy( buffer, szLineText, sizeof(TCHAR) * (nLen + 1) );
|
|
buffer[nLen] = '\0';
|
|
buffer[i + nSearchLen - 1] = '\0';
|
|
int nDispCol2 = (int) _tcsclen( buffer );
|
|
buffer[i - 1] = '\0';
|
|
int nDispCol1 = (int) _tcsclen( buffer );
|
|
nDispCol1 = CalcDispCol(szLineText, nDispCol1 + 1 );
|
|
nDispCol2 = CalcDispCol(szLineText, nDispCol2 + 1 );
|
|
Select(nRow, nDispCol1, nRow, nDispCol2, bRedraw);
|
|
free( buffer );
|
|
|
|
m_nDispCol = nDispCol1;
|
|
m_nCurrentCol = i;
|
|
SetCurCaretPos(m_pSelection->GetNormalEnd_disp().nLine,
|
|
m_pSelection->GetNormalEnd_disp().nCol, FALSE/*, FALSE*/);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bMatched;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ShowHScrollBar(BOOL bShow)
|
|
{
|
|
ShowScrollBar(SB_HORZ, bShow);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SelectWord(CPoint point)
|
|
{
|
|
int nRow = 0, nCol = 0;
|
|
|
|
if (!RowColFromPoint(point, &nRow, &nCol))
|
|
return;
|
|
|
|
XTP_EDIT_LINECOL lcWord1, lcWord2;
|
|
BOOL bOverSpace = FALSE;
|
|
|
|
UINT nFindDir = XTP_EDIT_FINDWORD_NEXT;
|
|
BOOL bFind = FindWordEx(nFindDir, nRow, nCol, lcWord1, lcWord2, bOverSpace);
|
|
|
|
if (bFind && lcWord1.IsValidData() && lcWord2.IsValidData() && !bOverSpace)
|
|
{
|
|
m_pSelection->SetStart_str(lcWord1.nLine, lcWord1.nCol-1);
|
|
m_pSelection->SetEnd_str(lcWord2.nLine, lcWord2.nCol-1);
|
|
|
|
SetCurCaretPos(m_pSelection->GetEnd_disp().nLine,
|
|
m_pSelection->GetEnd_disp().nCol);
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::FindWord(UINT nFindWhat)
|
|
{
|
|
XTP_EDIT_LINECOL lcWord1, lcWord2;
|
|
BOOL bOverSpace;
|
|
|
|
BOOL bFind = FindWordEx(nFindWhat, GetCurrentDocumentRow(), m_nCurrentCol,
|
|
lcWord1, lcWord2, bOverSpace);
|
|
|
|
XTP_EDIT_LINECOL& lcWordEnd = (nFindWhat == XTP_EDIT_FINDWORD_NEXT) ? lcWord2 : lcWord1;
|
|
|
|
|
|
if (!bFind || !lcWordEnd.IsValidData())
|
|
return;
|
|
|
|
int nDispCol = CalcDispCol(lcWordEnd.nLine, lcWordEnd.nCol);
|
|
SetCurCaretPos(lcWordEnd.nLine, nDispCol);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::FindWordEx_str(UINT nFindWhat, XTP_EDIT_LINECOL lcPos_str,
|
|
XTP_EDIT_LINECOL& rlcWordStart, XTP_EDIT_LINECOL& rlcWordEnd, BOOL& rbOverSpace)
|
|
{
|
|
return FindWordEx(nFindWhat, lcPos_str.nLine, lcPos_str.nCol + 1, rlcWordStart,
|
|
rlcWordEnd, rbOverSpace);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::FindWordEx(UINT nFindWhat, int nTextRow, int nCol,
|
|
XTP_EDIT_LINECOL& rlcWordStart, XTP_EDIT_LINECOL& rlcWordEnd, BOOL& rbOverSpace)
|
|
{
|
|
// set word invalid borders
|
|
rlcWordStart = rlcWordEnd = XTP_EDIT_LINECOL::MINPOS;
|
|
rbOverSpace = FALSE;
|
|
|
|
CString strLineText;
|
|
const TCHAR* pCh = NULL;
|
|
|
|
// Volker Elies: added '+' character
|
|
const TCHAR szSeps[] = _T("[]{}()<>.,;:!?=*&%@^#-+\"\'/");
|
|
// const TCHAR szSepsAll[] = _T("[]{}()<>.,;:!?=*&%@^#-\"\'/\n\r\t ");
|
|
const TCHAR szSpaceSeps[] = _T(" \t");
|
|
const TCHAR szNLSeps[] = _T("\r\n");
|
|
|
|
int nDir = nFindWhat == XTP_EDIT_FINDWORD_PREV ? -1 : 1;
|
|
nCol = min(nCol-1, GetEditBuffer()->GetLineTextLengthC(nTextRow));
|
|
XTP_EDIT_LINECOL lcPosStart = XTP_EDIT_LINECOL::MakeLineCol(nTextRow, max(0, nCol));
|
|
|
|
CXTPSyntaxEditTextIterator txtIter(GetEditBuffer());
|
|
BOOL bSeek = txtIter.SeekPos(lcPosStart);
|
|
if (!bSeek)
|
|
return FALSE;
|
|
|
|
pCh = (nDir < 0) ? txtIter.SeekPrev() : txtIter.GetText(2);
|
|
if (!pCh)
|
|
return FALSE;
|
|
|
|
// Is over space/tab
|
|
BOOL bOverSpace = !!_tcschr(szSpaceSeps, *pCh);
|
|
BOOL bOverNL = !!_tcschr(szNLSeps, *pCh);
|
|
rbOverSpace = (bOverSpace || bOverNL);
|
|
|
|
if (!pCh)
|
|
return FALSE;
|
|
|
|
BOOL bStartCharSep = !!_tcschr(szSeps, *pCh);
|
|
|
|
if (rbOverSpace && nDir < 0)
|
|
{
|
|
while (pCh && (_tcschr(szSpaceSeps, *pCh) ||
|
|
!bOverSpace && _tcschr(szNLSeps, *pCh)) )
|
|
{
|
|
rlcWordEnd = txtIter.GetPosLC();
|
|
pCh = txtIter.SeekPrev();
|
|
}
|
|
|
|
if (!pCh || rlcWordEnd.nCol == 0 || bOverNL)
|
|
{
|
|
rlcWordEnd.nCol++;
|
|
rlcWordStart = rlcWordEnd;
|
|
return TRUE;
|
|
}
|
|
|
|
bStartCharSep = !!_tcschr(szSeps, *pCh);
|
|
}
|
|
|
|
if (rbOverSpace && nDir > 0) // one word border find - find the other one
|
|
{
|
|
XTP_EDIT_LINECOL& rlc1 = (nDir < 0) ? rlcWordEnd : rlcWordStart;
|
|
XTP_EDIT_LINECOL& rlc2 = (nDir < 0) ? rlcWordStart : rlcWordEnd;
|
|
|
|
rlc1 = txtIter.GetPosLC();
|
|
rlc2 = txtIter.GetPosLC();
|
|
|
|
while (pCh && (_tcschr(szSpaceSeps, *pCh) ||
|
|
_tcschr(szNLSeps, *pCh)) )
|
|
{
|
|
pCh = (nDir < 0) ? txtIter.SeekPrev() : txtIter.SeekNext(1, 2);
|
|
rlc2 = txtIter.GetPosLC();
|
|
}
|
|
}
|
|
else //find 2 word borders
|
|
{
|
|
rlcWordStart = txtIter.GetPosLC();
|
|
while (pCh && !((bStartCharSep == (!_tcschr(szSeps, *pCh))) ||
|
|
_tcschr(szSpaceSeps, *pCh) || _tcschr(szNLSeps, *pCh)))
|
|
{
|
|
rlcWordStart = txtIter.GetPosLC();
|
|
pCh = txtIter.SeekPrev();
|
|
}
|
|
|
|
pCh = txtIter.SeekNext(1, 2);
|
|
rlcWordEnd = txtIter.GetPosLC();
|
|
while (pCh && !(bStartCharSep == !_tcschr(szSeps, *pCh) ||
|
|
_tcschr(szSpaceSeps, *pCh) || _tcschr(szNLSeps, *pCh))
|
|
)
|
|
|
|
{
|
|
pCh = txtIter.SeekNext(1, 2);
|
|
rlcWordEnd = txtIter.GetPosLC();
|
|
}
|
|
|
|
if (rlcWordEnd > txtIter.GetPosLC_last(FALSE))
|
|
rlcWordEnd = txtIter.GetPosLC_last(FALSE);
|
|
}
|
|
|
|
rlcWordStart.nCol++;
|
|
rlcWordEnd.nCol++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::DeleteSelectedLines(int iForceDeleteRow)
|
|
{
|
|
int iLineFrom, iLineTo;
|
|
int iColTo = 1;
|
|
|
|
if (m_pSelection->IsSelExist())
|
|
{
|
|
iLineFrom = m_pSelection->GetNormalStart_str().nLine;
|
|
iLineTo = m_pSelection->GetNormalEnd_str().nLine;;
|
|
}
|
|
else
|
|
{
|
|
iLineFrom = iForceDeleteRow;
|
|
iLineTo = iLineFrom + 1;
|
|
}
|
|
|
|
if (iLineTo > GetRowCount())
|
|
{
|
|
iLineTo = GetRowCount();
|
|
|
|
const int iLen = (int)_tcsclen(GetLineText(iLineTo));
|
|
|
|
if (iLen == 0 && (iLineTo < 1 || iLineTo < iLineFrom))
|
|
iColTo = 1;
|
|
else
|
|
iColTo = iLen + 1;
|
|
|
|
if (iLineFrom == iLineTo && iColTo == 1 && iLen == 0) // Nothing to delete
|
|
return;
|
|
}
|
|
|
|
m_pSelection->Reset_disp(iLineFrom, 1);
|
|
|
|
int nFlags = xtpEditLMRefresh_Delete | xtpEditLMRefresh_Delete_only1;
|
|
if (iColTo > 1)
|
|
nFlags |= xtpEditLMRefresh_Delete_only2;
|
|
|
|
GetLineMarksManager()->RefreshLineMarks(iLineFrom, iLineTo, nFlags);
|
|
|
|
DeleteBuffer(iLineFrom, 1, iLineTo, iColTo);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::IncreaseIndent()
|
|
{
|
|
if (!m_pSelection->IsSelExist() ||
|
|
(m_pSelection->GetStart_disp().nLine == m_pSelection->GetEnd_disp().nLine &&
|
|
m_pSelection->GetStart_disp().nLine < GetRowCount()))
|
|
{
|
|
if (!m_pBuffer->GetOverwriteFlag())
|
|
return FALSE;
|
|
|
|
CString strLineText = GetLineText(GetCurrentDocumentRow());
|
|
const int iLineLen = (int)_tcsclen(strLineText);
|
|
|
|
int iMaxDispCol = CalcDispCol(strLineText, (iLineLen + 1));
|
|
|
|
if (m_nDispCol >= iMaxDispCol)
|
|
return FALSE;
|
|
|
|
if (m_nCurrentCol > (iLineLen + 1))
|
|
m_nCurrentCol = (iLineLen + 1);
|
|
|
|
m_nDispCol += (GetTabSize() - (m_nDispCol % GetTabSize())); // Align by tab size
|
|
|
|
if (m_nDispCol < 1)
|
|
m_nDispCol = 1;
|
|
|
|
m_nDispCol = CalcValidDispCol(strLineText, m_nDispCol);
|
|
m_nCurrentCol = CalcAbsCol(strLineText, m_nDispCol);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
return TRUE;
|
|
}
|
|
|
|
int iRowFrom = m_pSelection->GetNormalStart_str().nLine;
|
|
int iRowTo = m_pSelection->GetNormalEnd_str().nLine;
|
|
int iColTo = m_pSelection->GetNormalEnd_str().nCol;
|
|
int iColTo2 = m_pSelection->GetStart_disp().nCol;
|
|
if (iColTo == 0 && iColTo2 == 1 && iRowTo > iRowFrom)
|
|
iRowTo--;
|
|
|
|
if (!CanEditDoc())
|
|
return FALSE;
|
|
|
|
BOOL bModified = FALSE;
|
|
|
|
// First insert tabs in front
|
|
// If overwrite flag is not set
|
|
if (!m_pBuffer->GetOverwriteFlag())
|
|
{
|
|
const CString strText(GetTabWithSpace() ? CString((TCHAR)(' '), GetTabSize()) : _T("\x09"));
|
|
|
|
for (int i = iRowFrom; i <= iRowTo; i++)
|
|
{
|
|
//**----------------------
|
|
OnBeforeEditChanged(i, 1);
|
|
//**----------------------
|
|
|
|
m_pBuffer->InsertText(strText, i, 1);
|
|
|
|
bModified = TRUE;
|
|
|
|
if (i > iRowFrom)
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_INDENTATION);
|
|
}
|
|
|
|
//**----------------------
|
|
OnEditChanged(i, 1, i, 2, xtpEditActInsert);
|
|
//**----------------------
|
|
}
|
|
|
|
if (bModified)
|
|
{
|
|
NotifyEditChanged(iRowFrom, iRowTo, XTP_EDIT_EDITACTION_MODIFYROW);
|
|
}
|
|
}
|
|
|
|
// Select the lines
|
|
m_pSelection->Reset_disp(iRowFrom, 1);
|
|
m_pSelection->SetEnd_disp(iRowTo + 1, 1);
|
|
|
|
if (bModified)
|
|
SetDocModified();
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
UpdateWindow();
|
|
UpdateScrollPos();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DecreaseIndent()
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
{
|
|
if (m_nCurrentCol < 1)
|
|
m_nCurrentCol = 1;
|
|
|
|
LPCTSTR szLineText = GetLineText(GetCurrentDocumentRow());
|
|
|
|
int iAddFactor = 1;
|
|
|
|
if ((m_nDispCol - 1) % GetTabSize())
|
|
iAddFactor = 0;
|
|
|
|
m_nDispCol = 1 + ((((m_nDispCol - 1) / GetTabSize()) - iAddFactor) * GetTabSize()); // Align by tab size
|
|
|
|
if (m_nDispCol < 1)
|
|
m_nDispCol = 1;
|
|
|
|
m_nDispCol = CalcValidDispCol(szLineText, m_nDispCol);
|
|
m_nCurrentCol = CalcAbsCol(szLineText, m_nDispCol);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int iRowFrom = m_pSelection->GetNormalStart_str().nLine;
|
|
int iRowTo = m_pSelection->GetNormalEnd_str().nLine;
|
|
int iColTo = m_pSelection->GetNormalEnd_str().nCol;
|
|
int iColTo2 = m_pSelection->GetStart_disp().nCol;
|
|
if (iColTo == 0 && iColTo2 == 1 && iRowTo > iRowFrom)
|
|
iRowTo--;
|
|
|
|
if (!CanEditDoc())
|
|
return FALSE;
|
|
|
|
CString strLineText;
|
|
|
|
BOOL bFrontDeleted = FALSE;
|
|
BOOL bModified = FALSE;
|
|
|
|
// First tabs or blank spaces from front
|
|
for (int i = iRowFrom; i <= iRowTo; i++)
|
|
{
|
|
GetLineText(i, strLineText);
|
|
const int iLen = (int)_tcsclen(strLineText);
|
|
|
|
if (iLen == 0)
|
|
continue;
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(i, 1);
|
|
//**----------------------
|
|
|
|
if (strLineText.GetAt(0) == _T('\t'))
|
|
{
|
|
m_pBuffer->DeleteText(i, 1, i, 2);
|
|
bFrontDeleted = TRUE;
|
|
bModified = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// No tab found in the front
|
|
// try to find blank spaces
|
|
int iSpaceCount = 0;
|
|
for (int iCol = 0; iCol < GetTabSize() && iCol < iLen; iCol++)
|
|
{
|
|
if (strLineText.GetAt(iCol) == 0x20)
|
|
iSpaceCount++;
|
|
else
|
|
break;
|
|
}
|
|
if (iSpaceCount)
|
|
{
|
|
m_pBuffer->DeleteText(i, 1, i, (iSpaceCount + 1));
|
|
bFrontDeleted = TRUE;
|
|
bModified = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bFrontDeleted)
|
|
{
|
|
m_pBuffer->GetUndoRedoManager()->ChainLastCommand();
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_INDENT_DECREASE);
|
|
}
|
|
|
|
//**----------------------
|
|
OnEditChanged(i, 1, i, 1, xtpEditActDelete);
|
|
//**----------------------
|
|
}
|
|
|
|
if (bModified)
|
|
{
|
|
NotifyEditChanged(iRowFrom, iRowTo, XTP_EDIT_EDITACTION_MODIFYROW);
|
|
}
|
|
|
|
// Select the lines
|
|
m_pSelection->Reset_disp(iRowFrom, 1);
|
|
m_pSelection->SetEnd_disp(iRowTo + 1, 1);
|
|
|
|
if (bModified)
|
|
SetDocModified();
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
UpdateWindow();
|
|
UpdateScrollPos();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RecalcScrollBars()
|
|
{
|
|
_RecalcScrollBars();
|
|
|
|
CalculateEditbarLength();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RedrawScrollBar(int nBar)
|
|
{
|
|
CScrollBar* pScrollBar = GetScrollBarCtrl(nBar);
|
|
|
|
if (pScrollBar)
|
|
{
|
|
SAFE_INVALIDATE(pScrollBar);
|
|
}
|
|
else
|
|
{
|
|
if (m_hWnd) SendMessage(WM_NCPAINT);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::_RecalcHScrollMaxWidth()
|
|
{
|
|
CRect rcText = m_pDrawTextProcessor->GetTextRect();
|
|
int nPageX = rcText.Width();
|
|
|
|
int nMaxX = m_pDrawTextProcessor->GetRowsMaxWidth();
|
|
nMaxX += max(nPageX/4, m_pDrawTextProcessor->GetTextMetrics().tmAveCharWidth * 20);
|
|
nMaxX = max(nMaxX, rcText.Width() * 2);
|
|
|
|
m_nHScrollMaxWidth = max(nMaxX, m_nHScrollMaxWidth);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::_RecalcScrollBars()
|
|
{
|
|
if (!GetPaintManager()->GetFont()->GetSafeHandle())
|
|
return;
|
|
|
|
if (!m_hWnd || !::IsWindow(m_hWnd))
|
|
return;
|
|
|
|
// create scroll bar info
|
|
SCROLLINFO info;
|
|
ZeroMemory(&info, sizeof(SCROLLINFO));
|
|
info.cbSize = sizeof(SCROLLINFO);
|
|
info.fMask = SIF_ALL;
|
|
|
|
int nVisRows = GetVisibleRowsCount();
|
|
|
|
CRect rcText = m_pDrawTextProcessor->GetTextRect();
|
|
|
|
int nPageX = rcText.Width();
|
|
int nPageY = m_pDrawTextProcessor->GetRowsCount(FALSE);
|
|
|
|
_RecalcHScrollMaxWidth();
|
|
|
|
if (GetRowCount() <= 0)
|
|
{
|
|
if (GetVertScrollBar())
|
|
{
|
|
GetScrollInfo(SB_VERT, &info);
|
|
|
|
info.cbSize = sizeof(info);
|
|
info.fMask = SIF_PAGE | SIF_RANGE;
|
|
info.nPage = nPageY;
|
|
info.nMax= nPageY;
|
|
|
|
SetScrollInfo(SB_VERT, &info);
|
|
EnableScrollBarCtrl(SB_VERT, FALSE);
|
|
}
|
|
|
|
if (GetHorzScrollBar())
|
|
{
|
|
info.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_HORZ, &info);
|
|
|
|
info.nMax = m_nHScrollMaxWidth;
|
|
info.nPage = nPageX;
|
|
info.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_RANGE;
|
|
|
|
SetScrollInfo(SB_HORZ, &info);
|
|
}
|
|
|
|
if (GetVertScrollBar() && m_bVertScrollBarEnabled)
|
|
{
|
|
m_bVertScrollBarEnabled = FALSE;
|
|
RedrawScrollBar(SB_VERT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetHorzScrollBar())
|
|
{
|
|
info.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_HORZ, &info);
|
|
|
|
info.nMin = 0;
|
|
info.nMax = max(m_nHScrollMaxWidth, info.nMax);
|
|
info.nPage = nPageX;
|
|
info.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
|
|
|
SetScrollInfo(SB_HORZ, &info);
|
|
EnableScrollBarCtrl(SB_HORZ);
|
|
}
|
|
|
|
//---------------------------------------
|
|
if (GetVertScrollBar())
|
|
{
|
|
info.fMask = SIF_ALL;
|
|
GetScrollInfo(SB_VERT, &info);
|
|
|
|
int nMaxRowInPage = GetRowPerPage();
|
|
BOOL bVertScrl = (nVisRows >= nMaxRowInPage);
|
|
|
|
if (bVertScrl)
|
|
{
|
|
int nVisRow = GetVisibleRowsCount(m_nTopRow);
|
|
|
|
info.nMin = 1;
|
|
info.nMax = nVisRows;
|
|
info.nPage = nPageY;
|
|
info.nPos = nVisRow;
|
|
|
|
info.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
|
|
|
SetScrollInfo(SB_VERT, &info);
|
|
}
|
|
else
|
|
{
|
|
m_nTopRow = 1;
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
EnableScrollBarCtrl(SB_VERT, bVertScrl);
|
|
|
|
if (m_bVertScrollBarEnabled != bVertScrl)
|
|
{
|
|
m_bVertScrollBarEnabled = bVertScrl;
|
|
RedrawScrollBar(SB_VERT);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GetCurrentDocumentRow() > GetRowCount())
|
|
SetCurCaretPos(GetRowCount(), m_nDispCol);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RecalcVertScrollPos()
|
|
{
|
|
if (!::IsWindow(m_hWnd))
|
|
return;
|
|
|
|
if (!GetPaintManager()->GetFont()->GetSafeHandle())
|
|
return;
|
|
|
|
if (!GetVertScrollBar())
|
|
return;
|
|
|
|
int nPageRows = GetRowPerPage();
|
|
int nTotalVisRows = GetVisibleRowsCount();
|
|
|
|
BOOL bVertScrl = (nTotalVisRows >= nPageRows);
|
|
|
|
if (bVertScrl)
|
|
{
|
|
int nVisRow = GetVisibleRowsCount(m_nTopRow);
|
|
|
|
SCROLLINFO si;
|
|
ZeroMemory(&si, sizeof(SCROLLINFO));
|
|
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
|
si.nMin = 1;
|
|
si.nMax = nTotalVisRows;
|
|
si.nPage = nPageRows;
|
|
si.nPos = nVisRow;
|
|
|
|
VERIFY(SetScrollInfo(SB_VERT, &si));
|
|
}
|
|
else
|
|
{
|
|
m_nTopRow = 1;
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
EnableScrollBarCtrl(SB_VERT, bVertScrl);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RecalcHorzScrollPos()
|
|
{
|
|
if (!::IsWindow(m_hWnd))
|
|
return;
|
|
|
|
if (!GetPaintManager()->GetFont()->GetSafeHandle())
|
|
return;
|
|
|
|
if (!GetHorzScrollBar())
|
|
return;
|
|
|
|
_RecalcHScrollMaxWidth();
|
|
|
|
int nPos = GetScrollPos(SB_HORZ);
|
|
|
|
SCROLLINFO si;
|
|
ZeroMemory(&si, sizeof(SCROLLINFO));
|
|
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
|
si.nMin = 0;
|
|
si.nMax = si.nMax = max(m_nHScrollMaxWidth, si.nMax);
|
|
si.nPage = m_pDrawTextProcessor->GetTextRect().Width();
|
|
si.nPos = nPos;
|
|
|
|
VERIFY(SetScrollInfo(SB_HORZ, &si, FALSE));
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::NotifyCurRowCol(int iRow, int iCol) const
|
|
{
|
|
// Notify the parent class that position has been changed
|
|
XTP_EDIT_NMHDR_ROWCOLCHANGED src;
|
|
|
|
// NMHDR codes
|
|
src.nmhdr.code = XTP_EDIT_NM_ROWCOLCHANGED;
|
|
src.nmhdr.hwndFrom = m_hWnd;
|
|
src.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// Row col specific codes
|
|
src.nRow = iRow;
|
|
src.nCol = iCol;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)src.nmhdr.idFrom, (LPARAM)&src);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ValidateCol(const int nRow, int &nCol, int& nAbsCol)
|
|
{
|
|
CString strText;
|
|
|
|
GetLineText(nRow, strText);
|
|
|
|
nCol = CalcValidDispCol(strText, nCol);
|
|
|
|
nAbsCol = CalcAbsCol(strText, nCol);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::EnableOleDrag(BOOL bEnableDrag)
|
|
{
|
|
m_bEnableOleDrag = bEnableDrag;
|
|
}
|
|
|
|
HGLOBAL CXTPSyntaxEditCtrl::GetSelectionBuffer(UINT nFormat)
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
return NULL;
|
|
|
|
if (nFormat != CF_TEXT && nFormat != CF_UNICODETEXT)
|
|
return NULL;
|
|
|
|
CMemFile file(CalcAveDataSize(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_str().nLine));
|
|
|
|
BOOL bRes = m_pBuffer->GetBuffer(m_pSelection->GetNormalStart_disp(),
|
|
m_pSelection->GetNormalEnd_disp(), file,
|
|
m_pSelection->bBlockSelectionMode, TRUE);
|
|
if (!bRes)
|
|
return NULL;
|
|
|
|
file.Seek(0, CFile::end);
|
|
file.Write(_T("\0"), sizeof(TCHAR));
|
|
int nLen = (int)file.GetLength();
|
|
BYTE *pBytes = file.Detach();
|
|
|
|
UINT uCodePage = m_pBuffer->GetCodePage();
|
|
#ifdef _UNICODE
|
|
// If Unicode defined then for CF_TEXT conversion is needed
|
|
if (nFormat == CF_TEXT)
|
|
{
|
|
nLen = ::WideCharToMultiByte(uCodePage, 0, (LPWSTR)pBytes, -1, NULL, 0, NULL, NULL);
|
|
|
|
}
|
|
#else
|
|
if (nFormat == CF_UNICODETEXT)
|
|
{
|
|
nLen = ::MultiByteToWideChar(uCodePage, 0, (LPCSTR)pBytes, -1, NULL, 0);
|
|
nLen *= sizeof(wchar_t);
|
|
}
|
|
#endif
|
|
|
|
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, nLen);
|
|
|
|
if (!hMem)
|
|
return 0;
|
|
|
|
void *pText = ::GlobalLock(hMem);
|
|
|
|
#ifdef _UNICODE
|
|
if (nFormat == CF_UNICODETEXT)
|
|
MEMCPY_S(pText, pBytes, nLen);
|
|
else
|
|
{
|
|
::WideCharToMultiByte(uCodePage, 0, (LPWSTR)pBytes, -1, (LPSTR)pText, nLen, NULL, NULL);
|
|
}
|
|
#else
|
|
if (nFormat == CF_TEXT)
|
|
MEMCPY_S(pText, pBytes, nLen);
|
|
else
|
|
{
|
|
::MultiByteToWideChar(uCodePage, 0, (LPSTR)pBytes, -1, (LPWSTR)pText, (nLen / sizeof(wchar_t)));
|
|
}
|
|
#endif
|
|
|
|
::GlobalUnlock(hMem);
|
|
|
|
::free(pBytes);
|
|
|
|
return hMem;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetSelectionText(CString &strText)
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
return 0;
|
|
|
|
CMemFile file(CalcAveDataSize(m_pSelection->GetNormalStart_str().nLine,
|
|
m_pSelection->GetNormalEnd_str().nLine));
|
|
BOOL bRes = m_pBuffer->GetBuffer(m_pSelection->GetNormalStart_disp(),
|
|
m_pSelection->GetNormalEnd_disp(), file,
|
|
m_pSelection->bBlockSelectionMode, TRUE);
|
|
if (!bRes)
|
|
return 0;
|
|
|
|
file.Write((LPVOID)_T("\0"), sizeof(TCHAR));
|
|
|
|
int iLen = (int)file.GetLength();
|
|
|
|
BYTE *pBytes = file.Detach();
|
|
|
|
strText = (LPTSTR)pBytes;
|
|
|
|
free(pBytes);
|
|
|
|
return iLen;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetDropPos(int iRow, int iCol)
|
|
{
|
|
m_ptDropPos.y = iRow;
|
|
m_ptDropPos.x = iCol;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnShowWindow(BOOL bShow, UINT nStatus)
|
|
{
|
|
CWnd::OnShowWindow(bShow, nStatus);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
|
|
{
|
|
CWnd::OnActivate(nState, pWndOther, bMinimized);
|
|
|
|
SetActive(nState != WA_INACTIVE);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetActive(BOOL bIsActive)
|
|
{
|
|
m_bIsActive = bIsActive;
|
|
|
|
if (::IsWindow(m_hWnd))
|
|
{
|
|
RedrawWindow();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::HandleDrop(BOOL bCopy)
|
|
{
|
|
if (!CanEditDoc())
|
|
return;
|
|
|
|
if (!m_bRightButtonDrag)
|
|
CopyOrMoveText(bCopy);
|
|
else
|
|
{
|
|
CMenu menu;
|
|
menu.CreatePopupMenu();
|
|
|
|
CString csMenuText;
|
|
|
|
XTPResourceManager()->LoadString(&csMenuText, XTP_IDS_EDIT_MOVE_HERE);
|
|
menu.AppendMenu(MF_STRING, XTP_IDC_EDIT_DRAG_MOVE, csMenuText);
|
|
|
|
XTPResourceManager()->LoadString(&csMenuText, XTP_IDS_EDIT_COPY_HERE);
|
|
menu.AppendMenu(MF_STRING, XTP_IDC_EDIT_DRAG_COPY, csMenuText);
|
|
|
|
menu.AppendMenu(MF_SEPARATOR);
|
|
|
|
XTPResourceManager()->LoadString(&csMenuText, XTP_IDS_EDIT_CANCEL);
|
|
menu.AppendMenu(MF_STRING, IDCANCEL, csMenuText);
|
|
|
|
CPoint pt;
|
|
GetCursorPos(&pt);
|
|
|
|
int nID = menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD, pt.x, pt.y, this);
|
|
|
|
if (nID == XTP_IDC_EDIT_DRAG_MOVE || nID == XTP_IDC_EDIT_DRAG_COPY)
|
|
CopyOrMoveText(nID == XTP_IDC_EDIT_DRAG_COPY);
|
|
}
|
|
|
|
m_bRightButtonDrag = FALSE;
|
|
m_bDragging = FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ShowDefaultContextMenu()
|
|
{
|
|
CPoint ptCur;
|
|
GetCursorPos(&ptCur);
|
|
OnContextMenu(this, ptCur);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::EnableWhiteSpace(BOOL bShow)
|
|
{
|
|
m_pOptions->m_bEnableWhiteSpace = bShow;
|
|
|
|
InvalidateAll();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::EnableVirtualSpace(BOOL bEnable, BOOL bUpdateReg)
|
|
{
|
|
SetValueBool(XTP_EDIT_REG_VIRTUALSPACE, bEnable, m_pOptions->m_bVirtualSpace, bUpdateReg);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetCollapsibleNodes(BOOL bDrawNodes, BOOL bUpdateReg)
|
|
{
|
|
SetValueBool(XTP_EDIT_REG_COLLAPSIBLENODES, bDrawNodes, m_pOptions->m_bDrawNodes, bUpdateReg);
|
|
|
|
CalculateEditbarLength();
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, TRUE);
|
|
|
|
if (!GetCollapsibleNodes())
|
|
ExpandAll();
|
|
else
|
|
InvalidateAll();
|
|
}
|
|
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetTabWithSpace(BOOL bTabWithSpace, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_TABWITHSPACE, bTabWithSpace, m_pOptions->m_bTabWithSpace, bUpdateReg))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::NotifySelInit() const
|
|
{
|
|
NotifyParent(XTP_EDIT_NM_SELINIT);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetTabSize(int nTabSize, BOOL bUpdateReg)
|
|
{
|
|
if (!m_pBuffer->SetTabSize(nTabSize, bUpdateReg))
|
|
return FALSE;
|
|
|
|
m_pDrawTextProcessor->SetTabSize(nTabSize);
|
|
|
|
CString strText;
|
|
GetLineText(GetCurrentDocumentRow(), strText);
|
|
|
|
m_nDispCol = CalcDispCol(strText, m_nCurrentCol);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetTabSize() const
|
|
{
|
|
return m_pBuffer ? m_pBuffer->GetTabSize() : 4;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetSyntaxColor(BOOL bSyntaxColor, BOOL bUpdateReg)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_SYNTAXCOLOR, bSyntaxColor, m_pOptions->m_bSyntaxColor, bUpdateReg))
|
|
return FALSE;
|
|
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
m_pBuffer->EnableParser(bSyntaxColor);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::NotifyParent(UINT uCode) const
|
|
{
|
|
if (!m_pParentWnd)
|
|
return -1;
|
|
|
|
ASSERT_VALID(m_pParentWnd);
|
|
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
NMHDR hdr;
|
|
hdr.hwndFrom = m_hWnd;
|
|
hdr.code = uCode;
|
|
hdr.idFrom = GetDlgCtrlID();
|
|
|
|
return m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)hdr.idFrom, (LPARAM)&hdr);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
LRESULT CXTPSyntaxEditCtrl::NotifyMouseEvent(UINT uCode, UINT nFlags, const CPoint& point) const
|
|
{
|
|
UNREFERENCED_PARAMETER(nFlags);
|
|
|
|
ASSERT_VALID(GetParent());
|
|
|
|
if (::IsWindow(GetParent()->GetSafeHwnd()))
|
|
{
|
|
NMMOUSE hdrMouse;
|
|
::ZeroMemory(&hdrMouse, sizeof(hdrMouse));
|
|
|
|
hdrMouse.hdr.hwndFrom = m_hWnd;
|
|
hdrMouse.hdr.code = uCode;
|
|
hdrMouse.hdr.idFrom = GetDlgCtrlID();
|
|
hdrMouse.pt = point;
|
|
|
|
return GetParent()->SendMessage(WM_NOTIFY, (WPARAM)hdrMouse.hdr.idFrom,
|
|
(LPARAM)&hdrMouse);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetSelMargin(BOOL bSelMargin, BOOL bUpdateReg)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_SELMARGIN, bSelMargin, m_pOptions->m_bSelMargin, bUpdateReg))
|
|
return FALSE;
|
|
|
|
CalculateEditbarLength();
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetScrollBars(BOOL bHorzSBar, BOOL bVertSBar, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_HSCROLLBAR, bHorzSBar, m_bHorzScrollBar, bUpdateReg))
|
|
return FALSE;
|
|
|
|
if (!SetValueBool(XTP_EDIT_REG_VSCROLLBAR, bVertSBar, m_bVertScrollBar, bUpdateReg))
|
|
return FALSE;
|
|
|
|
DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_HSCROLL|WS_VSCROLL);
|
|
|
|
if (bHorzSBar && !IsCreateScrollbarOnParent())
|
|
dwStyle |= WS_HSCROLL;
|
|
|
|
if (bVertSBar && !IsCreateScrollbarOnParent())
|
|
dwStyle |= WS_VSCROLL;
|
|
|
|
EnableScrollBarCtrl(SB_HORZ, m_bHorzScrollBar);
|
|
EnableScrollBarCtrl(SB_VERT, m_bVertScrollBar);
|
|
|
|
::SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CanEditDoc() const
|
|
{
|
|
if(!m_hWnd)
|
|
return FALSE;
|
|
|
|
if (IsReadOnly())
|
|
return FALSE;
|
|
|
|
BOOL bCancel = (BOOL)NotifyParent(XTP_EDIT_NM_EDITCHANGING);
|
|
return !bCancel;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::NotifyEditChanged(int iRowFrom, int iRowTo, UINT nActions)
|
|
{
|
|
XTP_EDIT_NMHDR_EDITCHANGED sec;
|
|
|
|
sec.nmhdr.code = XTP_EDIT_NM_EDITCHANGED;
|
|
sec.nmhdr.hwndFrom = m_hWnd;
|
|
sec.nmhdr.idFrom = GetDlgCtrlID();
|
|
sec.nRowFrom = iRowFrom;
|
|
sec.nRowTo = iRowTo;
|
|
sec.nAction = nActions;
|
|
|
|
RefreshLineMarks(&sec);
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)sec.nmhdr.idFrom, (LPARAM)&sec);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::CreateInsertText(LPTSTR szText,
|
|
CString& strTextToIns,
|
|
int& iNewRow,
|
|
int& iNewCol,
|
|
int& iNewDispCol,
|
|
int& iEditRowFrom,
|
|
int& iEditRowTo,
|
|
int& iChainActionCount)
|
|
{
|
|
// As this function will always be called by OnChar
|
|
// We can assume szText will contain only one character
|
|
// or the CRLF
|
|
|
|
int nCurDocRow = GetCurrentDocumentRow();
|
|
CString strLineText;
|
|
GetLineText(nCurDocRow, strLineText);
|
|
|
|
int nLineLenC = (int)_tcsclen(strLineText);
|
|
|
|
BOOL bTextCRLF = m_pBuffer->IsTextCRLF(szText);
|
|
|
|
BOOL bProcess = TRUE;
|
|
|
|
if (!bTextCRLF)
|
|
{
|
|
if (szText[0] == _T('\t') && !GetTabWithSpace() &&
|
|
m_nCurrentCol > 1 && nLineLenC > 0)
|
|
{
|
|
int nAlign = (m_nDispCol-1) % GetTabSize();
|
|
iNewDispCol = m_nDispCol - nAlign + GetTabSize();
|
|
|
|
int nDispCol = CalcDispCol(strLineText, nLineLenC + 1);
|
|
int nCurCol = m_nCurrentCol;
|
|
|
|
if (nDispCol < m_nDispCol)
|
|
{
|
|
nCurCol = nLineLenC+1;
|
|
}
|
|
else
|
|
{
|
|
nDispCol = m_nDispCol;
|
|
}
|
|
|
|
int nCharsToCheck = nCurCol-1;
|
|
|
|
if (nCharsToCheck)
|
|
{
|
|
LPCTSTR pCheck = _tcsninc((LPCTSTR)strLineText, max(0, nCurCol - 1 - 1));
|
|
int nBlanks;
|
|
for (nBlanks = 0; pCheck && nBlanks < nCharsToCheck; nBlanks++)
|
|
{
|
|
if (!pCheck || *pCheck != _T(' '))
|
|
break;
|
|
|
|
pCheck = _tcsdec((LPCTSTR)strLineText, pCheck);
|
|
}
|
|
|
|
if (nBlanks > 0)
|
|
{
|
|
int nAdditionalTabs = 0;
|
|
int nDC = m_nDispCol - nBlanks;
|
|
nDC += GetTabSize() - nDC % GetTabSize();
|
|
for (; nDC < m_nDispCol; nDC += GetTabSize())
|
|
{
|
|
nAdditionalTabs++;
|
|
}
|
|
|
|
m_pBuffer->SetOverwriteFlag(FALSE);
|
|
|
|
nCurDocRow = GetCurrentDocumentRow();
|
|
|
|
//**----------------------
|
|
OnBeforeEditChanged(nCurDocRow, nCurCol - nBlanks);
|
|
|
|
m_pBuffer->DeleteText(nCurDocRow, nCurCol - nBlanks, nCurDocRow, nCurCol);
|
|
|
|
OnEditChanged(nCurDocRow, nCurCol - nBlanks, nCurDocRow, nCurCol, xtpEditActDelete);
|
|
//**----------------------
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_FORMAT);
|
|
|
|
m_nDispCol -= nBlanks;
|
|
m_nCurrentCol -= nBlanks;
|
|
|
|
iChainActionCount = 2;
|
|
|
|
GetLineText(nCurDocRow, strLineText);
|
|
nLineLenC = (int)_tcsclen(strLineText);
|
|
|
|
if (nAdditionalTabs)
|
|
{
|
|
strTextToIns += CString(_T('\t'), nAdditionalTabs);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//iNewDispCol = m_nDispCol + (szText[0] == 0x09 ? GetTabSize() : 1);
|
|
//iNewCol = m_nCurrentCol + (szText[0] == 0x09 ? (GetTabWithSpace() ? GetTabSize() : 1) : 1);
|
|
|
|
//if (GetAutoIndent() && m_nAutoIndentCol > 0)
|
|
//{
|
|
// strTextToIns += CString(_T('\t'), m_nInsertTabCount) +
|
|
// CString(_T(' '), m_nInsertSpaceCount);
|
|
// m_nDispCol = 1;
|
|
// m_nCurrentCol = 1;
|
|
//}
|
|
if (szText[0] == _T('\t'))
|
|
{
|
|
// Align to the next tab position
|
|
int nAlign = (m_nDispCol-1) % GetTabSize();
|
|
iNewDispCol = m_nDispCol - nAlign + GetTabSize();
|
|
|
|
if (GetTabWithSpace())
|
|
{
|
|
int spaceCnt = GetTabSize() - nAlign;
|
|
strTextToIns += CString(_T(' '), spaceCnt);
|
|
szText++; // Skip tab, spaces are displayed
|
|
|
|
iNewCol = m_nCurrentCol + spaceCnt;
|
|
}
|
|
else
|
|
iNewCol = m_nCurrentCol + 1;
|
|
}
|
|
else
|
|
{
|
|
#ifdef XTP_FIXED
|
|
iNewDispCol = m_nDispCol + ( isleadbyte( szText[0] ) ? 2 : 1 );
|
|
#else
|
|
iNewDispCol = m_nDispCol + 1;
|
|
#endif
|
|
iNewCol = m_nCurrentCol + 1;
|
|
}
|
|
|
|
if (GetAutoIndent() && m_nAutoIndentCol > 0)
|
|
{
|
|
if (GetTabWithSpace())
|
|
strTextToIns += CString(_T(' '), m_nInsertTabCount * GetTabSize());
|
|
else
|
|
strTextToIns += CString(_T('\t'), m_nInsertTabCount);
|
|
|
|
strTextToIns += CString(_T(' '), m_nInsertSpaceCount);
|
|
m_nDispCol = 1;
|
|
m_nCurrentCol = 1;
|
|
}
|
|
}
|
|
|
|
iNewRow = GetCurrentDocumentRow();
|
|
|
|
strTextToIns += szText;
|
|
|
|
m_nAutoIndentCol = 0;
|
|
m_nInsertTabCount = 0;
|
|
m_nInsertSpaceCount = 0;
|
|
}
|
|
else if (bTextCRLF)
|
|
{
|
|
// Enter pressed
|
|
nCurDocRow = GetCurrentDocumentRow();
|
|
|
|
iNewRow = nCurDocRow + 1;
|
|
iNewCol = iNewDispCol = 1;
|
|
|
|
iEditRowFrom = nCurDocRow;
|
|
|
|
iEditRowTo = iEditRowFrom + 1;
|
|
|
|
strTextToIns = szText;
|
|
|
|
if (!GetAutoIndent())
|
|
return TRUE;
|
|
|
|
BOOL bInsertMid = (m_nCurrentCol <= nLineLenC);
|
|
|
|
DoAutoIndentIfNeed(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (m_nAutoIndentCol > 0 && bInsertMid)
|
|
{
|
|
CString strTabs;
|
|
FillTabs(strTabs, m_nAutoIndentCol);
|
|
strTextToIns += strTabs;
|
|
|
|
iNewDispCol = m_nAutoIndentCol;
|
|
iNewCol = (int)_tcsclen(strTabs);
|
|
|
|
m_nAutoIndentCol = 0;
|
|
}
|
|
}
|
|
|
|
return bProcess;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::DoAutoIndentIfNeed(int nBaseDocRow, int nDispCol_prev)
|
|
{
|
|
if (!GetAutoIndent())
|
|
return;
|
|
|
|
m_nAutoIndentCol = 0;
|
|
|
|
if (nDispCol_prev == 1)
|
|
return;
|
|
|
|
CString strTempLineText;
|
|
BOOL bFound = FALSE;
|
|
|
|
GetLineText(nBaseDocRow, strTempLineText);
|
|
|
|
LPCTSTR pChar = (LPCTSTR)strTempLineText;
|
|
for (; pChar && *pChar; pChar = _tcsinc(pChar))
|
|
{
|
|
if (*pChar == _T('\t'))
|
|
{
|
|
m_nAutoIndentCol += (GetTabSize() - (m_nAutoIndentCol % GetTabSize()));
|
|
}
|
|
else if (*pChar == 0x20)
|
|
{
|
|
m_nAutoIndentCol++;
|
|
}
|
|
else
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bFound && nDispCol_prev > 1)
|
|
{
|
|
bFound = TRUE;
|
|
m_nAutoIndentCol = nDispCol_prev - 1;
|
|
}
|
|
|
|
if (nDispCol_prev > 1 && m_nAutoIndentCol > nDispCol_prev - 1)
|
|
m_nAutoIndentCol = nDispCol_prev - 1;
|
|
|
|
if (bFound)
|
|
{
|
|
m_nInsertTabCount = m_nAutoIndentCol / GetTabSize();
|
|
m_nInsertSpaceCount = m_nAutoIndentCol % GetTabSize();
|
|
|
|
m_nAutoIndentCol++;
|
|
}
|
|
else
|
|
{
|
|
m_nAutoIndentCol = 0;
|
|
m_nInsertTabCount = 0;
|
|
m_nInsertSpaceCount = 0;
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::FillTabs(CString &rstrTextToIns, int nDispColl)
|
|
{
|
|
int nTabsCount = GetTabWithSpace() ? 0 : (nDispColl-1) / GetTabSize();
|
|
int nSpaceCount = nDispColl - nTabsCount * GetTabSize() - 1;
|
|
|
|
if (nTabsCount)
|
|
{
|
|
CString strTabs(_T('\t'), nTabsCount);
|
|
rstrTextToIns += strTabs;
|
|
}
|
|
|
|
if (nSpaceCount)
|
|
{
|
|
CString strSpaces(_T(' '), nSpaceCount);
|
|
rstrTextToIns += strSpaces;
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::IsRowVisible(int iRow) const
|
|
{
|
|
if (iRow > GetRowCount() || iRow < 1)
|
|
return FALSE;
|
|
|
|
int iMaxRowInPage = GetRowPerPage();
|
|
|
|
return (iRow >= m_nTopRow && iRow <= (m_nTopRow + iMaxRowInPage));
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::LowercaseSelection()
|
|
{
|
|
return DoChangeSelectionCase(FALSE);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::UppercaseSelection()
|
|
{
|
|
return DoChangeSelectionCase(TRUE);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DoChangeSelectionCase(BOOL bUpper)
|
|
{
|
|
if (!m_pSelection->IsSelExist())
|
|
return FALSE;
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(TRUE);
|
|
|
|
int nRowStrat = m_pSelection->GetNormalStart_disp().nLine;
|
|
int nRowEnd = m_pSelection->GetNormalEnd_disp().nLine;
|
|
for (int nRow = nRowStrat; nRow <= nRowEnd; nRow++)
|
|
{
|
|
int nVisFrom = 0;
|
|
int nVisTo = INT_MAX;
|
|
|
|
if (m_pSelection->bBlockSelectionMode || nRow == nRowStrat)
|
|
nVisFrom = m_pSelection->GetNormalStart_disp().nCol;
|
|
|
|
if (m_pSelection->bBlockSelectionMode || nRow == nRowEnd)
|
|
nVisTo = m_pSelection->GetNormalEnd_disp().nCol;
|
|
|
|
m_pBuffer->ChangeCase(nRow, nVisFrom, nVisTo, bUpper);
|
|
}
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(XTP_IDS_EDIT_CASE);
|
|
|
|
InvalidateRows(nRowStrat, nRowEnd);
|
|
Invalidate(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::DoChangeSelectionTabify(BOOL bTabify)
|
|
{
|
|
if (!IsSelectionExist())
|
|
return FALSE;
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(TRUE);
|
|
|
|
int nRowStrat = m_pSelection->GetNormalStart_disp().nLine;
|
|
int nRowEnd = m_pSelection->GetNormalEnd_disp().nLine;
|
|
for (int nRow = nRowStrat; nRow <= nRowEnd; nRow++)
|
|
{
|
|
int nVisFrom = 0;
|
|
int nVisTo = INT_MAX;
|
|
|
|
if (m_pSelection->bBlockSelectionMode || nRow == nRowStrat)
|
|
nVisFrom = m_pSelection->GetNormalStart_disp().nCol;
|
|
|
|
if (m_pSelection->bBlockSelectionMode || nRow == nRowEnd)
|
|
nVisTo = m_pSelection->GetNormalEnd_disp().nCol;
|
|
|
|
m_pBuffer->ChangeTabification(nRow, nVisFrom, nVisTo, bTabify);
|
|
}
|
|
|
|
m_pBuffer->GetUndoRedoManager()->SetGroupInsertMode(FALSE);
|
|
m_pBuffer->GetUndoRedoManager()->SetLastCommandText(bTabify ? XTP_IDS_EDIT_TABIFY : XTP_IDS_EDIT_UNTABIFY);
|
|
|
|
InvalidateRows(nRowStrat, nRowEnd);
|
|
Invalidate(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::TabifySelection()
|
|
{
|
|
return DoChangeSelectionTabify(TRUE);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::UnTabifySelection()
|
|
{
|
|
return DoChangeSelectionTabify(FALSE);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetLineNumbers(BOOL bLineNumbers, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
if (m_pOptions->m_bLineNumbers == bLineNumbers)
|
|
return TRUE;
|
|
|
|
if (!SetValueBool(XTP_EDIT_REG_LINENUMBERS, bLineNumbers, m_pOptions->m_bLineNumbers, bUpdateReg))
|
|
return FALSE;
|
|
|
|
CalculateEditbarLength();
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, TRUE);
|
|
|
|
InvalidateAll();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CalculateEditbarLength(CDC* pDC)
|
|
{
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
int nPrvEditbarLength = m_nEditbarLength;
|
|
|
|
// gutter
|
|
m_nEditbarLength = GetSelMargin() ? m_nMarginLength : 0;
|
|
|
|
// line numbers
|
|
m_nLineNumLength = 0;
|
|
|
|
if (GetLineNumbers())
|
|
{
|
|
int nMaxPageRow = GetRowCount();
|
|
|
|
if (pDC && pDC->IsPrinting())
|
|
nMaxPageRow = GetTopRow() + GetRowPerPage();
|
|
|
|
int nRowNumLen = (nMaxPageRow > 9 ? (int)log10l(nMaxPageRow) : 0) + 1;
|
|
CString sLineNumberFormat(GetPaintManager()->m_sLineNumberFormat);
|
|
if (!sLineNumberFormat.IsEmpty())
|
|
{
|
|
sLineNumberFormat.Replace(_T("%"), _T(""));
|
|
sLineNumberFormat.Replace(_T("d"), _T(""));
|
|
nRowNumLen = max(_ttoi(sLineNumberFormat), nRowNumLen);
|
|
}
|
|
|
|
CWindowDC dc(NULL);
|
|
|
|
CXTPFontDC fontDC(&dc, GetPaintManager()->GetFontLineNumber());
|
|
|
|
TEXTMETRIC tm;
|
|
VERIFY(dc.GetTextMetrics(&tm));
|
|
|
|
m_nLineNumLength = (nRowNumLen + 1) * (tm.tmAveCharWidth) + 2;
|
|
m_nEditbarLength += m_nLineNumLength;
|
|
}
|
|
|
|
// collapsible nodes area
|
|
if (GetCollapsibleNodes())
|
|
{
|
|
m_nEditbarLength += m_nNodesWidth;
|
|
}
|
|
|
|
if (GetSelMargin() || GetLineNumbers() || GetCollapsibleNodes())
|
|
m_nEditbarLength += TEXT_LEFT_OFFSET;
|
|
|
|
// update window if necessary
|
|
if (nPrvEditbarLength != m_nEditbarLength && (!pDC || !pDC->IsPrinting()))
|
|
{
|
|
CRect rcText;
|
|
CalcEditRects(NULL, NULL, NULL, &rcText);
|
|
m_pDrawTextProcessor->SetTextRect(rcText);
|
|
|
|
_RecalcScrollBars();
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::AddRemoveBookmark(int nRow)
|
|
{
|
|
if (GetLineMarksManager())
|
|
{
|
|
GetLineMarksManager()->AddRemoveLineMark(nRow, xtpEditLMT_Bookmark);
|
|
}
|
|
|
|
RedrawLineMarks();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::AddRemoveBreakPoint(int nRow)
|
|
{
|
|
if (GetLineMarksManager())
|
|
{
|
|
GetLineMarksManager()->AddRemoveLineMark(nRow, xtpEditLMT_Breakpoint);
|
|
}
|
|
|
|
RedrawLineMarks();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CollapseExpandBlock(int nRow)
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (!pMgr)
|
|
return;
|
|
|
|
// nLineEnd: adjust also column, for example when collapsing to the string of lower length
|
|
int nLineEnd = m_nCurrentCol; //m_nDispCol;
|
|
|
|
if (pMgr->HasRowMark(nRow, xtpEditLMT_Collapsed))
|
|
{
|
|
// try expand
|
|
pMgr->DeleteLineMark(nRow, xtpEditLMT_Collapsed);
|
|
}
|
|
else
|
|
{
|
|
// try collapse
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
CXTPSyntaxEditRowsBlockArray arCoBlocks;
|
|
GetCollapsableBlocksInfo(nRow, arCoBlocks);
|
|
|
|
int nCount = (int)arCoBlocks.GetSize();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
|
|
if (coBlk.lcStart.nLine == nRow)
|
|
{
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
if (!pCoDrawBlk)
|
|
{
|
|
pCoDrawBlk = new XTP_EDIT_COLLAPSEDBLOCK;
|
|
if (!pCoDrawBlk)
|
|
{
|
|
return;
|
|
}
|
|
LMCoParam.SetPtr(pCoDrawBlk, XTPSECollapsedBlockDeleteFn);
|
|
}
|
|
pCoDrawBlk->collBlock = coBlk;
|
|
pMgr->SetLineMark(nRow, xtpEditLMT_Collapsed, &LMCoParam);
|
|
m_arCollapsedTextRows.SetAtGrow(m_nCollapsedTextRowsCount, nRow);
|
|
nLineEnd = min(nLineEnd, pCoDrawBlk->collBlock.lcEnd.nCol);
|
|
m_nCollapsedTextRowsCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetCurrentDocumentRow(nRow);
|
|
m_nDispCol = nLineEnd + 1;
|
|
SetCurCaretPos(nRow, m_nDispCol);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
RecalcScrollBars();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::DeleteBookmark(int nRow)
|
|
{
|
|
if (GetLineMarksManager())
|
|
{
|
|
GetLineMarksManager()->DeleteLineMark(nRow, xtpEditLMT_Bookmark);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::PrevBookmark()
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (!pMgr)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
int nRow = GetCurRow();
|
|
int nVisRow = GetCurrentVisibleRow();
|
|
|
|
int nPrevRow = nRow;
|
|
do {
|
|
pMgr->FindPrevLineMark(--nPrevRow, xtpEditLMT_Bookmark);
|
|
} while (nPrevRow > 0 && GetVisibleRow(nPrevRow) == nVisRow);
|
|
|
|
if (nPrevRow < 0)
|
|
{
|
|
POSITION posLast = pMgr->GetLastLineMark(xtpEditLMT_Bookmark);
|
|
XTP_EDIT_LMDATA* pData = pMgr->GetLineMarkAt(posLast, xtpEditLMT_Bookmark);
|
|
nPrevRow = pData ? pData->m_nRow : -1;
|
|
}
|
|
if (GetVisibleRow(nPrevRow) == nVisRow)
|
|
{
|
|
nPrevRow = -1;
|
|
}
|
|
|
|
if (nPrevRow >= 0)
|
|
{
|
|
SetCurPos(nPrevRow, 1);
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::NextBookmark()
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (!pMgr)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
int nRow = GetCurRow();
|
|
int nVisRow = GetCurrentVisibleRow();
|
|
|
|
// move down to the next bookmark after the current collapsed block area
|
|
int nNextRow = nRow;
|
|
do {
|
|
pMgr->FindNextLineMark(++nNextRow, xtpEditLMT_Bookmark);
|
|
} while (nNextRow > 0 && GetVisibleRow(nNextRow) == nVisRow);
|
|
|
|
if (nNextRow < 0)
|
|
{
|
|
// find first line mark
|
|
POSITION posFirst = pMgr->GetFirstLineMark(xtpEditLMT_Bookmark);
|
|
XTP_EDIT_LMDATA* pData = pMgr->GetNextLineMark(posFirst, xtpEditLMT_Bookmark);
|
|
nNextRow = pData ? pData->m_nRow : -1;
|
|
}
|
|
|
|
if (GetVisibleRow(nNextRow) == nVisRow)
|
|
{
|
|
nNextRow = -1;
|
|
}
|
|
|
|
if (nNextRow >= 0)
|
|
{
|
|
SetCurPos(nNextRow, 1);
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::HasRowMark(int nRow, const XTP_EDIT_LINEMARKTYPE& lmType,
|
|
XTP_EDIT_LMPARAM* pParam) const
|
|
{
|
|
if (GetLineMarksManager())
|
|
{
|
|
return GetLineMarksManager()->HasRowMark(nRow, lmType, pParam);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::DeleteBreakpoint(int nRow)
|
|
{
|
|
if (GetLineMarksManager())
|
|
{
|
|
GetLineMarksManager()->DeleteLineMark(nRow, xtpEditLMT_Breakpoint);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RefreshLineMarks(XTP_EDIT_NMHDR_EDITCHANGED* pEditChanged)
|
|
{
|
|
if (!GetLineMarksManager())
|
|
{
|
|
ASSERT(FALSE);
|
|
return ;
|
|
}
|
|
|
|
int eRefreshType = xtpEditLMRefresh_Unknown;
|
|
|
|
if (pEditChanged->nAction & XTP_EDIT_EDITACTION_DELETEROW)
|
|
{
|
|
eRefreshType = xtpEditLMRefresh_Delete;
|
|
}
|
|
else if (pEditChanged->nAction & XTP_EDIT_EDITACTION_INSERTROW)
|
|
{
|
|
eRefreshType = xtpEditLMRefresh_Insert;
|
|
|
|
if (pEditChanged->nAction & XTP_EDIT_EDITACTION_INSERTROW_NEW)
|
|
eRefreshType |= xtpEditLMRefresh_InsertAt0;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetLineMarksManager()->RefreshLineMarks(pEditChanged->nRowFrom,
|
|
pEditChanged->nRowTo, eRefreshType);
|
|
|
|
RedrawLineMarks();
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::InvalidateAll()
|
|
{
|
|
CView* pParentWnd = DYNAMIC_DOWNCAST(CView, m_pParentWnd);
|
|
|
|
if (pParentWnd != NULL && pParentWnd->GetDocument() != NULL)
|
|
{
|
|
pParentWnd->GetDocument()->UpdateAllViews(NULL, xtpEditHintInvalidate);
|
|
}
|
|
else
|
|
{
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RedrawLineMarks()
|
|
{
|
|
InvalidateAll();
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::HasBookmarks() const
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (pMgr)
|
|
{
|
|
int nCount = pMgr->GetCount(xtpEditLMT_Bookmark);
|
|
return nCount > 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::HasBreakpoints() const
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (pMgr)
|
|
{
|
|
int nCount = pMgr->GetCount(xtpEditLMT_Breakpoint);
|
|
return nCount > 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
CXTPSyntaxEditLineMarksManager* CXTPSyntaxEditCtrl::GetLineMarksManager() const
|
|
{
|
|
ASSERT(m_pBuffer);
|
|
return m_pBuffer ? m_pBuffer->GetLineMarksManager() : NULL;
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetModulePath()
|
|
{
|
|
TCHAR zsFileName[_MAX_PATH];
|
|
|
|
//DWORD dwRes = ::GetModuleFileName(NULL, zsFileName, _MAX_PATH);
|
|
DWORD dwRes = ::GetModuleFileName(AfxGetInstanceHandle(), zsFileName, _MAX_PATH);
|
|
|
|
ASSERT(dwRes);
|
|
|
|
CString csFilePath = zsFileName;
|
|
int nFLs = csFilePath.ReverseFind(_T('\\'));
|
|
if (nFLs > 0)
|
|
{
|
|
csFilePath.ReleaseBuffer(nFLs + 1);
|
|
}
|
|
|
|
return csFilePath;
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetDefaultCfgFilePath()
|
|
{
|
|
return m_strDefaultCfgFilePath;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::RefreshColors()
|
|
{
|
|
if (!::IsWindow(m_hWnd) || !m_hWnd)
|
|
return;
|
|
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
|
|
if (!m_pBuffer)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (GetSyntaxColor())
|
|
{
|
|
XTP_EDIT_LINECOL pos1_0 = {1, 0};
|
|
BOOL bParseInThread = m_pBuffer->GetLexParser()->GetSchemaOptions(
|
|
m_pBuffer->GetFileExt() )->m_bFirstParseInSeparateThread;
|
|
if (bParseInThread)
|
|
{
|
|
m_pBuffer->GetLexParser()->StartParseInThread(m_pBuffer, &pos1_0, NULL, 0, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CXTPSyntaxEditLexTextSchema* ptrTextSch = m_pBuffer->GetLexParser()->GetTextSchema();
|
|
if (ptrTextSch)
|
|
{
|
|
CXTPSyntaxEditTextIterator txtIter(m_pBuffer);
|
|
ptrTextSch->RunParseUpdate(TRUE, &txtIter, &pos1_0, NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GetLineMarksManager()->RemoveAll(xtpEditLMT_Collapsed);
|
|
}
|
|
|
|
// Load data into AC
|
|
SetAutoCompleteList();
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetConfigFile() const
|
|
{
|
|
if (!m_pBuffer)
|
|
return _T("");
|
|
|
|
return m_pBuffer->GetConfigFile();
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetConfigFile(LPCTSTR szPath, BOOL bConfigFileMode)
|
|
{
|
|
m_strDefaultCfgFilePath = szPath;
|
|
//m_bConfigFileMode = bConfigFileMode;
|
|
if (!bConfigFileMode)
|
|
{
|
|
m_bUseMonitor = FALSE;
|
|
m_bConfigFileMode = FALSE;
|
|
}
|
|
if (!m_pBuffer)
|
|
return FALSE;
|
|
|
|
if (m_bConfigFileMode && !FILEEXISTS_S(szPath))
|
|
return FALSE;
|
|
|
|
m_pBuffer->SetConfigFile(szPath);
|
|
return TRUE;
|
|
}
|
|
|
|
CString CXTPSyntaxEditCtrl::GetCurrentTheme() const
|
|
{
|
|
if (!m_pBuffer || !m_pBuffer->GetLexConfigurationManager() || !GetSyntaxColor())
|
|
{
|
|
static CString strEmpty;
|
|
return strEmpty;
|
|
}
|
|
return m_pBuffer->GetLexConfigurationManager()->GetCurrentTheme();
|
|
}
|
|
|
|
CStringArray& CXTPSyntaxEditCtrl::GetThemes()
|
|
{
|
|
if (!m_pBuffer || !m_pBuffer->GetLexConfigurationManager())
|
|
{
|
|
static CStringArray s_ar;
|
|
return s_ar;
|
|
}
|
|
return m_pBuffer->GetLexConfigurationManager()->GetThemeManager().GetThemes();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ApplyTheme(CString strTheme)
|
|
{
|
|
if (!m_pBuffer || !m_pBuffer->GetLexConfigurationManager() || !GetSyntaxColor())
|
|
{
|
|
return;
|
|
}
|
|
CXTPSyntaxEditLexTextSchema* ptrTextSch = m_pBuffer->GetLexParser()->GetTextSchema();
|
|
m_pBuffer->GetLexConfigurationManager()->SetTheme(strTheme, ptrTextSch);
|
|
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::OnBeforeEditChanged(int nRow, int nCol)
|
|
{
|
|
UNREFERENCED_PARAMETER(nRow); UNREFERENCED_PARAMETER(nCol);
|
|
|
|
if (GetSyntaxColor())
|
|
{
|
|
m_pBuffer->GetLexParser()->OnBeforeEditChanged();
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnEditChanged(const XTP_EDIT_LINECOL& LCFrom,
|
|
const XTP_EDIT_LINECOL& LCTo, int eEditAction)
|
|
{
|
|
OnEditChanged(LCFrom.nLine, LCFrom.nCol, LCTo.nLine, LCTo.nCol, eEditAction);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnEditChanged(int nRowFrom, int nColFrom,
|
|
int nRowTo, int nColTo, int eEditAction)
|
|
{
|
|
InvalidateRows(nRowFrom);
|
|
|
|
if (GetSyntaxColor())
|
|
{
|
|
XTP_EDIT_LINECOL posFrom = {nRowFrom, max(0, nColFrom-1) };
|
|
XTP_EDIT_LINECOL posTo = {nRowTo, max(0, nColTo-1) };
|
|
|
|
m_pBuffer->GetLexParser()->OnEditChanged(posFrom, posTo, eEditAction, m_pBuffer);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::NotifyParseEvent(XTP_NOTIFY_CODE code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// Notify the parent class that position has been changed
|
|
XTP_EDIT_NMHDR_PARSEEVENT pe;
|
|
|
|
// NMHDR codes
|
|
pe.nmhdr.code = XTP_EDIT_NM_PARSEEVENT;
|
|
pe.nmhdr.hwndFrom = m_hWnd;
|
|
pe.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// notification event code.
|
|
pe.code = code;
|
|
pe.wParam = wParam;
|
|
pe.lParam = lParam;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
return (BOOL)m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)pe.nmhdr.idFrom, (LPARAM)&pe);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnParseEvent(XTP_NOTIFY_CODE code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
NotifyParseEvent(code, wParam, lParam);
|
|
|
|
//-----------------------------------------------------------------------
|
|
int nRSFactor = 3;
|
|
int nAveRedrawTime = m_aveRedrawScreenTime.GetAverageValue(333);
|
|
int nUpdateTimeOut = max(1000, nAveRedrawTime * nRSFactor);
|
|
|
|
BOOL bRedraw = FALSE;
|
|
BOOL bRedrawTimeOut = TRUE;
|
|
|
|
if (code == xtpEditOnParserStarted)
|
|
{
|
|
DWORD dwTime = ::GetTickCount();
|
|
m_dwLastRedrawTime = dwTime;
|
|
}
|
|
else if (code == xtpEditOnTextBlockParsed)
|
|
{
|
|
CXTPSyntaxEditLexTextBlock* pTBended = (CXTPSyntaxEditLexTextBlock*)wParam;
|
|
|
|
DWORD dwTime = ::GetTickCount();
|
|
bRedrawTimeOut = labs(dwTime - m_dwLastRedrawTime) >= nUpdateTimeOut;
|
|
if (bRedrawTimeOut)
|
|
{
|
|
m_dwLastRedrawTime = dwTime;
|
|
}
|
|
|
|
if (pTBended)
|
|
{
|
|
int nDispMax = GetRowPerPage() - 1;
|
|
int nBottomRow = GetDocumentRow(nDispMax+5);
|
|
|
|
if (!(pTBended->m_PosStartLC.nLine > nBottomRow ||
|
|
pTBended->m_PosEndLC.nLine < m_nTopRow) )
|
|
{
|
|
bRedraw = TRUE;
|
|
}
|
|
|
|
ClearOnScreenSchCache(pTBended->m_PosStartLC.nLine);
|
|
}
|
|
}
|
|
else if (code == xtpEditOnParserEnded)
|
|
{
|
|
bRedraw = TRUE;
|
|
}
|
|
|
|
//-----------------------------
|
|
if (bRedraw)
|
|
{
|
|
KillTimer(TIMER_REDRAW_WHEN_PARSE);
|
|
|
|
if (bRedrawTimeOut)
|
|
{
|
|
Invalidate(FALSE);
|
|
UpdateWindow();
|
|
}
|
|
else
|
|
{
|
|
SetTimer(TIMER_REDRAW_WHEN_PARSE, nUpdateTimeOut*5, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Row / col functions
|
|
|
|
void CXTPSyntaxEditCtrl::SetTopRow(int nRow)
|
|
{
|
|
if (nRow < 1)
|
|
m_nTopRow = 1;
|
|
else if (nRow > GetRowCount())
|
|
m_nTopRow = max (1, GetRowCount());
|
|
else
|
|
m_nTopRow = max (1, nRow);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetCurRow() const
|
|
{
|
|
return GetCurrentDocumentRow();
|
|
}
|
|
|
|
|
|
void CXTPSyntaxEditCtrl::GoToRow(int iRow, BOOL bSelectRow/* = FALSE*/)
|
|
{
|
|
CString csLineText = GetLineText(iRow);
|
|
|
|
m_nCurrentCol = 1;
|
|
m_nDispCol = 1;
|
|
|
|
if (bSelectRow)
|
|
{
|
|
m_pSelection->Reset_disp(iRow, 1);
|
|
m_pSelection->SetEnd_disp(iRow+1, 1);
|
|
|
|
SetCurrentDocumentRow(iRow);
|
|
Invalidate(FALSE);
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, TRUE, TRUE);
|
|
//SetTimer(TIMER_SELECTION_ID, TIMER_SELECTION_TIME, NULL);
|
|
}
|
|
else
|
|
{
|
|
SetCurrentDocumentRow(iRow);
|
|
SetCurPos(iRow, 1);
|
|
}
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetCurrentVisibleRow()
|
|
{
|
|
return GetVisibleRow(GetCurrentDocumentRow());
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetCurrentDocumentRow() const
|
|
{
|
|
return m_nCurrentDocumentRow;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetCurrentDocumentRow(int nRow)
|
|
{
|
|
if (nRow > GetRowCount())
|
|
nRow = GetRowCount();
|
|
|
|
if (nRow < 1)
|
|
nRow = 1;
|
|
|
|
m_nCurrentDocumentRow = nRow;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetDocumentRow(int nVisibleRow)
|
|
{
|
|
return CalculateDocumentRow(m_nTopRow, nVisibleRow);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalculateDocumentRow(int nStartDocumentRow, int nRowDelta)
|
|
{
|
|
int nDocRow = nStartDocumentRow + nRowDelta - 1;
|
|
int nNextCollapsedRow = nStartDocumentRow - 1;
|
|
|
|
POSITION pos = GetLineMarksManager()->FindNextLineMark(nNextCollapsedRow, xtpEditLMT_Collapsed);
|
|
while (pos != NULL)
|
|
{
|
|
XTP_EDIT_LMDATA* pData = GetLineMarksManager()->GetNextLineMark(pos, xtpEditLMT_Collapsed);
|
|
if (pData && pData->m_nRow >= nNextCollapsedRow) // mark should be not within previous collapsed block
|
|
{
|
|
if (pData->m_nRow >= nDocRow) // finish if mark is greater then row to calculate for
|
|
break;
|
|
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)pData->m_Param.GetPtr();
|
|
if (!pCoDBlk)
|
|
continue;
|
|
|
|
int nHiddenRows = pCoDBlk->collBlock.lcEnd.nLine - pCoDBlk->collBlock.lcStart.nLine;
|
|
|
|
nDocRow += nHiddenRows;
|
|
nNextCollapsedRow = pData->m_nRow + nHiddenRows;
|
|
}
|
|
}
|
|
return nDocRow;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetVisibleRow(int nDocumentRow)
|
|
{
|
|
return CalculateVisibleRow(m_nTopRow, nDocumentRow);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::CalculateVisibleRow(int nStartDocumentRow, int nDocumentRow)
|
|
{
|
|
int nVisRow = nDocumentRow - nStartDocumentRow + 1;
|
|
int nNextCollapsedRow = nStartDocumentRow - 1;
|
|
const int nRowCount = GetRowCount();
|
|
|
|
POSITION pos = GetLineMarksManager()->FindNextLineMark(nNextCollapsedRow, xtpEditLMT_Collapsed);
|
|
while (pos != NULL)
|
|
{
|
|
XTP_EDIT_LMDATA* pData = GetLineMarksManager()->GetNextLineMark(pos, xtpEditLMT_Collapsed);
|
|
if (pData && pData->m_nRow >= nNextCollapsedRow) // mark should be not within previous collapsed block
|
|
{
|
|
if (pData->m_nRow >= nDocumentRow) // finish if mark is greater then row to calculate for
|
|
break;
|
|
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)pData->m_Param.GetPtr();
|
|
if (!pCoDBlk)
|
|
continue;
|
|
|
|
int nHiddenRows = min(nRowCount, pCoDBlk->collBlock.lcEnd.nLine) -
|
|
pCoDBlk->collBlock.lcStart.nLine;
|
|
|
|
nVisRow -= nHiddenRows;
|
|
nNextCollapsedRow = pData->m_nRow + nHiddenRows;
|
|
}
|
|
}
|
|
return max(nVisRow, 1);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::MoveCurrentVisibleRowUp(int nCount)
|
|
{
|
|
int nOldVisRow = GetCurrentVisibleRow();
|
|
int nOldDocRow = GetCurrentDocumentRow();
|
|
|
|
int nNewVisRow = nOldVisRow - nCount;
|
|
|
|
// do not shift a window up
|
|
if (nNewVisRow > 0)
|
|
{
|
|
SetCurrentDocumentRow(GetDocumentRow(nNewVisRow));
|
|
return nNewVisRow;
|
|
}
|
|
|
|
// find global visible row index
|
|
int nVisRow = CalculateVisibleRow(1, nOldDocRow);
|
|
int nTargetDocRow = CalculateDocumentRow(1, max(nVisRow - nCount, 1));
|
|
int nDocDiff = nOldDocRow - nTargetDocRow;
|
|
nDocDiff = min(nDocDiff, m_nTopRow - 1);
|
|
nOldDocRow -= nDocDiff;
|
|
m_nCurrentDocumentRow -= nDocDiff;
|
|
m_nTopRow -= nDocDiff;
|
|
|
|
nNewVisRow = nOldVisRow - nDocDiff + GetRowPerPage();
|
|
|
|
return GetCurrentVisibleRow();
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::MoveCurrentVisibleRowDown(int nCount)
|
|
{
|
|
int nOldRow = GetCurrentVisibleRow();
|
|
int nNewDocRow = min(GetDocumentRow(nOldRow + nCount), GetRowCount());
|
|
SetCurrentDocumentRow(nNewDocRow);
|
|
int nMaxVisRow = GetRowPerPage();
|
|
int nMaxDocRow = GetDocumentRow(nMaxVisRow);
|
|
if (nNewDocRow > nMaxDocRow)
|
|
{
|
|
m_nTopRow = max (1, GetDocumentRow(nCount + 1));
|
|
}
|
|
return GetCurrentVisibleRow();
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetRowPerPage() const
|
|
{
|
|
return m_pDrawTextProcessor->GetRowsCount(FALSE);
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetVisibleRowsCount(int nMaxDocRow)
|
|
{
|
|
if (nMaxDocRow < 0)
|
|
nMaxDocRow = GetRowCount();
|
|
|
|
int nVisRow = nMaxDocRow;
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (pMgr)
|
|
{
|
|
int nNextCollapsedRow = -1;
|
|
POSITION pos = pMgr->GetFirstLineMark(xtpEditLMT_Collapsed);
|
|
while (pos != NULL)
|
|
{
|
|
XTP_EDIT_LMDATA* pData = pMgr->GetNextLineMark(pos, xtpEditLMT_Collapsed);
|
|
if (pData && pData->m_nRow >= nNextCollapsedRow) // mark should be not within previous collapsed block
|
|
{
|
|
if (pData->m_nRow >= nMaxDocRow) // finish if mark is greater then row to calculate for
|
|
break;
|
|
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)pData->m_Param.GetPtr();
|
|
if (!pCoDBlk)
|
|
continue;
|
|
|
|
int nHiddenRows = pCoDBlk->collBlock.lcEnd.nLine - pCoDBlk->collBlock.lcStart.nLine;
|
|
|
|
nVisRow -= nHiddenRows;
|
|
nNextCollapsedRow = pData->m_nRow + nHiddenRows;
|
|
}
|
|
}
|
|
}
|
|
return nVisRow;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::ShiftCurrentVisibleRowUp(int nCount, BOOL bChangeCaret)
|
|
{
|
|
BOOL bChanged = FALSE;
|
|
if (m_nTopRow > 1)
|
|
{
|
|
int nOldTopRow = m_nTopRow;
|
|
int nDocRow = GetCurrentDocumentRow(); // store old document row
|
|
SetCurrentDocumentRow(GetDocumentRow(1)); // move to first visible row
|
|
MoveCurrentVisibleRowUp(nCount); // move nCount row up
|
|
// move to old document row
|
|
int nBottomDocRow = GetDocumentRow(GetRowPerPage());
|
|
if (bChangeCaret)
|
|
nDocRow = min(nDocRow, nBottomDocRow);
|
|
SetCurrentDocumentRow(nDocRow);
|
|
if (nDocRow > nBottomDocRow)
|
|
CWnd::HideCaret();
|
|
if (nOldTopRow != m_nTopRow)
|
|
bChanged = TRUE;
|
|
}
|
|
return bChanged;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::ShiftCurrentVisibleRowDown(int nCount, BOOL bChangeCaret)
|
|
{
|
|
BOOL bChanged = FALSE;
|
|
if (m_nTopRow < GetRowCount())
|
|
{
|
|
int nOldTopRow = m_nTopRow;
|
|
int nDocRow = GetCurrentDocumentRow();
|
|
int nLastVisRow = GetRowPerPage();
|
|
SetCurrentDocumentRow(GetDocumentRow(nLastVisRow));
|
|
MoveCurrentVisibleRowDown(nCount);
|
|
int nTopDocRow = GetDocumentRow(1);
|
|
if (bChangeCaret)
|
|
nDocRow = max(nDocRow, nTopDocRow);
|
|
SetCurrentDocumentRow(nDocRow);
|
|
if (nDocRow < nTopDocRow)
|
|
CWnd::HideCaret();
|
|
if (nOldTopRow != m_nTopRow)
|
|
bChanged = TRUE;
|
|
}
|
|
return bChanged;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetCollapsedBlockLen(int nStartRow, int& rnLen) const
|
|
{
|
|
rnLen = 0;
|
|
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
BOOL bIsCollapsed = HasRowMark(nStartRow, xtpEditLMT_Collapsed, &LMCoParam);
|
|
if (!bIsCollapsed)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
if (!pCoDBlk)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
rnLen = pCoDBlk->collBlock.lcEnd.nLine - pCoDBlk->collBlock.lcStart.nLine;
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Line text internal functions
|
|
|
|
CString CXTPSyntaxEditCtrl::GetLineText(int nRow, BOOL bAddCRLF, int iCRLFStyle) const
|
|
{
|
|
CString strResult;
|
|
GetLineText(nRow, strResult, bAddCRLF, iCRLFStyle);
|
|
|
|
return strResult;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::GetLineText(int nRow, CString& strBuffer, BOOL bAddCRLF, int iCRLFStyle) const
|
|
{
|
|
m_pBuffer->GetLineText(nRow, strBuffer, bAddCRLF, iCRLFStyle);
|
|
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
BOOL bIsCollapsed = HasRowMark(nRow, xtpEditLMT_Collapsed, &LMCoParam);
|
|
if (bIsCollapsed)
|
|
{
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
if (!pCoDBlk)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
if (strBuffer.GetLength() > pCoDBlk->collBlock.lcStart.nCol)
|
|
{
|
|
strBuffer.SetAt(pCoDBlk->collBlock.lcStart.nCol, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetAutoCompleteList()
|
|
{
|
|
CXTPSyntaxEditLexTokensDefArray arTokens;
|
|
m_pBuffer->GetLexParser()->GetTokensForAutoCompleate(arTokens, FALSE);
|
|
CXTPSyntaxEditACDataArray arrData;
|
|
|
|
CXTPSyntaxEditLexTokensDef TokenDef;
|
|
int nTokensDef = (int)arTokens.GetSize();
|
|
if (!nTokensDef)
|
|
return;
|
|
|
|
for (int nTokenDef = 0; nTokenDef < nTokensDef; nTokenDef++)
|
|
{
|
|
TokenDef = (arTokens.GetAt(nTokenDef));
|
|
int nTags = (int)TokenDef.m_arTokens.GetSize();
|
|
for (int nTag = 0; nTag < nTags; nTag++)
|
|
{
|
|
CString sDef = TokenDef.m_arTokens.GetAt(nTag);
|
|
arrData.Add(new XTP_EDIT_ACDATA(0, sDef));
|
|
//arrData.Add(new XTP_EDIT_ACDATA(0, TokenDef.m_arTokens.GetAt(nTag)));
|
|
}
|
|
|
|
int nDelims = (int)TokenDef.m_arStartSeps.GetSize();
|
|
int nDelim;
|
|
for (nDelim = 0; nDelim < nDelims; nDelim++)
|
|
{
|
|
if (m_pAutoComplete->m_strDelims.Find(TokenDef.m_arStartSeps.GetAt(nDelim)) < 0)
|
|
m_pAutoComplete->m_strDelims += TokenDef.m_arStartSeps.GetAt(nDelim);
|
|
}
|
|
|
|
nDelims = (int)TokenDef.m_arEndSeps.GetSize();
|
|
for (nDelim = 0; nDelim < nDelims; nDelim++)
|
|
{
|
|
if (m_pAutoComplete->m_strDelims.Find(TokenDef.m_arEndSeps.GetAt(nDelim)) < 0)
|
|
m_pAutoComplete->m_strDelims += TokenDef.m_arEndSeps.GetAt(nDelim);
|
|
}
|
|
|
|
}
|
|
|
|
m_pAutoComplete->SetList(arrData);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
if (m_pAutoComplete->IsActive())
|
|
{
|
|
switch (pMsg->message)
|
|
{
|
|
case WM_KEYDOWN:
|
|
case WM_KEYUP:
|
|
case WM_CHAR:
|
|
case WM_DEADCHAR:
|
|
{
|
|
m_pAutoComplete->SendMessage(
|
|
pMsg->message, pMsg->wParam, pMsg->lParam);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (pMsg->message == WM_KEYDOWN)
|
|
{
|
|
switch (pMsg->wParam)
|
|
{
|
|
case VK_SPACE:
|
|
case VK_PRIOR:
|
|
case VK_NEXT:
|
|
case VK_END:
|
|
case VK_HOME:
|
|
case VK_LEFT:
|
|
case VK_UP:
|
|
case VK_RIGHT:
|
|
case VK_DOWN:
|
|
case VK_SELECT:
|
|
case VK_PRINT:
|
|
case VK_EXECUTE:
|
|
case VK_SNAPSHOT:
|
|
case VK_INSERT:
|
|
case VK_DELETE:
|
|
case VK_HELP:
|
|
case VK_RETURN:
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
else if (IsEnabledEditAccelerators() &&
|
|
(pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN))
|
|
{
|
|
BOOL bAltKey = (::GetKeyState(VK_MENU) & KF_UP) != 0;
|
|
BOOL bCtrlKey = (::GetKeyState(VK_CONTROL) & KF_UP) != 0;
|
|
BOOL bShiftKey = (::GetKeyState(VK_SHIFT) & KF_UP) != 0;
|
|
|
|
BOOL bAlt = bAltKey && !bCtrlKey && !bShiftKey;
|
|
BOOL bCtrl = bCtrlKey && !bAltKey && !bShiftKey;
|
|
BOOL bShift = bShiftKey && !bAltKey && !bCtrlKey;
|
|
BOOL bCtrlShift = bCtrlKey && bShiftKey && !bAltKey;
|
|
|
|
BOOL bProcessed = TRUE;
|
|
|
|
if (bCtrlKey && pMsg->wParam == (BYTE)'X')
|
|
{
|
|
if (IsSelectionExist() && CanEditDoc())
|
|
Cut();
|
|
}
|
|
else if (bCtrl && pMsg->wParam == (BYTE)'C' ||
|
|
bCtrl && pMsg->wParam == VK_INSERT)
|
|
{
|
|
if (IsSelectionExist())
|
|
Copy();
|
|
}
|
|
else if (bCtrl && pMsg->wParam == (BYTE)'V' ||
|
|
bShift && pMsg->wParam == VK_INSERT)
|
|
{
|
|
if (CanEditDoc())
|
|
Paste();
|
|
}
|
|
else if (bAlt && pMsg->wParam == VK_BACK ||
|
|
bCtrl && pMsg->wParam == (BYTE)'Z')
|
|
{
|
|
if (CanUndo())
|
|
Undo();
|
|
}
|
|
else if (bCtrl && pMsg->wParam == (BYTE)'Y' ||
|
|
bCtrlShift && pMsg->wParam == (BYTE)'Z')
|
|
{
|
|
if (CanRedo())
|
|
Redo();
|
|
}
|
|
else if (bCtrl && pMsg->wParam == (BYTE)'A')
|
|
{
|
|
SelectAll();
|
|
}
|
|
else
|
|
{
|
|
bProcessed = FALSE;
|
|
}
|
|
|
|
if (bProcessed)
|
|
return TRUE;
|
|
}
|
|
|
|
return CWnd::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
if (m_pAutoComplete->IsActive())
|
|
{
|
|
return (BOOL)m_pAutoComplete->SendMessage(WM_MOUSEWHEEL,
|
|
MAKEWPARAM(nFlags, zDelta), MAKELPARAM(pt.x, pt.y));
|
|
|
|
//CXTPWindowRect rcWndAC(&m_wndAutoComplete);
|
|
//if (rcWndAC.PtInRect(pt))
|
|
// return (BOOL)m_pAutoComplete->SendMessage(WM_MOUSEWHEEL, MAKEWPARAM(nFlags, zDelta), MAKELPARAM(pt.x, pt.y));
|
|
//else
|
|
// m_pAutoComplete->Hide();
|
|
}
|
|
|
|
m_pToolTip->Hide();
|
|
|
|
if (zDelta < 0)
|
|
Scroll(0, m_nWheelScroll);
|
|
else
|
|
Scroll(0, -m_nWheelScroll);
|
|
|
|
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CollapseAll()
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (!pMgr)
|
|
return;
|
|
|
|
CWaitCursor _WC;
|
|
|
|
CXTPSyntaxEditRowsBlockArray arCoBlocks;
|
|
GetCollapsableBlocksInfo(-1, arCoBlocks);
|
|
|
|
for (int nRow = 0; nRow < GetRowCount(); nRow++)
|
|
{
|
|
XTP_EDIT_LMPARAM LMCoParam;
|
|
|
|
int toRemove = -1;
|
|
|
|
int nCount = (int)arCoBlocks.GetSize();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
|
|
if (coBlk.lcStart.nLine == nRow)
|
|
{
|
|
XTP_EDIT_COLLAPSEDBLOCK* pCoDrawBlk = (XTP_EDIT_COLLAPSEDBLOCK*)LMCoParam.GetPtr();
|
|
if (!pCoDrawBlk)
|
|
{
|
|
pCoDrawBlk = new XTP_EDIT_COLLAPSEDBLOCK;
|
|
if (!pCoDrawBlk)
|
|
{
|
|
return;
|
|
}
|
|
LMCoParam.SetPtr(pCoDrawBlk, XTPSECollapsedBlockDeleteFn);
|
|
}
|
|
pCoDrawBlk->collBlock = coBlk;
|
|
pMgr->SetLineMark(nRow, xtpEditLMT_Collapsed, &LMCoParam);
|
|
m_arCollapsedTextRows.SetAtGrow(m_nCollapsedTextRowsCount, nRow);
|
|
m_nCollapsedTextRowsCount++;
|
|
if (toRemove < 0)
|
|
toRemove = i;
|
|
}
|
|
}
|
|
if (toRemove >= 0)
|
|
arCoBlocks.RemoveAt(0, toRemove+1);
|
|
}
|
|
|
|
// refresh picture
|
|
SetCurCaretPos(GetCurrentDocumentRow(), 1);
|
|
|
|
UpdateWindow();
|
|
|
|
RecalcScrollBars();
|
|
|
|
UpdateScrollPos();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ExpandAll()
|
|
{
|
|
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
|
|
if (!pMgr)
|
|
return;
|
|
|
|
CWaitCursor _WC;
|
|
|
|
pMgr->RemoveAll(xtpEditLMT_Collapsed);
|
|
|
|
// refresh picture
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol);
|
|
|
|
if (::IsWindow(m_hWnd))
|
|
UpdateWindow();
|
|
|
|
RecalcScrollBars();
|
|
|
|
UpdateScrollPos();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::GetRowColors(int nTextRow, int nColFrom, int nColTo,
|
|
const XTP_EDIT_COLORVALUES& clrDefault,
|
|
CXTPSyntaxEditTextBlockList* rBlocks)
|
|
{
|
|
if (!GetSyntaxColor())
|
|
return;
|
|
|
|
CXTPSyntaxEditLexTextSchema* ptrTxtSch = m_pBuffer->GetLexParser()->GetTextSchema();
|
|
if (ptrTxtSch)
|
|
{
|
|
CXTPSyntaxEditLexTextBlock* pScreenSchFirstTB = GetOnScreenSch(nTextRow);
|
|
//CXTPSyntaxEditLexTextBlock* pScreenSchFirstTB = ptrTxtSch->GetBlocks();
|
|
if (pScreenSchFirstTB)
|
|
{
|
|
CXTPSyntaxEditTextIterator txtIter(GetEditBuffer());
|
|
|
|
ptrTxtSch->GetRowColors(&txtIter, nTextRow, nColFrom, nColTo,
|
|
clrDefault, rBlocks, NULL, pScreenSchFirstTB);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::GetCollapsableBlocksInfo(int nTextRow,
|
|
CXTPSyntaxEditRowsBlockArray& rarCoBlocks) const
|
|
{
|
|
rarCoBlocks.RemoveAll();
|
|
|
|
if (GetSyntaxColor())
|
|
{
|
|
CXTPSyntaxEditLexTextSchema* ptrTxtSch = m_pBuffer->GetLexParser()->GetTextSchema();
|
|
if (ptrTxtSch)
|
|
ptrTxtSch->GetCollapsableBlocksInfo(nTextRow, rarCoBlocks, &m_fcCollapsable->ptrTBStart);
|
|
}
|
|
}
|
|
|
|
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditCtrl::GetOnScreenSch(int nForRow)
|
|
{
|
|
int nLifeTime = m_pBuffer->GetLexParser()->GetSchemaOptions(
|
|
m_pBuffer->GetFileExt())->m_dwOnScreenSchCacheLifeTime_sec;
|
|
m_arOnScreenSchCache->RemoveOld(nLifeTime);
|
|
|
|
//========================================================================
|
|
int nCount = (int)m_arOnScreenSchCache->GetSize();
|
|
int i;
|
|
|
|
for (i = 0; i < nCount; i++)
|
|
{
|
|
CScreenSearchBlock& rSchBlk = m_arOnScreenSchCache->ElementAt(i);
|
|
|
|
if (nForRow >= rSchBlk.nRowStart && nForRow <= rSchBlk.nRowEnd)
|
|
{
|
|
rSchBlk.dwLastAccessTime = ::GetTickCount();
|
|
return rSchBlk.ptrTBFirst;
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
CXTPSyntaxEditLexTextSchema* ptrTxtSch = m_pBuffer->GetLexParser()->GetTextSchema();
|
|
if (ptrTxtSch)
|
|
{
|
|
int nRowPerPage = GetRowPerPage()+1;
|
|
|
|
CScreenSearchBlock schBlkNew;
|
|
schBlkNew.nRowStart = nForRow;
|
|
schBlkNew.nRowEnd = nForRow + nRowPerPage;
|
|
|
|
//--------------------------------------------------------------------
|
|
int nRowStartMin = 1;
|
|
// 1. search next on screen region
|
|
nCount = (int)m_arOnScreenSchCache->GetSize();
|
|
|
|
for (i = 0; i < nCount; i++)
|
|
{
|
|
const CScreenSearchBlock& rSchBlk = m_arOnScreenSchCache->ElementAt(i);
|
|
|
|
if (rSchBlk.nRowStart > schBlkNew.nRowStart && rSchBlk.nRowStart <= schBlkNew.nRowEnd)
|
|
{
|
|
schBlkNew.nRowEnd = rSchBlk.nRowStart-1;
|
|
}
|
|
|
|
if (rSchBlk.nRowEnd+1 > nRowStartMin && rSchBlk.nRowEnd+1 < nForRow)
|
|
{
|
|
nRowStartMin = rSchBlk.nRowEnd+1;
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------
|
|
// 2. search next collapsed block start
|
|
for (i = 0; i < m_nCollapsedTextRowsCount; i++)
|
|
{
|
|
int nCoStartRow = m_arCollapsedTextRows[i];
|
|
|
|
if (nCoStartRow >= schBlkNew.nRowStart && nCoStartRow < schBlkNew.nRowEnd)
|
|
{
|
|
schBlkNew.nRowEnd = nCoStartRow;
|
|
}
|
|
}
|
|
|
|
//===========================
|
|
if (schBlkNew.nRowEnd - schBlkNew.nRowStart < nRowPerPage/2)
|
|
{
|
|
schBlkNew.nRowStart = max(schBlkNew.nRowStart-nRowPerPage, nRowStartMin);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
CXTPSyntaxEditTextIterator txtIter(m_pBuffer);
|
|
|
|
BOOL bParseRes = ptrTxtSch->RunParseOnScreen(&txtIter, schBlkNew.nRowStart,
|
|
schBlkNew.nRowEnd, schBlkNew.ptrTBFirst);
|
|
if (bParseRes)
|
|
{
|
|
schBlkNew.dwLastAccessTime = ::GetTickCount();
|
|
|
|
m_arOnScreenSchCache->Add(schBlkNew);
|
|
return schBlkNew.ptrTBFirst;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::InvalidateRows(int nRowFrom, int nRowTo)
|
|
{
|
|
int nCountVDR = (int)m_arValidDispRows.GetSize();
|
|
|
|
//-* Invalidate ALL ------------------------------------------------------
|
|
if (nRowFrom < 0 && nRowTo < 0)
|
|
{
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
|
|
for (int i = 0; i < nCountVDR; i++) {
|
|
m_arValidDispRows.SetAtGrow(i, 0);
|
|
}
|
|
return ;
|
|
}
|
|
|
|
//-* Invalidate Part -----------------------------------------------------
|
|
int nRow1 = nRowFrom;
|
|
int nRow2 = nRowTo;
|
|
|
|
if (nRow1 < 0)
|
|
{
|
|
nRow1 = m_nTopRow;
|
|
}
|
|
if (nRow2 < nRow1)
|
|
{
|
|
nRow2 = GetDocumentRow(GetRowPerPage());
|
|
}
|
|
|
|
int nDispRow1= CalculateVisibleRow(m_nTopRow, nRow1);
|
|
int nDispRow2 = CalculateVisibleRow(m_nTopRow, nRow2);
|
|
|
|
int nI1 = max(min(nDispRow1, 1000), 0);
|
|
int nI2 = max(min(nDispRow2, 1000), nCountVDR-1);
|
|
for (int i = nI1; i <= nI2; i++)
|
|
{
|
|
m_arValidDispRows.SetAtGrow(i, 0);
|
|
}
|
|
|
|
//===========================================================================
|
|
ClearOnScreenSchCache(nRowFrom);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ClearOnScreenSchCache(int nRowFrom)
|
|
{
|
|
//-* clear ALL ------------------------------------------------------
|
|
if (nRowFrom < 0)
|
|
{
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
return ;
|
|
}
|
|
|
|
//===========================================================================
|
|
int nCountSSC = (int)m_arOnScreenSchCache->GetSize();
|
|
for (int i = nCountSSC-1; i >= 0; i--)
|
|
{
|
|
CScreenSearchBlock& rSchBlk = m_arOnScreenSchCache->ElementAt(i);
|
|
|
|
BOOL bRemove = FALSE;
|
|
|
|
if (nRowFrom >= rSchBlk.nRowStart && nRowFrom <= rSchBlk.nRowEnd)
|
|
{
|
|
rSchBlk.nRowEnd = nRowFrom-1;
|
|
bRemove = !(rSchBlk.nRowStart <= rSchBlk.nRowEnd);
|
|
}
|
|
else if (nRowFrom < rSchBlk.nRowStart)
|
|
{
|
|
bRemove = TRUE;
|
|
}
|
|
|
|
//-------------------------------------
|
|
if (bRemove)
|
|
{
|
|
m_arOnScreenSchCache->RemoveAt(i);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_arOnScreenSchCache->ElementAt(i).nRowStart == rSchBlk.nRowStart);
|
|
ASSERT(m_arOnScreenSchCache->ElementAt(i).nRowEnd == rSchBlk.nRowEnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetRowValid(int nDispRow)
|
|
{
|
|
ASSERT(nDispRow < 1000);
|
|
m_arValidDispRows.SetAtGrow(nDispRow, 1);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::IsRowValid(int nDispRow) const
|
|
{
|
|
int nCount = (int)m_arValidDispRows.GetSize();
|
|
|
|
if (nDispRow > 0 && nDispRow < nCount)
|
|
{
|
|
int nValid = m_arValidDispRows[nDispRow];
|
|
return (nValid != 0);
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
const CStringList& CXTPSyntaxEditCtrl::GetUndoTextList()
|
|
{
|
|
return m_pBuffer->GetUndoRedoManager()->GetUndoTextList();
|
|
}
|
|
|
|
const CStringList& CXTPSyntaxEditCtrl::GetRedoTextList()
|
|
{
|
|
return m_pBuffer->GetUndoRedoManager()->GetRedoTextList();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::OnLexCfgWasChanged(XTP_NOTIFY_CODE code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam);
|
|
|
|
if (code == xtpEditAllConfigWasChanged ||
|
|
code == xtpEditClassSchWasChanged ||
|
|
code == xtpEditThemeWasChanged)
|
|
{
|
|
m_arOnScreenSchCache->RemoveAll();
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetRowNodes(int nRow, DWORD& dwType) const
|
|
{
|
|
dwType = XTP_EDIT_ROWNODE_NOTHING;
|
|
|
|
// retrieve row nodes
|
|
CXTPSyntaxEditRowsBlockArray arCoBlocks;
|
|
GetCollapsableBlocksInfo(nRow, arCoBlocks);
|
|
|
|
int nCount = (int)arCoBlocks.GetSize();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
XTP_EDIT_ROWSBLOCK coBlk = arCoBlocks[i];
|
|
if (coBlk.lcStart.nLine == nRow)
|
|
{
|
|
if (HasRowMark(coBlk.lcStart.nLine, xtpEditLMT_Collapsed))
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_COLLAPSED;
|
|
}
|
|
else
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_EXPANDED;
|
|
}
|
|
}
|
|
if (coBlk.lcEnd.nLine == nRow)
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_ENDMARK;
|
|
}
|
|
if (coBlk.lcStart.nLine < nRow)
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_NODEUP;
|
|
}
|
|
if (coBlk.lcEnd.nLine > nRow && (dwType & XTP_EDIT_ROWNODE_COLLAPSED))
|
|
{
|
|
dwType |= XTP_EDIT_ROWNODE_NODEDOWN;
|
|
}
|
|
}
|
|
|
|
return (dwType != XTP_EDIT_ROWNODE_NOTHING);
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::NotifyMarginLBtnClick(int nRow, int nDispRow) const
|
|
{
|
|
// Notify the parent class that position has been changed
|
|
XTP_EDIT_NMHDR_MARGINCLICKED somc;
|
|
|
|
// NMHDR codes
|
|
somc.nmhdr.code = XTP_EDIT_NM_MARGINCLICKED;
|
|
somc.nmhdr.hwndFrom = m_hWnd;
|
|
somc.nmhdr.idFrom = GetDlgCtrlID();
|
|
|
|
// Row col specific codes
|
|
somc.nRow = nRow;
|
|
somc.nDispRow = nDispRow;
|
|
|
|
// Notify the parent window
|
|
if (::IsWindow(m_pParentWnd->GetSafeHwnd()))
|
|
{
|
|
return (BOOL)m_pParentWnd->SendMessage(
|
|
WM_NOTIFY, (WPARAM)somc.nmhdr.idFrom, (LPARAM)&somc);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
UINT CXTPSyntaxEditCtrl::CalcAveDataSize(int nRowStart, int nRowEnd)
|
|
{
|
|
UINT uSize = m_nAverageLineLen * abs(nRowStart - nRowEnd);
|
|
uSize = (uSize / 1024 + 1) * 1024;
|
|
return uSize;
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditCtrl::GetWideCaret() const
|
|
{
|
|
return m_pOptions->m_bWideCaret && m_pBuffer && m_pBuffer->GetOverwriteFlag();
|
|
}
|
|
|
|
CXTPSyntaxEditSelection& CXTPSyntaxEditCtrl::GetSelection()
|
|
{
|
|
return *m_pSelection;
|
|
}
|
|
|
|
CXTPSyntaxEditDrawTextProcessor& CXTPSyntaxEditCtrl::GetDrawTextProcessor()
|
|
{
|
|
return *m_pDrawTextProcessor;
|
|
}
|
|
|
|
|
|
BOOL CXTPSyntaxEditCtrl::SetWideCaret(BOOL bWideCaret, BOOL bUpdateReg/*=FALSE*/)
|
|
{
|
|
if (m_pOptions->m_bWideCaret != bWideCaret)
|
|
{
|
|
if (!SetValueBool(XTP_EDIT_REG_WIDECARET, bWideCaret, m_pOptions->m_bWideCaret, bUpdateReg))
|
|
return FALSE;
|
|
|
|
SetCurCaretPos(GetCurrentDocumentRow(), m_nDispCol, FALSE, FALSE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetPaintManager(CXTPSyntaxEditPaintManager* pPaintManager)
|
|
{
|
|
ASSERT(pPaintManager);
|
|
if (pPaintManager)
|
|
{
|
|
CMDTARGET_RELEASE(m_pPaintManeger);
|
|
m_pPaintManeger = pPaintManager;
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CTextSearchCache
|
|
//===========================================================================
|
|
|
|
CXTPSyntaxEditCtrl::CTextSearchCache::CTextSearchCache()
|
|
{
|
|
nForTopRow = 0;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CTextSearchCache::Update(int nCurrTopRow)
|
|
{
|
|
if (nCurrTopRow != nForTopRow)
|
|
{
|
|
ptrTBStart = NULL;
|
|
nForTopRow = nCurrTopRow;
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CScreenSearchBlock
|
|
//===========================================================================
|
|
|
|
CXTPSyntaxEditCtrl::CScreenSearchBlock::CScreenSearchBlock()
|
|
{
|
|
nRowStart = nRowEnd = 0;
|
|
dwLastAccessTime = 0;
|
|
}
|
|
|
|
CXTPSyntaxEditCtrl::CScreenSearchBlock::CScreenSearchBlock(const CScreenSearchBlock& rSrc)
|
|
{
|
|
nRowStart = rSrc.nRowStart;
|
|
nRowEnd = rSrc.nRowEnd;
|
|
ptrTBFirst = rSrc.ptrTBFirst;
|
|
dwLastAccessTime = rSrc.dwLastAccessTime;
|
|
}
|
|
|
|
CXTPSyntaxEditCtrl::CScreenSearchBlock::~CScreenSearchBlock()
|
|
{
|
|
|
|
}
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CScreenSearchCache
|
|
//===========================================================================
|
|
|
|
CXTPSyntaxEditCtrl::CScreenSearchCache::CScreenSearchCache()
|
|
{
|
|
m_dwLastRemoveOldTime = 0;
|
|
}
|
|
|
|
CXTPSyntaxEditCtrl::CScreenSearchCache::~CScreenSearchCache()
|
|
{
|
|
RemoveAll();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CScreenSearchCache::RemoveAll()
|
|
{
|
|
for (int i = 0; i < (int)GetSize(); i++)
|
|
{
|
|
CScreenSearchBlock& rSchBlk = ElementAt(i);
|
|
CXTPSyntaxEditLexTextSchema::Close(rSchBlk.ptrTBFirst);
|
|
}
|
|
Base::RemoveAll();
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CScreenSearchCache::RemoveAt(int nIndex)
|
|
{
|
|
CScreenSearchBlock& rSchBlk = ElementAt(nIndex);
|
|
|
|
CXTPSyntaxEditLexTextSchema::Close(rSchBlk.ptrTBFirst);
|
|
Base::RemoveAt(nIndex);
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CScreenSearchCache::RemoveOld(int nTimeOut_sec)
|
|
{
|
|
int nTimeOut_ms = nTimeOut_sec * 1000;
|
|
|
|
DWORD dwTime = ::GetTickCount();
|
|
|
|
int cnCheckTimeOut_ms = min(nTimeOut_sec, 10*1000);
|
|
|
|
if (nTimeOut_sec == 0 || nTimeOut_sec == -1 ||
|
|
labs(dwTime - m_dwLastRemoveOldTime) < cnCheckTimeOut_ms)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//================================================================
|
|
m_dwLastRemoveOldTime = dwTime;
|
|
for (int i = (int)GetSize() - 1; i >= 0; i--)
|
|
{
|
|
CScreenSearchBlock& rSchBlk = ElementAt(i);
|
|
|
|
if (labs(dwTime - rSchBlk.dwLastAccessTime) >= nTimeOut_ms)
|
|
{
|
|
CXTPSyntaxEditLexTextSchema::Close(rSchBlk.ptrTBFirst);
|
|
Base::RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
// CXTPSyntaxEditCtrl::CAverageVal
|
|
//===========================================================================
|
|
|
|
CXTPSyntaxEditCtrl::CAverageVal::CAverageVal(int nDataSize/* = 100*/)
|
|
{
|
|
m_nDataSize = max(1, nDataSize);
|
|
m_nNextIndex = 0;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::CAverageVal::AddValue(UINT uVal)
|
|
{
|
|
m_arData.SetAtGrow(m_nNextIndex, uVal);
|
|
m_nNextIndex = (m_nNextIndex+1) % m_nDataSize;
|
|
}
|
|
|
|
UINT CXTPSyntaxEditCtrl::CAverageVal::GetAverageValue(UINT uDefaultIfNoData/* = 0*/)
|
|
{
|
|
int nCount = (int)m_arData.GetSize();
|
|
if (nCount <= 0)
|
|
return uDefaultIfNoData;
|
|
|
|
UINT uSumm = 0;
|
|
for (int i = 0; i < nCount; i++)
|
|
uSumm += m_arData[i];
|
|
|
|
UINT uAveVal = uSumm / nCount;
|
|
|
|
return uAveVal;
|
|
}
|
|
|
|
int CXTPSyntaxEditCtrl::GetRowCount() const
|
|
{
|
|
return m_pBuffer ? m_pBuffer->GetRowCount() : 0;
|
|
}
|
|
|
|
CXTPSyntaxEditConfigurationManager* CXTPSyntaxEditCtrl::GetLexConfigurationManager() const
|
|
{
|
|
return m_pBuffer? m_pBuffer->GetLexConfigurationManager(): NULL;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ReloadSyntaxConfigFileMode()
|
|
{
|
|
CXTPSyntaxEditConfigurationManager* pMan = GetLexConfigurationManager();
|
|
if (pMan)
|
|
{
|
|
pMan->m_bConfigFileMode = TRUE;
|
|
pMan->m_bUseMonitor = TRUE;
|
|
pMan->m_sIniSet = _T("");
|
|
}
|
|
m_bUseMonitor = TRUE;
|
|
m_bConfigFileMode = TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::ReloadSyntaxStringMode()
|
|
{
|
|
if (GetEditBuffer())
|
|
{
|
|
if (m_sPassedIniSet.IsEmpty())
|
|
m_sIniSet = _T("[Schemes]\r\nCPP\r\n[Themes]\r\nDefault\r\nAlternative\r\n");
|
|
else
|
|
m_sIniSet = m_sPassedIniSet;
|
|
CXTPSyntaxEditConfigurationManager* pMan = GetLexConfigurationManager();
|
|
if (pMan)
|
|
{
|
|
pMan->m_bConfigFileMode = FALSE;
|
|
pMan->m_bUseMonitor = FALSE;
|
|
pMan->m_sIniSet = m_sIniSet;
|
|
}
|
|
m_bUseMonitor = FALSE;
|
|
m_bConfigFileMode = FALSE;
|
|
|
|
SetConfigFile(_T(""), FALSE);
|
|
}
|
|
}
|
|
|
|
void CXTPSyntaxEditCtrl::SetSyntaxAndColorScheme(CString sSyntaxScheme, CString sColorScheme,
|
|
BOOL bScheme /*FALSE*/, BOOL bColors /*FALSE*/)
|
|
{
|
|
if (!sSyntaxScheme.IsEmpty() && !sColorScheme.IsEmpty())
|
|
{
|
|
if (m_sPassedIniSet.IsEmpty())
|
|
m_sIniSet = _T("[Schemes]\r\nCPP\r\n[Themes]\r\nDefault\r\nAlternative\r\n");
|
|
else
|
|
m_sIniSet = m_sPassedIniSet;
|
|
m_strSyntaxScheme = sSyntaxScheme;
|
|
m_strColorScheme = sColorScheme;
|
|
|
|
if (bScheme)
|
|
{
|
|
CXTPSyntaxEditStringDlg dlg;
|
|
dlg.m_Syntax = m_strSyntaxScheme;
|
|
if (dlg.DoModal() == IDOK)
|
|
m_strSyntaxScheme = dlg.m_Syntax;
|
|
}
|
|
|
|
if (bColors)
|
|
{
|
|
CXTPSyntaxEditStringDlg dlg;
|
|
dlg.m_Syntax = m_strColorScheme;
|
|
if (dlg.DoModal() == IDOK)
|
|
m_strColorScheme = dlg.m_Syntax;
|
|
}
|
|
|
|
m_bUseMonitor = FALSE;
|
|
m_bConfigFileMode = FALSE;
|
|
CXTPSyntaxEditConfigurationManager* pMan = GetLexConfigurationManager();
|
|
if (pMan)
|
|
{
|
|
pMan->p_sSyntaxScheme = &m_strSyntaxScheme;
|
|
pMan->p_sColorScheme = &m_strColorScheme;
|
|
|
|
pMan->m_bConfigFileMode = FALSE;
|
|
pMan->m_bUseMonitor = FALSE;
|
|
pMan->m_sIniSet = m_sIniSet;
|
|
|
|
SetConfigFile(_T(""), FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef IDC_SYNTAX_EDIT
|
|
#define IDC_SYNTAX_EDIT 1009
|
|
#endif
|
|
// CXTPSyntaxEditStringDlg dialog
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPSyntaxEditStringDlg, CDialog)
|
|
|
|
CXTPSyntaxEditStringDlg::CXTPSyntaxEditStringDlg(CWnd* pParent) : CDialog()
|
|
{
|
|
UNREFERENCED_PARAMETER(pParent);
|
|
}
|
|
|
|
CXTPSyntaxEditStringDlg::~CXTPSyntaxEditStringDlg()
|
|
{
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
DDX_Control(pDX, IDC_SYNTAX_EDIT, m_edit);
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPSyntaxEditStringDlg, CDialog)
|
|
ON_WM_SIZE()
|
|
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
|
|
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
|
|
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
|
|
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CXTPSyntaxEditStringDlg::OnOK()
|
|
{
|
|
m_edit.GetWindowText(m_Syntax);
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
BOOL CXTPSyntaxEditStringDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_edit.SetWindowText(m_Syntax);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CDialog::OnSize(nType, cx, cy);
|
|
|
|
if (GetDlgItem(IDC_SYNTAX_EDIT))
|
|
{
|
|
int H = 35;
|
|
CRect rc;
|
|
CWnd* pWnd = GetDlgItem(IDC_SYNTAX_EDIT);
|
|
pWnd->MoveWindow(0, 0, cx, cy - H - 5);
|
|
|
|
pWnd = GetDlgItem(ID_EDIT_CUT);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
|
|
pWnd = GetDlgItem(ID_EDIT_COPY);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
|
|
pWnd = GetDlgItem(ID_EDIT_PASTE);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
|
|
pWnd = GetDlgItem(ID_EDIT_UNDO);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
|
|
pWnd = GetDlgItem(IDOK);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
|
|
pWnd = GetDlgItem(IDCANCEL);
|
|
pWnd->GetWindowRect(&rc);
|
|
ScreenToClient(&rc);
|
|
pWnd->MoveWindow(rc.left, cy - H, rc.Width(), rc.Height());
|
|
}
|
|
}
|
|
|
|
INT_PTR CXTPSyntaxEditStringDlg::DoModal()
|
|
{
|
|
BYTE DlgTempl[]=
|
|
{
|
|
0X01, 0X00, 0XFF, 0XFF, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X48, 0X00, 0XCC, 0X80,
|
|
0X07, 0X00, 0X00, 0X00, 0X00, 0X00, 0X78, 0X01, 0X2B, 0X01, 0X00, 0X00, 0X00, 0X00, 0X43, 0X00,
|
|
0X6F, 0X00, 0X6E, 0X00, 0X74, 0X00, 0X65, 0X00, 0X6E, 0X00, 0X74, 0X00, 0X20, 0X00, 0X65, 0X00,
|
|
0X64, 0X00, 0X69, 0X00, 0X74, 0X00, 0X6F, 0X00, 0X72, 0X00, 0X00, 0X00, 0X08, 0X00, 0X90, 0X01,
|
|
0X00, 0X01, 0X4D, 0X00, 0X53, 0X00, 0X20, 0X00, 0X53, 0X00, 0X68, 0X00, 0X65, 0X00, 0X6C, 0X00,
|
|
0X6C, 0X00, 0X20, 0X00, 0X44, 0X00, 0X6C, 0X00, 0X67, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X01, 0X00, 0X01, 0X50, 0X01, 0X01, 0X18, 0X01, 0X32, 0X00, 0X0E, 0X00,
|
|
0X01, 0X00, 0X00, 0X00, 0XFF, 0XFF, 0X80, 0X00, 0X4F, 0X00, 0X4B, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X50, 0X40, 0X01, 0X18, 0X01,
|
|
0X32, 0X00, 0X0E, 0X00, 0X02, 0X00, 0X00, 0X00, 0XFF, 0XFF, 0X80, 0X00, 0X43, 0X00, 0X61, 0X00,
|
|
0X6E, 0X00, 0X63, 0X00, 0X65, 0X00, 0X6C, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X84, 0X10, 0XB1, 0X50, 0X00, 0X00, 0X01, 0X00, 0X77, 0X01, 0X11, 0X01,
|
|
0XF1, 0X03, 0X00, 0X00, 0XFF, 0XFF, 0X81, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X50, 0X05, 0X00, 0X18, 0X01, 0X32, 0X00, 0X0E, 0X00,
|
|
0X23, 0XE1, 0X00, 0X00, 0XFF, 0XFF, 0X80, 0X00, 0X43, 0X00, 0X75, 0X00, 0X74, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X50,
|
|
0X44, 0X00, 0X18, 0X01, 0X32, 0X00, 0X0E, 0X00, 0X22, 0XE1, 0X00, 0X00, 0XFF, 0XFF, 0X80, 0X00,
|
|
0X43, 0X00, 0X6F, 0X00, 0X70, 0X00, 0X79, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X50, 0X83, 0X00, 0X18, 0X01, 0X32, 0X00, 0X0E, 0X00,
|
|
0X25, 0XE1, 0X00, 0X00, 0XFF, 0XFF, 0X80, 0X00, 0X50, 0X00, 0X61, 0X00, 0X73, 0X00, 0X74, 0X00,
|
|
0X65, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
|
|
0X00, 0X00, 0X01, 0X50, 0XC2, 0X00, 0X18, 0X01, 0X32, 0X00, 0X0E, 0X00, 0X2B, 0XE1, 0X00, 0X00,
|
|
0XFF, 0XFF, 0X80, 0X00, 0X55, 0X00, 0X6E, 0X00, 0X64, 0X00, 0X6F, 0X00, 0X00, 0X00, 0X00, 0X00};
|
|
InitModalIndirect((LPCDLGTEMPLATE)&DlgTempl, NULL);
|
|
|
|
return CDialog::DoModal();
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditCopy()
|
|
{
|
|
m_edit.Copy();
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditCut()
|
|
{
|
|
m_edit.Cut();
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditClear()
|
|
{
|
|
m_edit.Clear();
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditPaste()
|
|
{
|
|
m_edit.Paste();
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditSelectAll()
|
|
{
|
|
m_edit.SetSel(0, -1);
|
|
}
|
|
|
|
void CXTPSyntaxEditStringDlg::OnEditUndo()
|
|
{
|
|
m_edit.Undo();
|
|
}
|