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.

671 lines
19 KiB
C++

// XTPSyntaxEditUndoManager.cpp : implementation file
//
// 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"
// common includes
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPColorManager.h"
// syntax editor includes
#include "XTPSyntaxEditDefines.h"
#include "XTPSyntaxEditStruct.h"
#include "XTPSyntaxEditUndoManager.h"
#include "XTPSyntaxEditLexPtrs.h"
#include "XTPSyntaxEditLexParser.h"
#include "XTPSyntaxEditBufferManager.h"
#include "XTPSyntaxEditCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditUndoRedoManager::CXTPSyntaxEditUndoRedoManager()
{
m_posSavedMark = m_posFirstUndo = NULL;
//m_posSavedMark = BEFORE_START_POSITION;
m_bGroupInsertMode = FALSE;
m_nDataSizeLimit = 50 * 1024 * 1024;
}
CXTPSyntaxEditUndoRedoManager::~CXTPSyntaxEditUndoRedoManager()
{
Clear();
}
int CXTPSyntaxEditUndoRedoManager::DoUndo(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
int nRet = 0;
if (m_posFirstUndo != NULL)
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetAt(m_posFirstUndo);
if (pCmd != NULL)
{
nRet = pCmd->UnExecute(lcFrom, lcTo, pEditCtrl);
}
m_CommandList.GetPrev(m_posFirstUndo);
}
return nRet;
}
int CXTPSyntaxEditUndoRedoManager::DoRedo(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
int nRet = 0;
// get next item
if (m_posFirstUndo != NULL)
{
m_CommandList.GetNext(m_posFirstUndo);
}
else
{
m_posFirstUndo = m_CommandList.GetHeadPosition();
}
// do action
if (m_posFirstUndo != NULL)
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetAt(m_posFirstUndo);
if (pCmd != NULL)
{
nRet = pCmd->Execute(lcFrom, lcTo, pEditCtrl);
}
}
return nRet;
}
void CXTPSyntaxEditUndoRedoManager::RemoveTail()
{
// remove tail of the list
for (POSITION posTail = m_CommandList.GetTailPosition();
posTail != m_posFirstUndo;
posTail = m_CommandList.GetTailPosition())
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetTail();
m_CommandList.RemoveTail();
delete pCmd;
}
}
int CXTPSyntaxEditUndoRedoManager::GetDataSize() const
{
int nDataSize = 0;
POSITION pos = m_CommandList.GetHeadPosition();
while (pos)
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetNext(pos);
if (pCmd)
nDataSize += pCmd->GetDataSize();
}
return nDataSize;
}
void CXTPSyntaxEditUndoRedoManager::LimitDataSize(int nNewCommandData, int nDataSizeLimit)
{
int nDataSize = GetDataSize();
if (nDataSize + nNewCommandData < nDataSizeLimit)
return;
POSITION pos = m_CommandList.GetHeadPosition();
while (pos)
{
if (pos == m_posFirstUndo)
{
Clear();
return;
}
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetNext(pos);
if (pCmd)
nDataSize -= pCmd->GetDataSize();
if (nDataSize + nNewCommandData < nDataSizeLimit)
break;
}
}
void CXTPSyntaxEditUndoRedoManager::AddCommand(CXTPSyntaxEditCommand* pCommand)
{
RemoveTail();
LimitDataSize(pCommand->GetDataSize(), m_nDataSizeLimit);
// insert undo command
if (!m_bGroupInsertMode)
{
m_CommandList.AddTail(pCommand);
}
else
{
CXTPSyntaxEditCommand* pCmd = m_CommandList.GetTailPosition() ?
(CXTPSyntaxEditCommand*)m_CommandList.GetTail() : NULL;
CXTPSyntaxEditBatchCommand* pBatchCmd = DYNAMIC_DOWNCAST(CXTPSyntaxEditBatchCommand, pCmd);
if (!pBatchCmd)
{
pBatchCmd = new CXTPSyntaxEditBatchCommand();
m_CommandList.AddTail(pBatchCmd);
}
pBatchCmd->AddCommand(pCommand);
}
m_posFirstUndo = m_CommandList.GetTailPosition();
}
void CXTPSyntaxEditUndoRedoManager::Clear()
{
for (POSITION posTail = m_CommandList.GetTailPosition();
posTail != NULL;
posTail = m_CommandList.GetTailPosition())
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetTail();
m_CommandList.RemoveTail();
delete pCmd;
}
m_posFirstUndo = NULL;
}
BOOL CXTPSyntaxEditUndoRedoManager::CanUndo() const
{
if (m_posFirstUndo == NULL)
return FALSE;
return TRUE;
}
BOOL CXTPSyntaxEditUndoRedoManager::CanRedo() const
{
POSITION posLast = m_CommandList.GetTailPosition();
if (posLast == m_posFirstUndo)
return FALSE;
return TRUE;
}
void CXTPSyntaxEditUndoRedoManager::MarkSaved()
{
m_posSavedMark = m_posFirstUndo;
}
BOOL CXTPSyntaxEditUndoRedoManager::IsModified() const
{
return m_posSavedMark != m_posFirstUndo;
}
void CXTPSyntaxEditUndoRedoManager::SetGroupInsertMode(BOOL bInsertInGroup)
{
if (m_bGroupInsertMode == bInsertInGroup)
return;
m_bGroupInsertMode = bInsertInGroup;
if (m_bGroupInsertMode)
{
// add empty batch command
RemoveTail();
m_CommandList.AddTail(new CXTPSyntaxEditBatchCommand());
m_posFirstUndo = m_CommandList.GetTailPosition();
}
else
{
// delete empty batch command if necessary
CXTPSyntaxEditCommand* pCmd = m_CommandList.GetTailPosition() ?
(CXTPSyntaxEditCommand*)m_CommandList.GetTail() : NULL;
CXTPSyntaxEditBatchCommand* pBatchCmd = DYNAMIC_DOWNCAST(CXTPSyntaxEditBatchCommand, pCmd);
if (pBatchCmd && pBatchCmd->GetCommandsCount() < 1)
{
m_CommandList.RemoveTail();
delete pBatchCmd;
m_posFirstUndo = m_CommandList.GetTailPosition();
}
}
}
const CStringList& CXTPSyntaxEditUndoRedoManager::GetUndoTextList()
{
m_lstUndoText.RemoveAll();
// iterate all undo items
POSITION posHead = m_CommandList.GetHeadPosition();
do
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetAt(posHead);
if (pCmd)
{
m_lstUndoText.AddTail(pCmd->GetCommandText());
}
if (posHead == m_posFirstUndo)
break;
else
m_CommandList.GetNext(posHead);
}
while (posHead != NULL);
return m_lstUndoText;
}
const CStringList& CXTPSyntaxEditUndoRedoManager::GetRedoTextList()
{
m_lstRedoText.RemoveAll();
// iterate all redo items
for (POSITION posTail = m_CommandList.GetTailPosition();
posTail != m_posFirstUndo;
m_CommandList.GetPrev(posTail))
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetAt(posTail);
if (pCmd)
{
m_lstRedoText.AddHead(pCmd->GetCommandText());
}
}
return m_lstRedoText;
}
void CXTPSyntaxEditUndoRedoManager::ChainLastCommand()
{
POSITION posPrev = m_posFirstUndo;
// Take latest command and the previous, if any not exists - return
CXTPSyntaxEditCommand* pCmd = posPrev ?
(CXTPSyntaxEditCommand*)m_CommandList.GetPrev(posPrev) : NULL;
if (!pCmd || !posPrev)
return;
CXTPSyntaxEditCommand* pPrevCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetAt(posPrev);
if (!pPrevCmd)
return;
// Convert previous command to batch, or create new batch if not exist
CXTPSyntaxEditBatchCommand* pBatchCmd = DYNAMIC_DOWNCAST(CXTPSyntaxEditBatchCommand, pPrevCmd);
if (!pBatchCmd)
{
// Create batch command
pBatchCmd = new CXTPSyntaxEditBatchCommand();
// add previous command to the batch
pBatchCmd->AddCommand(pPrevCmd);
// reinsert batch command instead of usual previous command
m_CommandList.SetAt(posPrev, pBatchCmd);
}
pBatchCmd->AddCommand(pCmd);
// make previous batch command as latest undo position
m_CommandList.RemoveAt(m_posFirstUndo);
m_posFirstUndo = posPrev;
}
void CXTPSyntaxEditUndoRedoManager::SetLastCommandText(LPCTSTR szText)
{
// Take the latest command
CXTPSyntaxEditCommand* pCmd = m_posFirstUndo ?
(CXTPSyntaxEditCommand*)m_CommandList.GetAt(m_posFirstUndo) : NULL;
if (!pCmd)
return;
// Set its text
pCmd->SetCommandText(szText);
}
void CXTPSyntaxEditUndoRedoManager::SetLastCommandText(UINT nTextId)
{
// load text from resources
CString strText;
XTPResourceManager()->LoadString(&strText, nTextId);
// run text changing
SetLastCommandText(strText);
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditCommand, CObject)
CXTPSyntaxEditCommand::CXTPSyntaxEditCommand()
{
XTPResourceManager()->LoadString(&m_strCommandText, XTP_IDS_EDIT_UNDEFINED);
}
CXTPSyntaxEditCommand::~CXTPSyntaxEditCommand()
{
}
void CXTPSyntaxEditCommand::SetPositionInternally(CXTPSyntaxEditCtrl* pEditCtrl, const XTP_EDIT_LINECOL& lcPos)
{
if (pEditCtrl)
{
pEditCtrl->SetCurrentDocumentRow(lcPos.nLine);
pEditCtrl->m_nCurrentCol = lcPos.nCol;
}
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditBatchCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditBatchCommand, CXTPSyntaxEditCommand)
CXTPSyntaxEditBatchCommand::CXTPSyntaxEditBatchCommand()
{
XTPResourceManager()->LoadString(&m_strCommandText, XTP_IDS_EDIT_MULTIPLE);
}
CXTPSyntaxEditBatchCommand::~CXTPSyntaxEditBatchCommand()
{
Clear();
}
int CXTPSyntaxEditBatchCommand::Execute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
int nRet = 0;
lcFrom = XTP_EDIT_LINECOL::MAXPOS;
lcTo = XTP_EDIT_LINECOL::MINPOS;
POSITION posCmd = m_CommandList.GetTailPosition();
for ( int i = (int)m_CommandList.GetCount() - 1; i >= 0; i-- )
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetPrev(posCmd);
if (pCmd != NULL)
{
XTP_EDIT_LINECOL lcTmpFrom, lcTmpTo;
nRet |= pCmd->Execute(lcTmpFrom, lcTmpTo, pEditCtrl);
lcFrom = min(lcFrom, lcTmpFrom);
lcTo = max(lcTo, lcTmpTo);
}
}
return nRet;
}
int CXTPSyntaxEditBatchCommand::UnExecute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
int nRet = 0;
lcFrom = XTP_EDIT_LINECOL::MAXPOS;
lcTo = XTP_EDIT_LINECOL::MINPOS;
POSITION posCmd = m_CommandList.GetHeadPosition();
for ( int i = 0; i < m_CommandList.GetCount(); i++ )
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetNext(posCmd);
if (pCmd != NULL)
{
XTP_EDIT_LINECOL lcTmpFrom, lcTmpTo;
nRet |= pCmd->UnExecute(lcTmpFrom, lcTmpTo, pEditCtrl);
lcFrom = min(lcFrom, lcTmpFrom);
lcTo = max(lcTo, lcTmpTo);
}
}
return nRet;
}
POSITION CXTPSyntaxEditBatchCommand::AddCommand(CXTPSyntaxEditCommand* pCmd)
{
// insert command
return m_CommandList.AddHead(pCmd);
}
void CXTPSyntaxEditBatchCommand::Clear()
{
for ( POSITION posTail = m_CommandList.GetTailPosition();
posTail != NULL;
posTail = m_CommandList.GetTailPosition() )
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetTail();
m_CommandList.RemoveTail();
delete pCmd;
}
}
int CXTPSyntaxEditBatchCommand::GetCommandsCount()
{
return (int)m_CommandList.GetCount();
}
int CXTPSyntaxEditBatchCommand::GetDataSize() const
{
int nDataSize = 0;
POSITION pos = m_CommandList.GetHeadPosition();
while (pos)
{
CXTPSyntaxEditCommand* pCmd = (CXTPSyntaxEditCommand*)m_CommandList.GetNext(pos);
if (pCmd)
nDataSize += pCmd->GetDataSize();
}
return nDataSize;
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditBufferCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditBufferCommand, CXTPSyntaxEditCommand)
CXTPSyntaxEditBufferCommand::CXTPSyntaxEditBufferCommand(
CXTPSyntaxEditBufferManager* pMgr,
LPCTSTR szText, const XTP_EDIT_LINECOL& lcFrom, const XTP_EDIT_LINECOL& lcTo)
: m_pBufferMgr(pMgr), m_strText(szText), m_lcFrom(lcFrom), m_lcTo(lcTo)
{
}
CXTPSyntaxEditBufferCommand::~CXTPSyntaxEditBufferCommand()
{
}
CXTPSyntaxEditBufferCommand::CXTPSyntaxEditBufferKeepOverwriteSettings::CXTPSyntaxEditBufferKeepOverwriteSettings(CXTPSyntaxEditBufferManager* pBufferMgr)
: m_pBufMgr(pBufferMgr)
{
m_bOldSettings = m_pBufMgr ? m_pBufMgr->GetOverwriteFlag() : FALSE;
if (m_pBufMgr)
{
m_pBufMgr->SetOverwriteFlag(FALSE);
}
}
CXTPSyntaxEditBufferCommand::CXTPSyntaxEditBufferKeepOverwriteSettings::~CXTPSyntaxEditBufferKeepOverwriteSettings()
{
if (m_pBufMgr)
{
m_pBufMgr->SetOverwriteFlag(m_bOldSettings);
}
}
int CXTPSyntaxEditBufferCommand::DoDeleteText(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
if (!m_pBufferMgr)
return 0;
CXTPSyntaxEditBufferKeepOverwriteSettings bufOwr(m_pBufferMgr);
m_pBufferMgr->GetLexParser()->OnBeforeEditChanged();
// performs undoing operation
m_pBufferMgr->DeleteText(m_lcFrom.nLine, m_lcFrom.nCol, m_lcTo.nLine, m_lcTo.nCol, FALSE);
// send corresponding notification
m_pBufferMgr->GetLexParser()->OnEditChanged(m_lcFrom, m_lcTo, xtpEditActDelete, m_pBufferMgr);
// adjust cursor position
SetPositionInternally(pEditCtrl, m_lcFrom);
// calculate edit action
int nEditAction = XTP_EDIT_EDITACTION_DELETETEXT;
if (m_lcFrom.nLine != m_lcTo.nLine)
nEditAction |= XTP_EDIT_EDITACTION_DELETEROW | XTP_EDIT_EDITACTION_MODIFYROW;
else if (m_lcFrom.nCol != m_lcTo.nCol)
nEditAction |= XTP_EDIT_EDITACTION_MODIFYROW;
// set edit action bounds
lcFrom = min(m_lcFrom, m_lcTo);
lcTo = max(m_lcFrom, m_lcTo);
return nEditAction;
}
int CXTPSyntaxEditBufferCommand::DoInsertText(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
if (!m_pBufferMgr)
return 0;
// performs undoing operation
CXTPSyntaxEditBufferKeepOverwriteSettings bufOwr(m_pBufferMgr);
m_pBufferMgr->GetLexParser()->OnBeforeEditChanged();
m_pBufferMgr->InsertText(m_strText, m_lcFrom.nLine, m_lcFrom.nCol, FALSE);
// send corresponding notification
m_pBufferMgr->GetLexParser()->OnEditChanged(m_lcFrom, m_lcTo, xtpEditActInsert, m_pBufferMgr);
// adjust cursor position
SetPositionInternally(pEditCtrl, m_lcTo);
// calculate edit action
int nEditAction = XTP_EDIT_EDITACTION_INSERTTEXT;
if (m_lcFrom.nLine != m_lcTo.nLine)
nEditAction |= XTP_EDIT_EDITACTION_INSERTROW | XTP_EDIT_EDITACTION_MODIFYROW;
else if (m_lcFrom.nCol != m_lcTo.nCol)
nEditAction |= XTP_EDIT_EDITACTION_MODIFYROW;
// set edit action bounds
lcFrom = min(m_lcFrom, m_lcTo);
lcTo = max(m_lcFrom, m_lcTo);
return nEditAction;
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditDeleteStringCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditDeleteStringCommand, CXTPSyntaxEditBufferCommand)
CXTPSyntaxEditDeleteStringCommand::CXTPSyntaxEditDeleteStringCommand(
CXTPSyntaxEditBufferManager* pMgr,
LPCTSTR szText, const XTP_EDIT_LINECOL& lcFrom, const XTP_EDIT_LINECOL& lcTo)
: CXTPSyntaxEditBufferCommand(pMgr, szText, lcFrom, lcTo)
{
XTPResourceManager()->LoadString(&m_strCommandText, XTP_IDS_EDIT_DELETE);
m_strCommandText += m_strText;
}
CXTPSyntaxEditDeleteStringCommand::~CXTPSyntaxEditDeleteStringCommand()
{
}
int CXTPSyntaxEditDeleteStringCommand::Execute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
return DoDeleteText(lcFrom, lcTo, pEditCtrl);
}
int CXTPSyntaxEditDeleteStringCommand::UnExecute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
int nResult = DoInsertText(lcFrom, lcTo, pEditCtrl);
return nResult;
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditInsertStringCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditInsertStringCommand, CXTPSyntaxEditBufferCommand)
CXTPSyntaxEditInsertStringCommand::CXTPSyntaxEditInsertStringCommand(
CXTPSyntaxEditBufferManager* pMgr,
LPCTSTR szText, const XTP_EDIT_LINECOL& lcFrom, const XTP_EDIT_LINECOL& lcTo)
: CXTPSyntaxEditBufferCommand(pMgr, szText, lcFrom, lcTo)
{
XTPResourceManager()->LoadString(&m_strCommandText, XTP_IDS_EDIT_INSERT);
m_strCommandText += m_strText;
}
CXTPSyntaxEditInsertStringCommand::~CXTPSyntaxEditInsertStringCommand()
{
}
int CXTPSyntaxEditInsertStringCommand::Execute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
return DoInsertText(lcFrom, lcTo, pEditCtrl);
}
int CXTPSyntaxEditInsertStringCommand::UnExecute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
return DoDeleteText(lcFrom, lcTo, pEditCtrl);
}
//////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditReplaceStringCommand
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPSyntaxEditReplaceStringCommand, CXTPSyntaxEditBufferCommand)
CXTPSyntaxEditReplaceStringCommand::CXTPSyntaxEditReplaceStringCommand(
CXTPSyntaxEditBufferManager* pMgr,
LPCTSTR szText, LPCTSTR szReplacedText,
const XTP_EDIT_LINECOL& lcFrom, const XTP_EDIT_LINECOL& lcTo)
: CXTPSyntaxEditBufferCommand(pMgr, szText, lcFrom, lcTo), m_strReplacedText(szReplacedText)
{
XTPResourceManager()->LoadString(&m_strCommandText, XTP_IDS_EDIT_MULTIPLE);
m_strCommandText += m_strText;
}
CXTPSyntaxEditReplaceStringCommand::~CXTPSyntaxEditReplaceStringCommand()
{
}
int CXTPSyntaxEditReplaceStringCommand::Execute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
return DoReplaceText(m_strText, lcFrom, lcTo, pEditCtrl);
}
int CXTPSyntaxEditReplaceStringCommand::UnExecute(XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
return DoReplaceText(m_strReplacedText, lcFrom, lcTo, pEditCtrl);
}
int CXTPSyntaxEditReplaceStringCommand::DoReplaceText(LPCTSTR szText, XTP_EDIT_LINECOL& lcFrom, XTP_EDIT_LINECOL& lcTo, CXTPSyntaxEditCtrl* pEditCtrl)
{
if (!m_pBufferMgr)
return 0;
// performs undoing operation
CXTPSyntaxEditBufferKeepOverwriteSettings bufOwr(m_pBufferMgr);
m_pBufferMgr->SetOverwriteFlag(TRUE);
m_pBufferMgr->GetLexParser()->OnBeforeEditChanged();
XTP_EDIT_LINECOL lcBegin = min(m_lcFrom, m_lcTo);
m_pBufferMgr->InsertText(szText, lcBegin.nLine, lcBegin.nCol, FALSE);
// send corresponding notification
m_pBufferMgr->GetLexParser()->OnEditChanged(m_lcFrom, m_lcTo, xtpEditActInsert, m_pBufferMgr);
// adjust cursor position
SetPositionInternally(pEditCtrl, m_lcFrom);
// calculate edit action
int nEditAction = XTP_EDIT_EDITACTION_INSERTTEXT | XTP_EDIT_EDITACTION_DELETETEXT;
if (m_lcFrom.nLine != m_lcTo.nLine)
nEditAction |= XTP_EDIT_EDITACTION_INSERTROW | XTP_EDIT_EDITACTION_DELETEROW | XTP_EDIT_EDITACTION_MODIFYROW;
else if (m_lcFrom.nCol != m_lcTo.nCol)
nEditAction |= XTP_EDIT_EDITACTION_MODIFYROW;
// set edit action bounds
lcFrom = min(m_lcFrom, m_lcTo);
lcTo = max(m_lcFrom, m_lcTo);
return nEditAction;
}