blob: 72965bd20ce9c9fcdad4d1cdd428e3bca0e2be91 [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include <algorithm>
#include "xfa/src/foxitlib.h"
#include "xfa/src/fee/include/ifde_txtedtengine.h"
#include "xfa/src/fee/include/ifde_txtedtbuf.h"
#include "xfa/src/fee/include/ifde_txtedtpage.h"
#include "fde_txtedtengine.h"
#include "fde_txtedtparag.h"
#include "fde_txtedtbuf.h"
#ifdef FDE_USEFORMATBLOCK
#include "fde_txtedtblock.h"
#endif
#define FDE_PAGEWIDTH_MAX 0xFFFF
#define FDE_TXTPLATESIZE (1024 * 12)
#define FDE_UNICODE_PARAGRAPH_SPERATOR (0x2029)
#define FDE_TXTEDT_DORECORD_INS 0
#define FDE_TXTEDT_DORECORD_DEL 1
#ifdef FDE_USEFORMATBLOCK
#define FDE_TXTEDT_DORECORD_FORMATINS 3
#define FDE_TXTEDT_DORECORD_FORMATDEL 4
#define FDE_TXTEDT_DORECORD_FORMATREP 5
#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
#endif
IFDE_TxtEdtEngine* IFDE_TxtEdtEngine::Create() {
return new CFDE_TxtEdtEngine();
}
CFDE_TxtEdtEngine::CFDE_TxtEdtEngine()
: m_pTextBreak(nullptr),
m_nPageLineCount(20),
m_nLineCount(0),
m_nAnchorPos(-1),
m_nLayoutPos(0),
m_fCaretPosReserve(0.0),
m_nCaret(0),
m_bBefore(TRUE),
m_nCaretPage(0),
m_dwFindFlags(0),
m_bLock(FALSE),
m_nLimit(0),
m_wcAliasChar(L'*'),
#ifdef FDE_USEFORMATBLOCK
m_nFixLength(-1), // FIXME: no such member => USEFORMATBLOCK can't work.
#endif
m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto),
m_bAutoLineEnd(TRUE),
m_wLineEnd(FDE_UNICODE_PARAGRAPH_SPERATOR) {
FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF));
m_pTxtBuf = new CFDE_TxtEdtBuf();
m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
}
CFDE_TxtEdtEngine::~CFDE_TxtEdtEngine() {
if (m_pTxtBuf) {
m_pTxtBuf->Release();
m_pTxtBuf = NULL;
}
if (m_pTextBreak) {
m_pTextBreak->Release();
m_pTextBreak = NULL;
}
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount > 0) {
int32_t i = 0;
for (; i < nBlockCount; i++) {
CFDE_TxtEdtBlock* pBlock = m_BlockArray[i];
delete pBlock;
}
m_BlockArray.RemoveAll();
}
#endif
RemoveAllParags();
RemoveAllPages();
m_Param.pEventSink = NULL;
ClearSelection();
}
void CFDE_TxtEdtEngine::Release() {
delete this;
}
void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS& params) {
if (m_pTextBreak == NULL) {
m_pTextBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
}
FXSYS_memcpy(&m_Param, &params, sizeof(FDE_TXTEDTPARAMS));
m_wLineEnd = params.wLineBreakChar;
m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
UpdateTxtBreak();
}
const FDE_TXTEDTPARAMS* CFDE_TxtEdtEngine::GetEditParams() const {
return &m_Param;
}
int32_t CFDE_TxtEdtEngine::CountPages() const {
if (m_nLineCount == 0) {
return 0;
}
return ((m_nLineCount - 1) / m_nPageLineCount) + 1;
}
IFDE_TxtEdtPage* CFDE_TxtEdtEngine::GetPage(int32_t nIndex) {
if (m_PagePtrArray.GetSize() <= nIndex) {
return NULL;
}
return (IFDE_TxtEdtPage*)m_PagePtrArray[nIndex];
}
FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(int32_t nChunkSize) {
return m_pTxtBuf->SetChunkSize(nChunkSize);
}
void CFDE_TxtEdtEngine::SetTextByStream(IFX_Stream* pStream) {
ResetEngine();
int32_t nIndex = 0;
if (pStream != NULL && pStream->GetLength()) {
int32_t nStreamLength = pStream->GetLength();
FX_BOOL bValid = TRUE;
if (m_nLimit > 0 && nStreamLength > m_nLimit) {
bValid = FALSE;
}
FX_BOOL bPreIsCR = FALSE;
if (bValid) {
uint8_t bom[4];
int32_t nPos = pStream->GetBOM(bom);
pStream->Seek(FX_STREAMSEEK_Begin, nPos);
int32_t nPlateSize = std::min(nStreamLength, m_pTxtBuf->GetChunkSize());
FX_WCHAR* lpwstr = FX_Alloc(FX_WCHAR, nPlateSize);
FX_BOOL bEos = false;
while (!bEos) {
int32_t nRead = pStream->ReadString(lpwstr, nPlateSize, bEos);
bPreIsCR = ReplaceParagEnd(lpwstr, nRead, bPreIsCR);
m_pTxtBuf->Insert(nIndex, lpwstr, nRead);
nIndex += nRead;
}
FX_Free(lpwstr);
}
}
m_pTxtBuf->Insert(nIndex, &m_wLineEnd, 1);
RebuildParagraphs();
}
void CFDE_TxtEdtEngine::SetText(const CFX_WideString& wsText) {
ResetEngine();
int32_t nLength = wsText.GetLength();
if (nLength > 0) {
CFX_WideString wsTemp;
FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength);
FXSYS_memcpy(lpBuffer, wsText.c_str(), nLength * sizeof(FX_WCHAR));
ReplaceParagEnd(lpBuffer, nLength, FALSE);
wsTemp.ReleaseBuffer(nLength);
if (m_nLimit > 0 && nLength > m_nLimit) {
wsTemp.Delete(m_nLimit, nLength - m_nLimit);
nLength = m_nLimit;
}
m_pTxtBuf->SetText(wsTemp);
}
m_pTxtBuf->Insert(nLength, &m_wLineEnd, 1);
RebuildParagraphs();
}
int32_t CFDE_TxtEdtEngine::GetTextLength() const {
return GetTextBufLength();
}
void CFDE_TxtEdtEngine::GetText(CFX_WideString& wsText,
int32_t nStart,
int32_t nCount) {
int32_t nTextBufLength = GetTextBufLength();
if (nCount == -1) {
nCount = nTextBufLength - nStart;
}
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount == 0 || m_wsFixText.IsEmpty()) {
m_pTxtBuf->GetRange(wsText, nStart, nCount);
return;
}
CFX_WideString wsTemp;
const FX_WCHAR* lpFixBuffer = const FX_WCHAR * (m_wsFixText);
FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nTextBufLength);
int32_t nRealLength = 0;
int32_t nPrePos = 0;
for (int32_t i = 0; i < nBlockCount; i++) {
CFDE_TxtEdtBlock* pBlock = m_BlockArray[i];
int32_t nPos = pBlock->GetPos();
int32_t nCopyLength = nPos - nPrePos;
FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos,
nCopyLength * sizeof(FX_WCHAR));
nRealLength += nCopyLength;
nPrePos = nPos;
CFX_WideString wsBlock;
pBlock->GetRealText(wsBlock);
nCopyLength = wsBlock.GetLength();
FXSYS_memcpy(lpBuffer + nRealLength, const FX_WCHAR*(wsBlock),
nCopyLength * sizeof(FX_WCHAR));
nRealLength += nCopyLength;
}
int32_t nLeftLength = m_wsFixText.GetLength() - nPrePos;
if (nLeftLength > 0) {
FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos,
nLeftLength * sizeof(FX_WCHAR));
nRealLength += nLeftLength;
}
wsTemp.ReleaseBuffer(nRealLength);
int32_t nRealBgn = GetRealIndex(nStart);
int32_t nRealEnd = GetRealIndex(nStart + nCount - 1);
int32_t nRealCount = nRealEnd - nRealBgn;
FX_WCHAR* lpDestBuf = wsText.GetBuffer(nRealCount);
FXSYS_memcpy(lpDestBuf, const FX_WCHAR*(wsTemp) + nRealBgn,
nRealCount * sizeof(FX_WCHAR));
wsText.ReleaseBuffer();
#else
m_pTxtBuf->GetRange(wsText, nStart, nCount);
RecoverParagEnd(wsText);
#endif
}
void CFDE_TxtEdtEngine::ClearText() {
DeleteRange(0, -1);
}
int32_t CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret) const {
rtCaret = m_rtCaret;
return m_nCaret;
}
int32_t CFDE_TxtEdtEngine::GetCaretPos() const {
if (IsLocked()) {
return 0;
}
return m_nCaret + (m_bBefore ? 0 : 1);
}
int32_t CFDE_TxtEdtEngine::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
if (IsLocked()) {
return 0;
}
FXSYS_assert(nIndex >= 0 && nIndex <= GetTextBufLength());
if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
return 0;
}
#ifdef FDE_USEFORMATBLOCK
if (m_BlockArray.GetSize() > 0) {
nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_MIDDLE, bBefore);
}
#endif
m_bBefore = bBefore;
m_nCaret = nIndex;
MovePage2Char(m_nCaret);
GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
if (!m_bBefore) {
m_nCaret++;
m_bBefore = TRUE;
}
m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical)
? m_rtCaret.top
: m_rtCaret.left;
m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
m_nAnchorPos = -1;
return m_nCaret;
}
int32_t CFDE_TxtEdtEngine::MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret,
FX_BOOL bShift,
FX_BOOL bCtrl) {
if (IsLocked()) {
return 0;
}
if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
return 0;
}
FX_BOOL bSelChange = FALSE;
if (IsSelect()) {
ClearSelection();
bSelChange = TRUE;
}
if (bShift) {
if (m_nAnchorPos == -1) {
m_nAnchorPos = m_nCaret;
}
} else {
m_nAnchorPos = -1;
}
FX_BOOL bVertical = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
switch (eMoveCaret) {
case MC_Left: {
if (bVertical) {
CFX_PointF ptCaret;
if (MoveUp(ptCaret)) {
UpdateCaretIndex(ptCaret);
}
} else {
FX_BOOL bBefore = TRUE;
int32_t nIndex = MoveBackward(bBefore);
#ifdef FDE_USEFORMATBLOCK
if (m_BlockArray.GetSize()) {
nIndex =
NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore);
if (nIndex < 0) {
return m_nCaret;
}
}
#endif
if (nIndex >= 0) {
UpdateCaretRect(nIndex, bBefore);
}
}
} break;
case MC_Right: {
if (bVertical) {
CFX_PointF ptCaret;
if (MoveDown(ptCaret)) {
UpdateCaretIndex(ptCaret);
}
} else {
FX_BOOL bBefore = TRUE;
int32_t nIndex = MoveForward(bBefore);
#ifdef FDE_USEFORMATBLOCK
if (m_BlockArray.GetSize()) {
if (nIndex == -1) {
nIndex = GetTextBufLength();
}
nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore);
}
#endif
if (nIndex >= 0) {
UpdateCaretRect(nIndex, bBefore);
}
}
} break;
case MC_Up: {
if (bVertical) {
FX_BOOL bBefore = TRUE;
int32_t nIndex = MoveBackward(bBefore);
#ifdef FDE_USEFORMATBLOCK
if (m_BlockArray.GetSize()) {
nIndex =
NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore);
}
#endif
if (nIndex >= 0) {
UpdateCaretRect(nIndex, bBefore);
}
} else {
CFX_PointF ptCaret;
if (MoveUp(ptCaret)) {
UpdateCaretIndex(ptCaret);
}
}
} break;
case MC_Down: {
if (bVertical) {
FX_BOOL bBefore = TRUE;
int32_t nIndex = MoveForward(bBefore);
#ifdef FDE_USEFORMATBLOCK
if (m_BlockArray.GetSize()) {
nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore);
}
#endif
if (nIndex >= 0) {
UpdateCaretRect(nIndex, bBefore);
}
} else {
CFX_PointF ptCaret;
if (MoveDown(ptCaret)) {
UpdateCaretIndex(ptCaret);
}
}
} break;
case MC_WordBackward:
break;
case MC_WordForward:
break;
case MC_LineStart:
MoveLineStart();
break;
case MC_LineEnd:
MoveLineEnd();
break;
case MC_ParagStart:
MoveParagStart();
break;
case MC_ParagEnd:
MoveParagEnd();
break;
case MC_PageDown:
break;
case MC_PageUp:
break;
case MC_Home:
MoveHome();
break;
case MC_End:
MoveEnd();
break;
default:
break;
}
if (bShift && m_nAnchorPos != -1 && (m_nAnchorPos != m_nCaret)) {
AddSelRange(std::min(m_nAnchorPos, m_nCaret),
FXSYS_abs(m_nAnchorPos - m_nCaret));
m_Param.pEventSink->On_SelChanged(this);
}
if (bSelChange) {
m_Param.pEventSink->On_SelChanged(this);
}
return m_nCaret;
}
void CFDE_TxtEdtEngine::Lock() {
m_bLock = TRUE;
}
void CFDE_TxtEdtEngine::Unlock() {
m_bLock = FALSE;
}
FX_BOOL CFDE_TxtEdtEngine::IsLocked() const {
return m_bLock;
}
int32_t CFDE_TxtEdtEngine::Insert(int32_t nStart,
const FX_WCHAR* lpText,
int32_t nLength) {
if (IsLocked()) {
return FDE_TXTEDT_MODIFY_RET_F_Locked;
}
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount) {
if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_TAB && nLength == 1 &&
lpText[0] == L'\t') {
return Move2NextEditableField(nStart) ? FDE_TXTEDT_MODIFY_RET_T_Tab
: FDE_TXTEDT_MODIFY_RET_F_Tab;
}
int32_t nSelRangeCount = CountSelRanges();
if (nSelRangeCount > 0) {
if (nSelRangeCount > 1) {
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
}
int32_t nSelStart;
int32_t nSelCount;
nSelCount = GetSelRange(0, nSelStart);
int32_t nSelEnd = nSelStart + nSelCount;
int32_t nBgn = 0;
int32_t nEnd = 0;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField);
if (nSelEnd > nEnd) {
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
}
if (bInField) {
pField->Backup();
FX_BOOL bBefore = FALSE;
CFX_WideString wsDel;
int32_t nCaret;
int32_t nIndexInField = nSelStart - nBgn;
int32_t nRet = pField->Replace(nSelStart - nBgn, nSelCount,
CFX_WideStringC(lpText, nLength), wsDel,
nCaret, bBefore);
switch (nRet) {
case FDE_FORMAT_FIELD_INSERT_RET_F_FULL:
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Full;
case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE:
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
default:
break;
}
CFX_WideString wsField;
pField->GetFieldText(wsField);
if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(),
pField->GetIndex(), wsField,
0)) {
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
CFX_WideString wsDisplay;
pField->GetDisplayText(wsDisplay);
if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) ||
(m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
CFX_WideString wsText;
GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1,
const FX_WCHAR*(wsDisplay), wsDisplay.GetLength());
if (!IsFitArea(wsText)) {
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Full;
}
}
Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
int32_t nNewCaret = nBgn + nCaret;
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldReplace(
this, m_nCaret, nNewCaret, pField, nIndexInField, nBgn,
wsDisplay.GetLength(), wsDel, CFX_WideStringC(lpText, nLength),
TRUE);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
SetCaretPos(nBgn + nCaret, bBefore);
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
}
int32_t nBgn = 0;
int32_t nEnd = 0;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bInField = GetFieldBoundary(m_nCaret, nBgn, nEnd, pField);
int32_t nCaretInField = m_nCaret - nBgn;
FX_BOOL bBefore = FALSE;
if (bInField) {
pField->Backup();
CFX_WideStringC wsIns(lpText, nLength);
int32_t nRet =
pField->Insert(nCaretInField, wsIns, nCaretInField, bBefore);
FX_BOOL bFull = FALSE;
switch (nRet) {
case FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL:
break;
case FDE_FORMAT_FIELD_INSERT_RET_S_FULL:
bFull = TRUE;
break;
case FDE_FORMAT_FIELD_INSERT_RET_F_FULL:
return FDE_TXTEDT_MODIFY_RET_F_Full;
case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE:
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
default:
return FDE_TXTEDT_MODIFY_RET_F_Normal;
}
CFX_WideString wsField;
pField->GetFieldText(wsField);
if (!m_Param.pEventSink->On_ValidateField(
this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
CFX_WideString wsDisplay;
pField->GetDisplayText(wsDisplay);
if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) ||
(m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
CFX_WideString wsText;
GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1,
const FX_WCHAR*(wsDisplay), wsDisplay.GetLength());
if (!IsFitArea(wsText)) {
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Full;
}
}
Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldInsert(
this, m_nCaret, pField, m_nCaret - nBgn, nBgn, nEnd - nBgn + 1,
wsDisplay.GetLength(), CFX_WideStringC(lpText, nLength), FALSE);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
int32_t nCaretPos = nBgn + nCaretInField;
if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_AUTO && bFull &&
nCaretPos == nEnd) {
if (Move2NextEditableField(nEnd, TRUE, FALSE)) {
return TRUE;
}
}
SetCaretPos(nCaretPos, bBefore);
return bFull ? FDE_TXTEDT_MODIFY_RET_S_Full
: FDE_TXTEDT_MODIFY_RET_S_Normal;
}
FXSYS_assert(0);
return FDE_TXTEDT_MODIFY_RET_F_Normal;
}
#endif
CFX_WideString wsTemp;
FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength);
FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
ReplaceParagEnd(lpBuffer, nLength, FALSE);
wsTemp.ReleaseBuffer(nLength);
FX_BOOL bPart = FALSE;
if (m_nLimit > 0) {
int32_t nTotalLength = GetTextBufLength();
int32_t nCount = m_SelRangePtrArr.GetSize();
for (int32_t i = 0; i < nCount; i++) {
FDE_LPTXTEDTSELRANGE lpSelRange = m_SelRangePtrArr.GetAt(i);
nTotalLength -= lpSelRange->nCount;
}
int32_t nExpectLength = nTotalLength + nLength;
if (nTotalLength == m_nLimit) {
return FDE_TXTEDT_MODIFY_RET_F_Full;
}
if (nExpectLength > m_nLimit) {
nLength -= (nExpectLength - m_nLimit);
bPart = TRUE;
}
}
if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) ||
(m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
int32_t nTemp = nLength;
if (m_Param.dwMode & FDE_TEXTEDITMODE_Password) {
CFX_WideString wsText;
while (nLength > 0) {
GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
int32_t nTotal = wsText.GetLength();
FX_WCHAR* lpBuf = wsText.GetBuffer(nTotal);
for (int32_t i = 0; i < nTotal; i++) {
lpBuf[i] = m_wcAliasChar;
}
wsText.ReleaseBuffer(nTotal);
if (IsFitArea(wsText)) {
break;
}
nLength--;
}
} else {
CFX_WideString wsText;
while (nLength > 0) {
GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
if (IsFitArea(wsText)) {
break;
}
nLength--;
}
}
if (nLength == 0) {
return FDE_TXTEDT_MODIFY_RET_F_Full;
}
if (nLength < nTemp) {
bPart = TRUE;
}
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
CFX_WideString wsText;
GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
if (!m_Param.pEventSink->On_Validate(this, wsText)) {
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
}
if (IsSelect()) {
DeleteSelect();
}
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
IFDE_TxtEdtDoRecord* pRecord =
new CFDE_TxtEdtDoRecord_Insert(this, m_nCaret, lpBuffer, nLength);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
GetText(m_ChangeInfo.wsPrevText, 0);
Inner_Insert(m_nCaret, lpBuffer, nLength);
m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
m_ChangeInfo.wsInsert = CFX_WideString(lpBuffer, nLength);
nStart = m_nCaret;
nStart += nLength;
FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
FX_BOOL bBefore = TRUE;
if (wChar != L'\n' && wChar != L'\r') {
nStart--;
bBefore = FALSE;
}
SetCaretPos(nStart, bBefore);
m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
return bPart ? FDE_TXTEDT_MODIFY_RET_S_Part : FDE_TXTEDT_MODIFY_RET_S_Normal;
}
int32_t CFDE_TxtEdtEngine::Delete(int32_t nStart, FX_BOOL bBackspace) {
if (IsLocked()) {
return FDE_TXTEDT_MODIFY_RET_F_Locked;
}
if (IsSelect()) {
DeleteSelect();
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount > 0) {
if (bBackspace) {
nStart--;
}
int32_t nCount = 1;
int32_t nBgn = 0;
int32_t nEnd = 0;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bInField = GetFieldBoundary(nStart, nBgn, nEnd, pField);
int32_t nCaretInField = nStart - nBgn;
FX_BOOL bBefore = FALSE;
if (bInField && !pField->IsFix()) {
pField->Backup();
CFX_WideString wsDel;
int32_t nCaret = 0;
int32_t nRet =
pField->Delete(nCaretInField, nCount, wsDel, nCaret, bBefore);
nCaret += nBgn;
switch (nRet) {
case FDE_FORMAT_FIELD_DELETE_RET_S:
break;
case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE:
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY:
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
default:
FXSYS_assert(0);
break;
}
CFX_WideString wsField;
pField->GetFieldText(wsField);
if (!m_Param.pEventSink->On_ValidateField(
this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
pField->Restore();
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
CFX_WideString wsDisplay;
pField->GetDisplayText(wsDisplay);
Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldDelete(
this, nStart, pField, nCaretInField, nBgn, nEnd - nBgn + 1,
wsDisplay.GetLength(), wsDel, FALSE);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
SetCaretPos(nStart, bBefore);
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
}
#endif
int32_t nCount = 1;
if (bBackspace) {
if (nStart == 0) {
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
}
if (nStart > 2 && m_pTxtBuf->GetCharByIndex(nStart - 1) == L'\n' &&
m_pTxtBuf->GetCharByIndex(nStart - 2) == L'\r') {
nStart--;
nCount++;
}
nStart--;
} else {
if (nStart == GetTextBufLength()) {
return FDE_TXTEDT_MODIFY_RET_F_Full;
}
if ((nStart + 1 < GetTextBufLength()) &&
(m_pTxtBuf->GetCharByIndex(nStart) == L'\r') &&
(m_pTxtBuf->GetCharByIndex(nStart + 1) == L'\n')) {
nCount++;
}
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
CFX_WideString wsText;
GetPreDeleteText(wsText, nStart, nCount);
if (!m_Param.pEventSink->On_Validate(this, wsText)) {
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
}
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
CFX_WideString wsRange;
m_pTxtBuf->GetRange(wsRange, nStart, nCount);
IFDE_TxtEdtDoRecord* pRecord =
new CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, wsRange);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
GetText(m_ChangeInfo.wsDelete, nStart, nCount);
Inner_DeleteRange(nStart, nCount);
SetCaretPos(nStart + ((!bBackspace && nStart > 0) ? -1 : 0),
(bBackspace || nStart == 0));
m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
int32_t CFDE_TxtEdtEngine::DeleteRange(int32_t nStart, int32_t nCount) {
if (IsLocked()) {
return FDE_TXTEDT_MODIFY_RET_F_Locked;
}
if (nCount == -1) {
nCount = GetTextBufLength();
}
if (nCount == 0) {
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
CFX_WideString wsText;
GetPreDeleteText(wsText, nStart, nCount);
if (!m_Param.pEventSink->On_Validate(this, wsText)) {
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
}
DeleteRange_DoRecord(nStart, nCount);
m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
SetCaretPos(nStart, TRUE);
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
int32_t CFDE_TxtEdtEngine::Replace(int32_t nStart,
int32_t nLength,
const CFX_WideString& wsReplace) {
if (IsLocked()) {
return FDE_TXTEDT_MODIFY_RET_F_Locked;
}
if (nStart < 0 || (nStart + nLength > GetTextBufLength())) {
return FDE_TXTEDT_MODIFY_RET_F_Boundary;
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
CFX_WideString wsText;
GetPreReplaceText(wsText, nStart, nLength, wsReplace.c_str(),
wsReplace.GetLength());
if (!m_Param.pEventSink->On_Validate(this, wsText)) {
return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
}
}
if (IsSelect()) {
ClearSelection();
}
m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Replace;
GetText(m_ChangeInfo.wsDelete, nStart, nLength);
if (nLength > 0) {
Inner_DeleteRange(nStart, nLength);
}
int32_t nTextLength = wsReplace.GetLength();
if (nTextLength > 0) {
Inner_Insert(nStart, wsReplace.c_str(), nTextLength);
}
m_ChangeInfo.wsInsert = CFX_WideString(wsReplace.c_str(), nTextLength);
nStart += nTextLength;
FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
FX_BOOL bBefore = TRUE;
if (wChar != L'\n' && wChar != L'\r') {
nStart--;
bBefore = FALSE;
}
SetCaretPos(nStart, bBefore);
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
return FDE_TXTEDT_MODIFY_RET_S_Normal;
}
void CFDE_TxtEdtEngine::SetLimit(int32_t nLimit) {
m_nLimit = nLimit;
}
void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias) {
m_wcAliasChar = wcAlias;
}
void CFDE_TxtEdtEngine::SetFormatBlock(int32_t nIndex,
const CFX_WideString& wsBlockFormat) {
#ifdef FDE_USEFORMATBLOCK
if (m_nFixLength == -1) {
m_nFixLength = GetTextLength();
FXSYS_assert(m_wsFixText.IsEmpty());
GetText(m_wsFixText, 0, -1);
}
FX_BOOL bInBlock = FALSE;
int32_t nCharIndex = 0;
int32_t nBlockIndex = 0;
int32_t nBlockPos = -1;
FX_WCHAR wc;
CFDE_TxtEdtBufIter* pIter =
new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
pIter->SetAt(0);
do {
wc = pIter->GetChar();
if (bInBlock) {
if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
nBlockIndex++;
bInBlock = FALSE;
}
} else {
if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
bInBlock = TRUE;
} else {
if (nCharIndex++ == nIndex) {
nBlockPos = pIter->GetAt();
break;
}
}
}
} while (pIter->Next());
pIter->Release();
if (nBlockPos == -1) {
nBlockPos = GetTextBufLength();
}
CFDE_TxtEdtBlock* pEditBlock =
new CFDE_TxtEdtBlock(this, wsBlockFormat, nIndex);
m_BlockArray.InsertAt(m_BlockArray.GetSize(), pEditBlock);
CFX_WideString wsDisplay;
pEditBlock->GetDisplayText(wsDisplay);
m_nCaret = nBlockPos;
if (wsDisplay.GetLength() > 0) {
RawInsert(nBlockPos, const FX_WCHAR*(wsDisplay), wsDisplay.GetLength());
}
#endif
}
int32_t CFDE_TxtEdtEngine::CountEditBlocks() const {
#ifdef FDE_USEFORMATBLOCK
return m_BlockArray.GetSize();
#else
return 0;
#endif
}
void CFDE_TxtEdtEngine::GetEditBlockText(int32_t nIndex,
CFX_WideString& wsBlockText) const {
#ifdef FDE_USEFORMATBLOCK
CFDE_TxtEdtBlock* pBlock = m_BlockArray[nIndex];
pBlock->GetBlockText(wsBlockText);
#endif
}
int32_t CFDE_TxtEdtEngine::CountEditFields(int32_t nBlockIndex) const {
#ifdef FDE_USEFORMATBLOCK
CFDE_TxtEdtBlock* pBlock = m_BlockArray[nBlockIndex];
return pBlock->CountField();
#else
return 0;
#endif
}
void CFDE_TxtEdtEngine::GetEditFieldText(int32_t nBlockIndex,
int32_t nFieldIndex,
CFX_WideString& wsFieldText) const {
#ifdef FDE_USEFORMATBLOCK
CFDE_TxtEdtBlock* pBlock = m_BlockArray[nBlockIndex];
pBlock->GetFieldText(nFieldIndex, wsFieldText);
#endif
}
void CFDE_TxtEdtEngine::StartEdit() {
#ifdef FDE_USEFORMATBLOCK
#endif
}
void CFDE_TxtEdtEngine::EndEdit() {
#ifdef FDE_USEFORMATBLOCK
#endif
}
void CFDE_TxtEdtEngine::RemoveSelRange(int32_t nStart, int32_t nCount) {
FDE_LPTXTEDTSELRANGE lpTemp = NULL;
int32_t nRangeCount = m_SelRangePtrArr.GetSize();
int32_t i = 0;
for (i = 0; i < nRangeCount; i++) {
lpTemp = m_SelRangePtrArr[i];
if (lpTemp->nStart == nStart && lpTemp->nCount == nCount) {
delete lpTemp;
m_SelRangePtrArr.RemoveAt(i);
return;
}
}
}
void CFDE_TxtEdtEngine::AddSelRange(int32_t nStart, int32_t nCount) {
if (nCount == -1) {
nCount = GetTextLength() - nStart;
}
int32_t nSize = m_SelRangePtrArr.GetSize();
if (nSize <= 0) {
FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
lpSelRange->nStart = nStart;
lpSelRange->nCount = nCount;
m_SelRangePtrArr.Add(lpSelRange);
m_Param.pEventSink->On_SelChanged(this);
return;
}
FDE_LPTXTEDTSELRANGE lpTemp = NULL;
lpTemp = m_SelRangePtrArr[nSize - 1];
if (nStart >= lpTemp->nStart + lpTemp->nCount) {
FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
lpSelRange->nStart = nStart;
lpSelRange->nCount = nCount;
m_SelRangePtrArr.Add(lpSelRange);
m_Param.pEventSink->On_SelChanged(this);
return;
}
int32_t nEnd = nStart + nCount - 1;
FX_BOOL bBegin = FALSE;
int32_t nRangeBgn = 0;
int32_t nRangeCnt = 0;
for (int32_t i = 0; i < nSize; i++) {
lpTemp = m_SelRangePtrArr[i];
int32_t nTempBgn = lpTemp->nStart;
int32_t nTempEnd = nTempBgn + lpTemp->nCount - 1;
if (bBegin) {
if (nEnd < nTempBgn) {
break;
} else if (nStart >= nTempBgn && nStart <= nTempEnd) {
nRangeCnt++;
break;
}
nRangeCnt++;
} else {
if (nStart <= nTempEnd) {
nRangeBgn = i;
if (nEnd < nTempBgn) {
break;
}
nRangeCnt = 1;
bBegin = TRUE;
}
}
}
if (nRangeCnt == 0) {
FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
lpSelRange->nStart = nStart;
lpSelRange->nCount = nCount;
m_SelRangePtrArr.InsertAt(nRangeBgn, lpSelRange);
} else {
lpTemp = m_SelRangePtrArr[nRangeBgn];
lpTemp->nStart = nStart;
lpTemp->nCount = nCount;
nRangeCnt--;
nRangeBgn++;
while (nRangeCnt--) {
delete m_SelRangePtrArr[nRangeBgn];
m_SelRangePtrArr.RemoveAt(nRangeBgn);
}
}
m_Param.pEventSink->On_SelChanged(this);
}
int32_t CFDE_TxtEdtEngine::CountSelRanges() {
return m_SelRangePtrArr.GetSize();
}
int32_t CFDE_TxtEdtEngine::GetSelRange(int32_t nIndex, int32_t& nStart) {
nStart = m_SelRangePtrArr[nIndex]->nStart;
return m_SelRangePtrArr[nIndex]->nCount;
}
void CFDE_TxtEdtEngine::ClearSelection() {
int32_t nCount = m_SelRangePtrArr.GetSize();
FDE_LPTXTEDTSELRANGE lpRange = NULL;
int32_t i = 0;
for (i = 0; i < nCount; i++) {
lpRange = m_SelRangePtrArr[i];
if (lpRange != NULL) {
delete lpRange;
lpRange = NULL;
}
}
m_SelRangePtrArr.RemoveAll();
if (nCount && m_Param.pEventSink) {
m_Param.pEventSink->On_SelChanged(this);
}
}
FX_BOOL CFDE_TxtEdtEngine::Redo(const CFX_ByteStringC& bsRedo) {
if (IsLocked()) {
return FALSE;
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
return FALSE;
}
IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsRedo);
FXSYS_assert(pDoRecord);
if (pDoRecord == NULL) {
return FALSE;
}
FX_BOOL bOK = pDoRecord->Redo();
pDoRecord->Release();
return bOK;
}
FX_BOOL CFDE_TxtEdtEngine::Undo(const CFX_ByteStringC& bsUndo) {
if (IsLocked()) {
return FALSE;
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
return FALSE;
}
IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsUndo);
FXSYS_assert(pDoRecord);
if (pDoRecord == NULL) {
return FALSE;
}
FX_BOOL bOK = pDoRecord->Undo();
pDoRecord->Release();
return bOK;
}
int32_t CFDE_TxtEdtEngine::StartLayout() {
Lock();
RemoveAllPages();
m_nLayoutPos = 0;
m_nLineCount = 0;
return 0;
}
int32_t CFDE_TxtEdtEngine::DoLayout(IFX_Pause* pPause) {
int32_t nCount = m_ParagPtrArray.GetSize();
CFDE_TxtEdtParag* pParag = NULL;
int32_t nLineCount = 0;
for (; m_nLayoutPos < nCount; m_nLayoutPos++) {
pParag = m_ParagPtrArray[m_nLayoutPos];
pParag->CalcLines();
nLineCount += pParag->m_nLineCount;
if ((pPause != NULL) && (nLineCount > m_nPageLineCount) &&
pPause->NeedToPauseNow()) {
m_nLineCount += nLineCount;
return (++m_nLayoutPos * 100) / nCount;
}
}
m_nLineCount += nLineCount;
return 100;
}
void CFDE_TxtEdtEngine::EndLayout() {
UpdatePages();
int32_t nLength = GetTextLength();
if (m_nCaret > nLength) {
m_nCaret = nLength;
}
int32_t nIndex = m_nCaret;
if (!m_bBefore) {
nIndex--;
}
m_rtCaret.Set(0, 0, 1, m_Param.fFontSize);
Unlock();
}
FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause* pPause) {
return m_pTxtBuf->Optimize(pPause);
}
IFDE_TxtEdtBuf* CFDE_TxtEdtEngine::GetTextBuf() const {
return (IFDE_TxtEdtBuf*)m_pTxtBuf;
}
int32_t CFDE_TxtEdtEngine::GetTextBufLength() const {
return m_pTxtBuf->GetTextLength() - 1;
}
IFX_TxtBreak* CFDE_TxtEdtEngine::GetTextBreak() const {
return m_pTextBreak;
}
int32_t CFDE_TxtEdtEngine::GetLineCount() const {
return m_nLineCount;
}
int32_t CFDE_TxtEdtEngine::GetPageLineCount() const {
return m_nPageLineCount;
}
int32_t CFDE_TxtEdtEngine::CountParags() const {
return m_ParagPtrArray.GetSize();
}
IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const {
return m_ParagPtrArray[nParagIndex];
}
IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() {
if (!m_pTxtBuf) {
return NULL;
}
return new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
}
int32_t CFDE_TxtEdtEngine::Line2Parag(int32_t nStartParag,
int32_t nStartLineofParag,
int32_t nLineIndex,
int32_t& nStartLine) const {
int32_t nLineTotal = nStartLineofParag;
int32_t nCount = m_ParagPtrArray.GetSize();
CFDE_TxtEdtParag* pParag = NULL;
int32_t i = nStartParag;
for (; i < nCount; i++) {
pParag = m_ParagPtrArray[i];
nLineTotal += pParag->m_nLineCount;
if (nLineTotal > nLineIndex) {
break;
}
}
nStartLine = nLineTotal - pParag->m_nLineCount;
return i;
}
void CFDE_TxtEdtEngine::GetPreDeleteText(CFX_WideString& wsText,
int32_t nIndex,
int32_t nLength) {
GetText(wsText, 0, GetTextBufLength());
wsText.Delete(nIndex, nLength);
}
void CFDE_TxtEdtEngine::GetPreInsertText(CFX_WideString& wsText,
int32_t nIndex,
const FX_WCHAR* lpText,
int32_t nLength) {
GetText(wsText, 0, GetTextBufLength());
int32_t nSelIndex = 0;
int32_t nSelLength = 0;
int32_t nSelCount = CountSelRanges();
while (nSelCount--) {
nSelLength = GetSelRange(nSelCount, nSelIndex);
wsText.Delete(nSelIndex, nSelLength);
nIndex = nSelIndex;
}
CFX_WideString wsTemp;
int32_t nOldLength = wsText.GetLength();
const FX_WCHAR* pOldBuffer = wsText.c_str();
FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nOldLength + nLength);
FXSYS_memcpy(lpBuffer, pOldBuffer, (nIndex) * sizeof(FX_WCHAR));
FXSYS_memcpy(lpBuffer + nIndex, lpText, nLength * sizeof(FX_WCHAR));
FXSYS_memcpy(lpBuffer + nIndex + nLength, pOldBuffer + nIndex,
(nOldLength - nIndex) * sizeof(FX_WCHAR));
wsTemp.ReleaseBuffer(nOldLength + nLength);
wsText = wsTemp;
}
void CFDE_TxtEdtEngine::GetPreReplaceText(CFX_WideString& wsText,
int32_t nIndex,
int32_t nOriginLength,
const FX_WCHAR* lpText,
int32_t nLength) {
GetText(wsText, 0, GetTextBufLength());
int32_t nSelIndex = 0;
int32_t nSelLength = 0;
int32_t nSelCount = CountSelRanges();
while (nSelCount--) {
nSelLength = GetSelRange(nSelCount, nSelIndex);
wsText.Delete(nSelIndex, nSelLength);
}
wsText.Delete(nIndex, nOriginLength);
int32_t i = 0;
for (i = 0; i < nLength; i++) {
wsText.Insert(nIndex++, lpText[i]);
}
}
void CFDE_TxtEdtEngine::Inner_Insert(int32_t nStart,
const FX_WCHAR* lpText,
int32_t nLength) {
FXSYS_assert(nLength > 0);
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nStart, ParagPos);
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
int32_t nParagCount = m_ParagPtrArray.GetSize();
int32_t i = 0;
for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) {
m_ParagPtrArray[i]->m_nCharStart += nLength;
}
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
int32_t nReserveLineCount = pParag->m_nLineCount;
int32_t nReserveCharStart = pParag->m_nCharStart;
int32_t nLeavePart = ParagPos.nCharIndex;
int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex;
int32_t nTextStart = 0;
FX_WCHAR wCurChar = L' ';
const FX_WCHAR* lpPos = lpText;
FX_BOOL bFirst = TRUE;
int32_t nParagIndex = ParagPos.nParagIndex;
for (i = 0; i < nLength; i++, lpPos++) {
wCurChar = *lpPos;
if (wCurChar == m_wLineEnd) {
if (bFirst) {
pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1);
pParag->m_nLineCount = -1;
nReserveCharStart += pParag->m_nCharCount;
bFirst = FALSE;
} else {
pParag = new CFDE_TxtEdtParag(this);
pParag->m_nLineCount = -1;
pParag->m_nCharCount = i - nTextStart + 1;
pParag->m_nCharStart = nReserveCharStart;
m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
nReserveCharStart += pParag->m_nCharCount;
}
nTextStart = i + 1;
}
}
if (bFirst) {
pParag->m_nCharCount += nLength;
pParag->m_nLineCount = -1;
bFirst = FALSE;
} else {
pParag = new CFDE_TxtEdtParag(this);
pParag->m_nLineCount = -1;
pParag->m_nCharCount = nLength - nTextStart + nCutPart;
pParag->m_nCharStart = nReserveCharStart;
m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
}
m_pTxtBuf->Insert(nStart, lpText, nLength);
int32_t nTotalLineCount = 0;
for (i = ParagPos.nParagIndex; i <= nParagIndex; i++) {
pParag = m_ParagPtrArray[i];
pParag->CalcLines();
nTotalLineCount += pParag->m_nLineCount;
}
m_nLineCount += nTotalLineCount - nReserveLineCount;
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
UpdatePages();
}
#ifdef FDE_USEFORMATBLOCK
void CFDE_TxtEdtEngine::RawInsert(int32_t nStart,
const FX_WCHAR* lpText,
int32_t nLength) {
FXSYS_assert(nLength > 0);
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nStart, ParagPos);
int32_t nParagCount = m_ParagPtrArray.GetSize();
int32_t i = 0;
for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) {
m_ParagPtrArray[i]->m_nCharStart += nLength;
}
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
int32_t nReserveLineCount = pParag->m_nLineCount;
int32_t nReserveCharStart = pParag->m_nCharStart;
int32_t nLeavePart = ParagPos.nCharIndex;
int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex;
int32_t nTextStart = 0;
FX_WCHAR wCurChar = L' ';
const FX_WCHAR* lpPos = lpText;
FX_BOOL bFirst = TRUE;
int32_t nParagIndex = ParagPos.nParagIndex;
for (i = 0; i < nLength; i++, lpPos++) {
wCurChar = *lpPos;
if (wCurChar == m_wLineEnd) {
if (bFirst) {
pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1);
pParag->m_nLineCount = -1;
nReserveCharStart += pParag->m_nCharCount;
bFirst = FALSE;
} else {
pParag = new CFDE_TxtEdtParag(this);
pParag->m_nLineCount = -1;
pParag->m_nCharCount = i - nTextStart + 1;
pParag->m_nCharStart = nReserveCharStart;
m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
nReserveCharStart += pParag->m_nCharCount;
}
nTextStart = i + 1;
}
}
if (bFirst) {
pParag->m_nCharCount += nLength;
pParag->m_nLineCount = -1;
bFirst = FALSE;
} else {
pParag = new CFDE_TxtEdtParag(this);
pParag->m_nLineCount = -1;
pParag->m_nCharCount = nLength - nTextStart + nCutPart;
pParag->m_nCharStart = nReserveCharStart;
m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
}
m_pTxtBuf->Insert(nStart, lpText, nLength);
}
#endif
void CFDE_TxtEdtEngine::Inner_DeleteRange(int32_t nStart, int32_t nCount) {
if (nCount == -1) {
nCount = m_pTxtBuf->GetTextLength() - nStart;
}
int32_t nEnd = nStart + nCount - 1;
FXSYS_assert(nStart >= 0 && nEnd < m_pTxtBuf->GetTextLength());
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
FDE_TXTEDTPARAGPOS ParagPosBgn, ParagPosEnd;
TextPos2ParagPos(nStart, ParagPosBgn);
TextPos2ParagPos(nEnd, ParagPosEnd);
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPosEnd.nParagIndex];
FX_BOOL bLastParag = FALSE;
if (ParagPosEnd.nCharIndex == pParag->m_nCharCount - 1) {
if (ParagPosEnd.nParagIndex < m_ParagPtrArray.GetSize() - 1) {
ParagPosEnd.nParagIndex++;
} else {
bLastParag = TRUE;
}
}
int32_t nTotalLineCount = 0;
int32_t nTotalCharCount = 0;
int32_t i = 0;
for (i = ParagPosBgn.nParagIndex; i <= ParagPosEnd.nParagIndex; i++) {
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i];
pParag->CalcLines();
nTotalLineCount += pParag->m_nLineCount;
nTotalCharCount += pParag->m_nCharCount;
}
m_pTxtBuf->Delete(nStart, nCount);
int32_t nNextParagIndex = (ParagPosBgn.nCharIndex == 0 && bLastParag)
? ParagPosBgn.nParagIndex
: (ParagPosBgn.nParagIndex + 1);
for (i = nNextParagIndex; i <= ParagPosEnd.nParagIndex; i++) {
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nNextParagIndex];
delete pParag;
m_ParagPtrArray.RemoveAt(nNextParagIndex);
}
if (!(bLastParag && ParagPosBgn.nCharIndex == 0)) {
pParag = m_ParagPtrArray[ParagPosBgn.nParagIndex];
pParag->m_nCharCount = nTotalCharCount - nCount;
pParag->CalcLines();
nTotalLineCount -= pParag->m_nLineCount;
}
int32_t nParagCount = m_ParagPtrArray.GetSize();
for (i = nNextParagIndex; i < nParagCount; i++) {
m_ParagPtrArray[i]->m_nCharStart -= nCount;
}
m_nLineCount -= nTotalLineCount;
UpdatePages();
int32_t nPageCount = CountPages();
if (m_nCaretPage >= nPageCount) {
m_nCaretPage = nPageCount - 1;
}
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
}
void CFDE_TxtEdtEngine::DeleteRange_DoRecord(int32_t nStart,
int32_t nCount,
FX_BOOL bSel) {
FXSYS_assert(nStart >= 0);
if (nCount == -1) {
nCount = GetTextLength() - nStart;
}
FXSYS_assert((nStart + nCount) <= m_pTxtBuf->GetTextLength());
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount > 0) {
}
#endif
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
CFX_WideString wsRange;
m_pTxtBuf->GetRange(wsRange, nStart, nCount);
IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_DeleteRange(
this, nStart, m_nCaret, wsRange, bSel);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
GetText(m_ChangeInfo.wsDelete, nStart, nCount);
Inner_DeleteRange(nStart, nCount);
}
void CFDE_TxtEdtEngine::ResetEngine() {
RemoveAllPages();
RemoveAllParags();
ClearSelection();
m_nCaret = 0;
m_pTxtBuf->Clear(FALSE);
m_nCaret = 0;
}
void CFDE_TxtEdtEngine::RebuildParagraphs() {
RemoveAllParags();
FX_WCHAR wChar = L' ';
int32_t nParagStart = 0;
int32_t nIndex = 0;
IFX_CharIter* pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
pIter->SetAt(0);
do {
wChar = pIter->GetChar();
nIndex = pIter->GetAt();
if (wChar == m_wLineEnd) {
CFDE_TxtEdtParag* pParag = new CFDE_TxtEdtParag(this);
pParag->m_nCharStart = nParagStart;
pParag->m_nCharCount = nIndex - nParagStart + 1;
pParag->m_nLineCount = -1;
m_ParagPtrArray.Add(pParag);
nParagStart = nIndex + 1;
}
} while (pIter->Next());
pIter->Release();
}
void CFDE_TxtEdtEngine::RemoveAllParags() {
int32_t nCount = m_ParagPtrArray.GetSize();
int32_t i = 0;
for (i = 0; i < nCount; i++) {
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i];
if (pParag) {
delete pParag;
}
}
m_ParagPtrArray.RemoveAll();
}
void CFDE_TxtEdtEngine::RemoveAllPages() {
int32_t nCount = m_PagePtrArray.GetSize();
int32_t i = 0;
for (i = 0; i < nCount; i++) {
IFDE_TxtEdtPage* pPage = m_PagePtrArray[i];
if (pPage) {
pPage->Release();
}
}
m_PagePtrArray.RemoveAll();
}
void CFDE_TxtEdtEngine::UpdateParags() {
int32_t nCount = m_ParagPtrArray.GetSize();
if (nCount == 0) {
return;
}
CFDE_TxtEdtParag* pParag = NULL;
int32_t nLineCount = 0;
int32_t i = 0;
for (i = 0; i < nCount; i++) {
pParag = m_ParagPtrArray[i];
if (pParag->m_nLineCount == -1) {
pParag->CalcLines();
}
nLineCount += pParag->m_nLineCount;
}
m_nLineCount = nLineCount;
}
void CFDE_TxtEdtEngine::UpdatePages() {
if (m_nLineCount == 0) {
return;
}
int32_t nPageCount = (m_nLineCount - 1) / (m_nPageLineCount) + 1;
int32_t nSize = m_PagePtrArray.GetSize();
if (nSize == nPageCount) {
return;
}
if (nSize > nPageCount) {
IFDE_TxtEdtPage* pPage = NULL;
int32_t i = 0;
for (i = nSize - 1; i >= nPageCount; i--) {
pPage = m_PagePtrArray[i];
if (pPage) {
pPage->Release();
}
m_PagePtrArray.RemoveAt(i);
}
m_Param.pEventSink->On_PageCountChanged(this);
return;
}
if (nSize < nPageCount) {
IFDE_TxtEdtPage* pPage = NULL;
int32_t i = 0;
for (i = nSize; i < nPageCount; i++) {
pPage = IFDE_TxtEdtPage::Create(this, i);
m_PagePtrArray.Add(pPage);
}
m_Param.pEventSink->On_PageCountChanged(this);
return;
}
}
void CFDE_TxtEdtEngine::UpdateTxtBreak() {
FX_DWORD dwStyle = m_pTextBreak->GetLayoutStyles();
if (m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines) {
dwStyle &= ~FX_TXTLAYOUTSTYLE_SingleLine;
} else {
dwStyle |= FX_TXTLAYOUTSTYLE_SingleLine;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
dwStyle |= FX_TXTLAYOUTSTYLE_VerticalLayout;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalLayout;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve) {
dwStyle |= FX_TXTLAYOUTSTYLE_ReverseLine;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_ReverseLine;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_RTL) {
dwStyle |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_RTLReadingOrder;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
dwStyle |= FX_TXTLAYOUTSTYLE_CombText;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_CombText;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CharVertial) {
dwStyle |= FX_TXTLAYOUTSTYLE_VerticalChars;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalChars;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ExpandTab) {
dwStyle |= FX_TXTLAYOUTSTYLE_ExpandTab;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_ExpandTab;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicContext) {
dwStyle |= FX_TXTLAYOUTSTYLE_ArabicContext;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicContext;
}
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicShapes) {
dwStyle |= FX_TXTLAYOUTSTYLE_ArabicShapes;
} else {
dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicShapes;
}
m_pTextBreak->SetLayoutStyles(dwStyle);
FX_DWORD dwAligment = 0;
if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Justified) {
dwAligment |= FX_TXTLINEALIGNMENT_Justified;
} else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Distributed) {
dwAligment |= FX_TXTLINEALIGNMENT_Distributed;
}
if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Center) {
dwAligment |= FX_TXTLINEALIGNMENT_Center;
} else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Right) {
dwAligment |= FX_TXTLINEALIGNMENT_Right;
}
m_pTextBreak->SetAlignment(dwAligment);
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
m_pTextBreak->SetLineWidth(m_Param.fPlateHeight);
} else {
m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
}
} else {
if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
m_pTextBreak->SetLineWidth(m_Param.fPlateWidth);
} else {
m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
}
}
m_nPageLineCount = m_Param.nLineCount;
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
FX_FLOAT fCombWidth =
m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical
? m_Param.fPlateHeight
: m_Param.fPlateWidth;
if (m_nLimit > 0) {
fCombWidth /= m_nLimit;
}
m_pTextBreak->SetCombWidth(fCombWidth);
}
m_pTextBreak->SetFont(m_Param.pFont);
m_pTextBreak->SetFontSize(m_Param.fFontSize);
m_pTextBreak->SetTabWidth(m_Param.fTabWidth, m_Param.bTabEquidistant);
m_pTextBreak->SetDefaultChar(m_Param.wDefChar);
m_pTextBreak->SetParagraphBreakChar(m_Param.wLineBreakChar);
m_pTextBreak->SetCharRotation(m_Param.nCharRotation);
m_pTextBreak->SetLineBreakTolerance(m_Param.fFontSize * 0.2f);
m_pTextBreak->SetHorizontalScale(m_Param.nHorzScale);
m_pTextBreak->SetCharSpace(m_Param.fCharSpace);
}
FX_BOOL CFDE_TxtEdtEngine::ReplaceParagEnd(FX_WCHAR*& lpText,
int32_t& nLength,
FX_BOOL bPreIsCR) {
for (int32_t i = 0; i < nLength; i++) {
FX_WCHAR wc = lpText[i];
switch (wc) {
case L'\r': {
lpText[i] = m_wLineEnd;
bPreIsCR = TRUE;
} break;
case L'\n': {
if (bPreIsCR == TRUE) {
int32_t nNext = i + 1;
if (nNext < nLength) {
FXSYS_memmove(lpText + i, lpText + nNext,
(nLength - nNext) * sizeof(FX_WCHAR));
}
i--;
nLength--;
bPreIsCR = FALSE;
if (m_bAutoLineEnd) {
m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CRLF;
m_bAutoLineEnd = FALSE;
}
} else {
lpText[i] = m_wLineEnd;
if (m_bAutoLineEnd) {
m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_LF;
m_bAutoLineEnd = FALSE;
}
}
} break;
default: {
if (bPreIsCR && m_bAutoLineEnd) {
m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CR;
m_bAutoLineEnd = FALSE;
}
bPreIsCR = FALSE;
} break;
}
}
return bPreIsCR;
}
void CFDE_TxtEdtEngine::RecoverParagEnd(CFX_WideString& wsText) {
FX_WCHAR wc = (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CR) ? L'\n' : L'\r';
if (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CRLF) {
CFX_ArrayTemplate<int32_t> PosArr;
int32_t nLength = wsText.GetLength();
int32_t i = 0;
FX_WCHAR* lpPos = (FX_WCHAR*)(const FX_WCHAR*)wsText;
for (i = 0; i < nLength; i++, lpPos++) {
if (*lpPos == m_wLineEnd) {
*lpPos = wc;
PosArr.Add(i);
}
}
const FX_WCHAR* lpSrcBuf = wsText.c_str();
CFX_WideString wsTemp;
int32_t nCount = PosArr.GetSize();
FX_WCHAR* lpDstBuf = wsTemp.GetBuffer(nLength + nCount);
int32_t nDstPos = 0;
int32_t nSrcPos = 0;
for (i = 0; i < nCount; i++) {
int32_t nPos = PosArr[i];
int32_t nCopyLen = nPos - nSrcPos + 1;
FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos,
nCopyLen * sizeof(FX_WCHAR));
nDstPos += nCopyLen;
nSrcPos += nCopyLen;
lpDstBuf[nDstPos] = L'\n';
nDstPos++;
}
if (nSrcPos < nLength) {
FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos,
(nLength - nSrcPos) * sizeof(FX_WCHAR));
}
wsTemp.ReleaseBuffer(nLength + nCount);
wsText = wsTemp;
} else {
int32_t nLength = wsText.GetLength();
FX_WCHAR* lpBuf = (FX_WCHAR*)(const FX_WCHAR*)wsText;
for (int32_t i = 0; i < nLength; i++, lpBuf++) {
if (*lpBuf == m_wLineEnd) {
*lpBuf = wc;
}
}
}
}
int32_t CFDE_TxtEdtEngine::MovePage2Char(int32_t nIndex) {
FXSYS_assert(nIndex >= 0);
FXSYS_assert(nIndex <= m_pTxtBuf->GetTextLength());
if (m_nCaretPage >= 0) {
IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
int32_t nPageCharStart = pPage->GetCharStart();
int32_t nPageCharCount = pPage->GetCharCount();
if (nIndex >= nPageCharStart && nIndex < nPageCharStart + nPageCharCount) {
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
return m_nCaretPage;
}
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
}
CFDE_TxtEdtParag* pParag = NULL;
int32_t nLineCount = 0;
int32_t nParagCount = m_ParagPtrArray.GetSize();
int32_t i = 0;
for (i = 0; i < nParagCount; i++) {
pParag = m_ParagPtrArray[i];
if (pParag->m_nCharStart <= nIndex &&
nIndex < (pParag->m_nCharStart + pParag->m_nCharCount)) {
break;
}
nLineCount += pParag->m_nLineCount;
}
pParag->LoadParag();
int32_t nLineStart = -1;
int32_t nLineCharCount = -1;
for (i = 0; i < pParag->m_nLineCount; i++) {
pParag->GetLineRange(i, nLineStart, nLineCharCount);
if (nLineStart <= nIndex && nIndex < (nLineStart + nLineCharCount)) {
break;
}
}
FXSYS_assert(i < pParag->m_nLineCount);
nLineCount += (i + 1);
m_nCaretPage = (nLineCount - 1) / m_nPageLineCount + 1 - 1;
m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
pParag->UnloadParag();
return m_nCaretPage;
}
void CFDE_TxtEdtEngine::TextPos2ParagPos(int32_t nIndex,
FDE_TXTEDTPARAGPOS& ParagPos) const {
FXSYS_assert(nIndex >= 0 && nIndex < m_pTxtBuf->GetTextLength());
int32_t nCount = m_ParagPtrArray.GetSize();
int32_t nBgn = 0;
int32_t nMid = 0;
int32_t nEnd = nCount - 1;
while (nEnd > nBgn) {
nMid = (nBgn + nEnd) / 2;
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nMid];
if (nIndex < pParag->m_nCharStart) {
nEnd = nMid - 1;
} else if (nIndex >= (pParag->m_nCharStart + pParag->m_nCharCount)) {
nBgn = nMid + 1;
} else {
break;
}
}
if (nBgn == nEnd) {
nMid = nBgn;
}
FXSYS_assert(nIndex >= m_ParagPtrArray[nMid]->m_nCharStart &&
(nIndex < m_ParagPtrArray[nMid]->m_nCharStart +
m_ParagPtrArray[nMid]->m_nCharCount));
ParagPos.nParagIndex = nMid;
ParagPos.nCharIndex = nIndex - m_ParagPtrArray[nMid]->m_nCharStart;
}
int32_t CFDE_TxtEdtEngine::MoveForward(FX_BOOL& bBefore) {
if (m_nCaret == m_pTxtBuf->GetTextLength() - 1) {
return -1;
}
int32_t nCaret = m_nCaret;
if ((nCaret + 1 < m_pTxtBuf->GetTextLength()) &&
(m_pTxtBuf->GetCharByIndex(nCaret) == L'\r') &&
(m_pTxtBuf->GetCharByIndex(nCaret + 1) == L'\n')) {
nCaret++;
}
nCaret++;
bBefore = TRUE;
return nCaret;
}
int32_t CFDE_TxtEdtEngine::MoveBackward(FX_BOOL& bBefore) {
if (m_nCaret == 0) {
return FALSE;
}
int32_t nCaret = m_nCaret;
if (nCaret > 2 && m_pTxtBuf->GetCharByIndex(nCaret - 1) == L'\n' &&
m_pTxtBuf->GetCharByIndex(nCaret - 2) == L'\r') {
nCaret--;
}
nCaret--;
bBefore = TRUE;
return nCaret;
}
FX_BOOL CFDE_TxtEdtEngine::MoveUp(CFX_PointF& ptCaret) {
IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage);
const CFX_RectF& rtContent = pPage->GetContentsBox();
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 - m_Param.fLineSpace;
ptCaret.y = m_fCaretPosReserve;
FX_BOOL bLineReserve =
m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
if (ptCaret.x < rtContent.left) {
if (bLineReserve) {
if (m_nCaretPage == CountPages() - 1) {
return FALSE;
}
} else {
if (m_nCaretPage == 0) {
return FALSE;
}
}
if (bLineReserve) {
m_nCaretPage++;
} else {
m_nCaretPage--;
}
m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
ptCaret.x -= rtContent.left;
IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
ptCaret.x += pCurPage->GetContentsBox().right();
}
} else {
ptCaret.x = m_fCaretPosReserve;
ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 - m_Param.fLineSpace;
if (ptCaret.y < rtContent.top) {
if (m_nCaretPage == 0) {
return FALSE;
}
ptCaret.y -= rtContent.top;
m_nCaretPage--;
m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
ptCaret.y += pCurPage->GetContentsBox().bottom();
}
}
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveDown(CFX_PointF& ptCaret) {
IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage);
const CFX_RectF& rtContent = pPage->GetContentsBox();
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 + m_Param.fLineSpace;
ptCaret.y = m_fCaretPosReserve;
if (ptCaret.x >= rtContent.right()) {
FX_BOOL bLineReserve =
m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
if (bLineReserve) {
if (m_nCaretPage == 0) {
return FALSE;
}
} else {
if (m_nCaretPage == CountPages() - 1) {
return FALSE;
}
}
if (bLineReserve) {
m_nCaretPage--;
} else {
m_nCaretPage++;
}
m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
ptCaret.x -= rtContent.right();
IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
ptCaret.x += pCurPage->GetContentsBox().left;
}
} else {
ptCaret.x = m_fCaretPosReserve;
ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 + m_Param.fLineSpace;
if (ptCaret.y >= rtContent.bottom()) {
if (m_nCaretPage == CountPages() - 1) {
return FALSE;
}
ptCaret.y -= rtContent.bottom();
m_nCaretPage++;
m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
ptCaret.y += pCurPage->GetContentsBox().top;
}
}
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveLineStart() {
int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nIndex, ParagPos);
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
pParag->LoadParag();
int32_t nLineCount = pParag->m_nLineCount;
int32_t i = 0;
int32_t nStart = 0;
int32_t nCount = 0;
for (; i < nLineCount; i++) {
pParag->GetLineRange(i, nStart, nCount);
if (nIndex >= nStart && nIndex < nStart + nCount) {
break;
}
}
UpdateCaretRect(nStart, TRUE);
pParag->UnloadParag();
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveLineEnd() {
int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nIndex, ParagPos);
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
pParag->LoadParag();
int32_t nLineCount = pParag->m_nLineCount;
int32_t i = 0;
int32_t nStart = 0;
int32_t nCount = 0;
for (; i < nLineCount; i++) {
pParag->GetLineRange(i, nStart, nCount);
if (nIndex >= nStart && nIndex < nStart + nCount) {
break;
}
}
nIndex = nStart + nCount - 1;
FXSYS_assert(nIndex <= GetTextBufLength());
FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
FX_BOOL bBefore = FALSE;
if (nIndex <= GetTextBufLength()) {
if (wChar == L'\r') {
bBefore = TRUE;
} else if (wChar == L'\n' && nIndex > nStart) {
bBefore = TRUE;
nIndex--;
wChar = m_pTxtBuf->GetCharByIndex(nIndex);
if (wChar != L'\r') {
nIndex++;
}
}
}
UpdateCaretRect(nIndex, bBefore);
pParag->UnloadParag();
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveParagStart() {
int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nIndex, ParagPos);
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
UpdateCaretRect(pParag->m_nCharStart, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveParagEnd() {
int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
FDE_TXTEDTPARAGPOS ParagPos;
TextPos2ParagPos(nIndex, ParagPos);
CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
nIndex = pParag->m_nCharStart + pParag->m_nCharCount - 1;
FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
if (wChar == L'\n' && nIndex > 0) {
nIndex--;
wChar = m_pTxtBuf->GetCharByIndex(nIndex);
if (wChar != L'\r') {
nIndex++;
}
}
UpdateCaretRect(nIndex, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveHome() {
UpdateCaretRect(0, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtEngine::MoveEnd() {
UpdateCaretRect(GetTextBufLength(), TRUE);
return TRUE;
}
#ifdef FDE_USEFORMATBLOCK
int32_t CFDE_TxtEdtEngine::NormalizeCaretPos(int32_t nIndex,
int32_t nFlags,
FX_BOOL& bBefore) {
bBefore = TRUE;
int32_t nBgn = 0, nEnd = 0;
int32_t nRecord = -1;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bRet = GetFieldBoundary(nIndex, nBgn, nEnd, pField);
int32_t nDelta = 0;
if (bRet && !pField->IsFix()) {
if (nIndex - nBgn < FDE_FORMAT_EDIT_FIELD_HADERSIZE) {
if (nFlags == FDE_FORMAT_CARET_BACKWARD) {
CFDE_TxtEdtField* pEditableField = NULL;
if (FindEditableField(nIndex, nBgn, nEnd, pEditableField, FALSE)) {
return pEditableField->NormalizeCaretPos(nEnd - nBgn,
FDE_FORMAT_CARET_BACKWARD) +
nBgn;
}
}
nIndex = nBgn + FDE_FORMAT_EDIT_FIELD_HADERSIZE;
}
int32_t nRet = pField->NormalizeCaretPos(
nIndex - nBgn, (FDE_FORMAT_CARET_DIRECTION)nFlags);
if (nRet >= 0) {
return nRet + nBgn;
}
if (nRet == -2) {
int32_t nEditablePosBgn = 0, nEditablePosEnd = 0;
pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
nRecord = nBgn + nEditablePosBgn;
nFlags = FDE_FORMAT_CARET_BACKWARD;
} else {
FXSYS_assert(nRet == -1);
int32_t nEditablePosBgn = 0, nEditablePosEnd = 0;
pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
nRecord = nBgn + nEditablePosEnd;
nFlags = FDE_FORMAT_CARET_FORWARD;
}
} else if (!bRet) {
nDelta = FDE_FORMAT_EDIT_FIELD_HADERSIZE - FDE_FORMAT_EDIT_FIELD_TAILSIZE;
}
switch (nFlags) {
case FDE_FORMAT_CARET_FORWARD: {
if (FindEditableField(nIndex, nBgn, nEnd, pField)) {
return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE,
FDE_FORMAT_CARET_FORWARD) +
nBgn;
} else {
if (nRecord != -1) {
return nRecord;
}
bRet = FindEditableField(nIndex, nBgn, nEnd, pField, FALSE);
FXSYS_assert(bRet);
return pField->NormalizeCaretPos(nEnd - nBgn,
FDE_FORMAT_CARET_BACKWARD) +
nBgn;
}
} break;
case FDE_FORMAT_CARET_MIDDLE: {
int32_t nBgn1 = 0, nEnd1 = 0, nBgn2 = 0, nEnd2 = 0;
CFDE_TxtEdtField* pEditableField1 = NULL;
CFDE_TxtEdtField* pEditableField2 = NULL;
FX_BOOL bRet1 =
FindEditableField(nIndex, nBgn1, nEnd1, pEditableField1, FALSE);
FX_BOOL bRet2 = FindEditableField(nIndex, nBgn2, nEnd2, pEditableField2);
if (bRet1 == FALSE) {
FXSYS_assert(bRet2);
return pEditableField2->NormalizeCaretPos(
FDE_FORMAT_EDIT_FIELD_HADERSIZE, FDE_FORMAT_CARET_FORWARD) +
nBgn2;
} else if (bRet2 == FALSE) {
FXSYS_assert(bRet1);
return pEditableField1->NormalizeCaretPos(nEnd1 - nBgn1,
FDE_FORMAT_CARET_BACKWARD) +
nBgn1;
} else {
int32_t nEditablePosBgn = 0, nEditablePosEnd = 0;
if (nIndex - nEnd1 < nBgn2 + nDelta - nIndex) {
pEditableField1->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
return nEditablePosEnd + nBgn1;
} else {
pEditableField2->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
return nEditablePosBgn + nBgn2;
}
}
} break;
case FDE_FORMAT_CARET_BACKWARD: {
if (FindEditableField(nIndex, nBgn, nEnd, pField, FALSE)) {
return pField->NormalizeCaretPos(nEnd - nBgn,
FDE_FORMAT_CARET_BACKWARD) +
nBgn;
} else {
if (nRecord != -1) {
return nRecord;
}
bRet = FindEditableField(nIndex, nBgn, nEnd, pField);
FXSYS_assert(bRet);
return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE,
FDE_FORMAT_CARET_FORWARD) +
nBgn;
}
} break;
default:
FXSYS_assert(0);
return nIndex;
}
}
FX_BOOL CFDE_TxtEdtEngine::GetFieldBoundary(int32_t nIndex,
int32_t& nBgn,
int32_t& nEnd,
CFDE_TxtEdtField*& pField) {
CFDE_TxtEdtBufIter* pIter =
new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
pIter->SetAt(nIndex);
FX_BOOL bFind = FALSE;
do {
FX_WCHAR wc = pIter->GetChar();
if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
nEnd = pIter->GetAt();
bFind = TRUE;
nIndex--;
break;
}
if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
pIter->Release();
return FALSE;
}
} while (pIter->Next());
if (!bFind) {
pIter->Release();
return FALSE;
}
pIter->SetAt(nIndex);
do {
FX_WCHAR wc = pIter->GetChar();
if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
nBgn = pIter->GetAt();
pIter->Next();
FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
pIter->Next();
FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre);
pIter->Release();
return TRUE;
}
if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
pIter->Release();
return FALSE;
}
} while (pIter->Next(TRUE));
pIter->Release();
return FALSE;
}
FX_BOOL CFDE_TxtEdtEngine::FindEditableField(int32_t nIndex,
int32_t& nBgn,
int32_t& nEnd,
CFDE_TxtEdtField*& pField,
FX_BOOL bForward) {
FX_WCHAR wcFirst = FDE_TXTEDT_FORMATBLOCK_BGN;
FX_WCHAR wcSecond = FDE_TXTEDT_FORMATBLOCK_END;
if (!bForward) {
wcFirst = FDE_TXTEDT_FORMATBLOCK_END;
wcSecond = FDE_TXTEDT_FORMATBLOCK_BGN;
}
CFDE_TxtEdtBufIter* pIter =
new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
pIter->SetAt(nIndex);
int32_t bFind = FALSE;
do {
FX_WCHAR wc = pIter->GetChar();
if (wc == wcFirst) {
nBgn = pIter->GetAt();
bFind = TRUE;
break;
}
} while (pIter->Next(!bForward));
if (!bFind) {
pIter->Release();
return FALSE;
}
bFind = FALSE;
do {
FX_WCHAR wc = pIter->GetChar();
if (wc == wcSecond) {
nEnd = pIter->GetAt();
bFind = TRUE;
break;
}
} while (pIter->Next(!bForward));
FXSYS_assert(bFind);
if (!bForward) {
int32_t nTemp = nBgn;
nBgn = nEnd;
nEnd = nTemp;
}
pIter->SetAt(nBgn + 1);
FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
pIter->Next();
FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre);
pIter->Release();
if (!pField->IsFix()) {
return TRUE;
}
return FindEditableField((bForward ? nEnd : nBgn), nBgn, nEnd, pField,
bForward);
}
FX_BOOL CFDE_TxtEdtEngine::Move2NextEditableField(int32_t nIndex,
FX_BOOL bForward,
FX_BOOL bSelect) {
if (m_SelRangePtrArr.GetSize() > 0) {
ClearSelection();
m_Param.pEventSink->On_SelChanged(this);
}
int32_t nBgn = 0, nEnd = 0;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bRet = FindEditableField(nIndex, nBgn, nEnd, pField, bForward);
if (!bRet) {
return FALSE;
}
int32_t nEditableBgn = 0, nEditableEnd = 0;
pField->GetEditableRange(nEditableBgn, nEditableEnd);
nEditableBgn += nBgn;
nEditableEnd += nBgn;
if (bSelect) {
int32_t nRangeCount = nEditableEnd - nEditableBgn;
if (nRangeCount > 0) {
AddSelRange(nEditableBgn, nEditableEnd - nEditableBgn);
}
}
SetCaretPos(nEditableEnd, TRUE);
return TRUE;
}
int32_t CFDE_TxtEdtEngine::GetRealIndex(int32_t nIndex) const {
CFDE_TxtEdtBufIter* pIter =
new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
pIter->SetAt(0);
FX_BOOL bInField = FALSE;
int32_t nFieldBgn = 0;
int32_t nRealIndex = 0;
for (int32_t i = 0; i <= nIndex; i++) {
FX_WCHAR wc = pIter->GetChar();
if (bInField) {
if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
FX_DWORD dwPre = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 1);
FX_DWORD dwCur = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 2);
CFDE_TxtEdtField* pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre);
nRealIndex += pField->GetFieldTextLength();
bInField = FALSE;
}
} else {
if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
bInField = TRUE;
nFieldBgn = pIter->GetAt();
} else {
nRealIndex++;
}
}
pIter->Next();
}
if (!bInField) {
pIter->Release();
return nRealIndex;
}
pIter->SetAt(nFieldBgn + 1);
FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
pIter->Next();
FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
CFDE_TxtEdtField* pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre);
pIter->Release();
if (pField->IsFix()) {
int32_t nDelta = nIndex - nFieldBgn - FDE_FORMAT_EDIT_FIELD_HADERSIZE + 1;
return nRealIndex + (nDelta > 0 ? nDelta : 0);
} else {
return nRealIndex + pField->GetRealIndex(nIndex - nFieldBgn);
}
}
#endif
FX_BOOL CFDE_TxtEdtEngine::IsFitArea(CFX_WideString& wsText) {
IFDE_TextOut* pTextOut = IFDE_TextOut::Create();
pTextOut->SetLineSpace(m_Param.fLineSpace);
pTextOut->SetFont(m_Param.pFont);
pTextOut->SetFontSize(m_Param.fFontSize);
CFX_RectF rcText;
FXSYS_memset(&rcText, 0, sizeof(rcText));
FX_DWORD dwStyle = 0;
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) {
dwStyle |= FDE_TTOSTYLE_SingleLine;
}
if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
dwStyle |= FDE_TTOSTYLE_LineWrap;
rcText.width = m_Param.fPlateWidth;
} else {
rcText.width = 65535;
}
pTextOut->SetStyles(dwStyle);
wsText += L"\n";
pTextOut->CalcLogicSize(wsText, wsText.GetLength(), rcText);
pTextOut->Release();
wsText.Delete(wsText.GetLength() - 1);
if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz) &&
(rcText.width > m_Param.fPlateWidth)) {
return FALSE;
}
if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) &&
(rcText.height > m_Param.fLineSpace * m_Param.nLineCount)) {
return FALSE;
}
return TRUE;
}
void CFDE_TxtEdtEngine::UpdateCaretRect(int32_t nIndex, FX_BOOL bBefore) {
MovePage2Char(nIndex);
GetCaretRect(m_rtCaret, m_nCaretPage, nIndex, bBefore);
m_nCaret = nIndex;
m_bBefore = bBefore;
if (!m_bBefore) {
m_nCaret++;
m_bBefore = TRUE;
}
m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical)
? m_rtCaret.top
: m_rtCaret.left;
m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
}
void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret,
int32_t nPageIndex,
int32_t nCaret,
FX_BOOL bBefore) {
IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText;
int32_t nIndexInpage = nCaret - pPage->GetCharStart();
if (bBefore && bCombText && nIndexInpage > 0) {
nIndexInpage--;
bBefore = FALSE;
}
int32_t nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText);
if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
(FX_IsOdd(nBIDILevel) && bBefore)) {
rtCaret.Offset(0, rtCaret.height - 1.0f);
}
if (rtCaret.height == 0 && rtCaret.top > 1.0f) {
rtCaret.top -= 1.0f;
}
rtCaret.height = 1.0f;
} else {
if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
(FX_IsOdd(nBIDILevel) && bBefore)) {
rtCaret.Offset(rtCaret.width - 1.0f, 0);
}
if (rtCaret.width == 0 && rtCaret.left > 1.0f) {
rtCaret.left -= 1.0f;
}
rtCaret.width = 1.0f;
}
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
}
void CFDE_TxtEdtEngine::UpdateCaretIndex(const CFX_PointF& ptCaret) {
IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
m_nCaret = pPage->GetCharIndex(ptCaret, m_bBefore);
GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
if (!m_bBefore) {
m_nCaret++;
m_bBefore = TRUE;
}
m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage);
m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
}
FX_BOOL CFDE_TxtEdtEngine::IsSelect() {
return m_SelRangePtrArr.GetSize() > 0;
}
void CFDE_TxtEdtEngine::DeleteSelect() {
int32_t nCountRange = CountSelRanges();
if (nCountRange > 0) {
#ifdef FDE_USEFORMATBLOCK
int32_t nBlockCount = m_BlockArray.GetSize();
if (nBlockCount > 0) {
if (nCountRange > 1) {
return;
}
int32_t nSelStart;
int32_t nSelCount;
nSelCount = GetSelRange(0, nSelStart);
int32_t nSelEnd = nSelStart + nSelCount;
int32_t nBgn = 0;
int32_t nEnd = 0;
CFDE_TxtEdtField* pField = NULL;
FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField);
int32_t nCaretInField = nSelStart - nBgn;
FX_BOOL bBefore = FALSE;
if (!bInField || pField->IsFix() || nSelEnd > nEnd) {
return;
}
pField->Backup();
CFX_WideString wsDel;
int32_t nCaret = 0;
int32_t nRet =
pField->Delete(nCaretInField, nSelCount, wsDel, nCaret, bBefore);
nCaret += nBgn;
switch (nRet) {
case FDE_FORMAT_FIELD_DELETE_RET_S:
break;
case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE:
case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY:
return;
default:
FXSYS_assert(0);
break;
}
CFX_WideString wsField;
pField->GetFieldText(wsField);
if (!m_Param.pEventSink->On_ValidateField(
this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
pField->Restore();
return;
}
CFX_WideString wsDisplay;
pField->GetDisplayText(wsDisplay);
Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldDelete(
this, nSelStart, pField, nCaretInField, nBgn, nEnd - nBgn + 1,
wsDisplay.GetLength(), wsDel, FALSE);
CFX_ByteString bsDoRecord;
pRecord->Serialize(bsDoRecord);
m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
pRecord->Release();
}
SetCaretPos(nSelStart, bBefore);
return;
}
#endif
int32_t nSelStart;
int32_t nSelCount;
while (nCountRange > 0) {
nSelCount = GetSelRange(--nCountRange, nSelStart);
FDE_LPTXTEDTSELRANGE lpTemp = m_SelRangePtrArr[nCountRange];
delete lpTemp;
m_SelRangePtrArr.RemoveAt(nCountRange);
DeleteRange_DoRecord(nSelStart, nSelCount, TRUE);
}
ClearSelection();
m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
m_Param.pEventSink->On_SelChanged(this);
SetCaretPos(nSelStart, TRUE);
return;
}
}
IFDE_TxtEdtDoRecord* IFDE_TxtEdtDoRecord::Create(
const CFX_ByteStringC& bsDoRecord) {
const FX_CHAR* lpBuf = bsDoRecord.GetCStr();
int32_t nType = *((int32_t*)lpBuf);
switch (nType) {
case FDE_TXTEDT_DORECORD_INS:
return new CFDE_TxtEdtDoRecord_Insert(bsDoRecord);
case FDE_TXTEDT_DORECORD_DEL:
return new CFDE_TxtEdtDoRecord_DeleteRange(bsDoRecord);
#ifdef FDE_USEFORMATBLOCK
case FDE_TXTEDT_DORECORD_FORMATINS:
return new CFDE_TxtEdtDoRecord_FieldInsert(bsDoRecord);
case FDE_TXTEDT_DORECORD_FORMATDEL:
return new CFDE_TxtEdtDoRecord_FieldDelete(bsDoRecord);
case FDE_TXTEDT_DORECORD_FORMATREP:
return new CFDE_TxtEdtDoRecord_FieldReplace(bsDoRecord);
#endif
default:
break;
}
return NULL;
}
CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(
const CFX_ByteStringC& bsDoRecord) {
Deserialize(bsDoRecord);
}
CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(
CFDE_TxtEdtEngine* pEngine,
int32_t nCaret,
const FX_WCHAR* lpText,
int32_t nLength)
: m_pEngine(pEngine), m_nCaret(nCaret) {
FXSYS_assert(pEngine);
FX_WCHAR* lpBuffer = m_wsInsert.GetBuffer(nLength);
FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
m_wsInsert.ReleaseBuffer();
}
CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert() {}
void CFDE_TxtEdtDoRecord_Insert::Release() {
delete this;
}
FX_BOOL CFDE_TxtEdtDoRecord_Insert::Undo() {
if (m_pEngine->IsSelect()) {
m_pEngine->ClearSelection();
}
m_pEngine->Inner_DeleteRange(m_nCaret, m_wsInsert.GetLength());
FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
m_pEngine->SetCaretPos(m_nCaret, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtDoRecord_Insert::Redo() {
m_pEngine->Inner_Insert(m_nCaret, m_wsInsert.c_str(), m_wsInsert.GetLength());
FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
m_pEngine->SetCaretPos(m_nCaret, FALSE);
return TRUE;
}
void CFDE_TxtEdtDoRecord_Insert::Serialize(CFX_ByteString& bsDoRecord) const {
CFX_ArchiveSaver ArchiveSaver;
ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_INS);
ArchiveSaver << (int32_t)(uintptr_t)m_pEngine;
ArchiveSaver << m_nCaret;
ArchiveSaver << m_wsInsert;
int32_t nLength = ArchiveSaver.GetLength();
const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
bsDoRecord.ReleaseBuffer(nLength);
}
void CFDE_TxtEdtDoRecord_Insert::Deserialize(
const CFX_ByteStringC& bsDoRecord) {
CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
bsDoRecord.GetLength());
int32_t nType = 0;
ArchiveLoader >> nType;
FXSYS_assert(nType == FDE_TXTEDT_DORECORD_INS);
int32_t nEngine = 0;
ArchiveLoader >> nEngine;
m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
ArchiveLoader >> m_nCaret;
ArchiveLoader >> m_wsInsert;
}
CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(
const CFX_ByteStringC& bsDoRecord) {
Deserialize(bsDoRecord);
}
CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(
CFDE_TxtEdtEngine* pEngine,
int32_t nIndex,
int32_t nCaret,
const CFX_WideString& wsRange,
FX_BOOL bSel)
: m_pEngine(pEngine),
m_bSel(bSel),
m_nIndex(nIndex),
m_nCaret(nCaret),
m_wsRange(wsRange) {
FXSYS_assert(pEngine);
}
CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange() {}
void CFDE_TxtEdtDoRecord_DeleteRange::Release() {
delete this;
}
FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Undo() {
if (m_pEngine->IsSelect()) {
m_pEngine->ClearSelection();
}
m_pEngine->Inner_Insert(m_nIndex, m_wsRange.c_str(), m_wsRange.GetLength());
if (m_bSel) {
m_pEngine->AddSelRange(m_nIndex, m_wsRange.GetLength());
}
FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
m_pEngine->SetCaretPos(m_nCaret, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Redo() {
m_pEngine->Inner_DeleteRange(m_nIndex, m_wsRange.GetLength());
if (m_bSel) {
m_pEngine->RemoveSelRange(m_nIndex, m_wsRange.GetLength());
}
FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
m_pEngine->SetCaretPos(m_nIndex, TRUE);
return TRUE;
}
void CFDE_TxtEdtDoRecord_DeleteRange::Serialize(
CFX_ByteString& bsDoRecord) const {
CFX_ArchiveSaver ArchiveSaver;
ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_DEL);
ArchiveSaver << (int32_t)(uintptr_t)m_pEngine;
ArchiveSaver << (int32_t)m_bSel;
ArchiveSaver << m_nIndex;
ArchiveSaver << m_nCaret;
ArchiveSaver << m_wsRange;
int32_t nLength = ArchiveSaver.GetLength();
const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
bsDoRecord.ReleaseBuffer(nLength);
}
void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize(
const CFX_ByteStringC& bsDoRecord) {
CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
bsDoRecord.GetLength());
int32_t nType = 0;
ArchiveLoader >> nType;
FXSYS_assert(nType == FDE_TXTEDT_DORECORD_DEL);
int32_t nEngine = 0;
ArchiveLoader >> nEngine;
m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
int32_t iSel = 0;
ArchiveLoader >> iSel;
m_bSel = !!iSel;
ArchiveLoader >> m_nIndex;
ArchiveLoader >> m_nCaret;
ArchiveLoader >> m_wsRange;
}
#ifdef FDE_USEFORMATBLOCK
CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert(
const CFX_ByteStringC& bsDoRecord) {
Deserialize(bsDoRecord);
}
CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert(
CFDE_TxtEdtEngine* pEngine,
int32_t nCaret,
CFDE_TxtEdtField* pField,
int32_t nIndexInField,
int32_t nFieldBgn,
int32_t nOldFieldLength,
int32_t nNewFieldLength,
const CFX_WideString& wsIns,
FX_BOOL bSel)
: m_pEngine(pEngine),
m_nCaret(nCaret),
m_pField(pField),
m_nIndexInField(nIndexInField),
m_nFieldBgn(nFieldBgn),
m_nOldFieldLength(nOldFieldLength),
m_nNewFieldLength(nNewFieldLength),
m_wsIns(wsIns),
m_bSel(bSel) {
FXSYS_assert(pEngine);
FXSYS_assert(pField);
}
CFDE_TxtEdtDoRecord_FieldInsert::~CFDE_TxtEdtDoRecord_FieldInsert() {}
void CFDE_TxtEdtDoRecord_FieldInsert::Release() {
delete this;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Undo() {
CFX_WideString wsDel;
int32_t nCaret = 0;
FX_BOOL bBefore = FALSE;
int32_t nRet = m_pField->Delete(m_nIndexInField, m_wsIns.GetLength(), wsDel,
nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE &&
nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay);
m_pEngine->SetCaretPos(m_nCaret, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Redo() {
int32_t nCaret = 0;
FX_BOOL bBefore = FALSE;
int32_t nRet = m_pField->Insert(m_nIndexInField, m_wsIns, nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL &&
nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay);
m_pEngine->SetCaretPos(m_nCaret + m_wsIns.GetLength(), TRUE);
return TRUE;
}
void CFDE_TxtEdtDoRecord_FieldInsert::Serialize(
CFX_ByteString& bsDoRecord) const {
CFX_ArchiveSaver ArchiveSaver;
ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATINS);
ArchiveSaver << int32_t(m_pEngine);
ArchiveSaver << m_nCaret;
ArchiveSaver << int32_t(m_pField);
ArchiveSaver << m_nIndexInField;
ArchiveSaver << m_nFieldBgn;
ArchiveSaver << m_nOldFieldLength;
ArchiveSaver << m_nNewFieldLength;
ArchiveSaver << m_wsIns;
ArchiveSaver << m_bSel;
int32_t nLength = ArchiveSaver.GetLength();
const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
bsDoRecord.ReleaseBuffer(nLength);
}
void CFDE_TxtEdtDoRecord_FieldInsert::Deserialize(
const CFX_ByteStringC& bsDoRecord) {
CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
bsDoRecord.GetLength());
int32_t nType = 0;
ArchiveLoader >> nType;
FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATINS);
int32_t nEngine = 0;
ArchiveLoader >> nEngine;
m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
ArchiveLoader >> m_nCaret;
int32_t nField = 0;
ArchiveLoader >> nField;
m_pField = (CFDE_TxtEdtField*)nField;
ArchiveLoader >> m_nIndexInField;
ArchiveLoader >> m_nFieldBgn;
ArchiveLoader >> m_nOldFieldLength;
ArchiveLoader >> m_nNewFieldLength;
ArchiveLoader >> m_wsIns;
ArchiveLoader >> m_bSel;
}
CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete(
const CFX_ByteStringC& bsDoRecord) {
Deserialize(bsDoRecord);
}
CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete(
CFDE_TxtEdtEngine* pEngine,
int32_t nCaret,
CFDE_TxtEdtField* pField,
int32_t nIndexInField,
int32_t nFieldBgn,
int32_t nOldLength,
int32_t nNewLength,
const CFX_WideString& wsDel,
FX_BOOL bSel)
: m_pEngine(pEngine),
m_nCaret(nCaret),
m_pField(pField),
m_nIndexInField(nIndexInField),
m_nFieldBgn(nFieldBgn),
m_nOldFieldLength(nOldLength),
m_nNewFieldLength(nNewLength),
m_wsDel(wsDel),
m_bSel(bSel) {
FXSYS_assert(m_pEngine);
FXSYS_assert(m_pField);
}
CFDE_TxtEdtDoRecord_FieldDelete::~CFDE_TxtEdtDoRecord_FieldDelete() {}
void CFDE_TxtEdtDoRecord_FieldDelete::Release() {
delete this;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Undo() {
int32_t nCaret = 0;
FX_BOOL bBefore = FALSE;
int32_t nRet = m_pField->Insert(m_nIndexInField, m_wsDel, nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL &&
nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay);
m_pEngine->SetCaretPos(m_nCaret, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Redo() {
int32_t nCaret = 0;
FX_BOOL bBefore = 0;
CFX_WideString wsDel;
int32_t nRet = m_pField->Delete(m_nIndexInField, m_wsDel.GetLength(), wsDel,
nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE &&
nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay);
m_pEngine->SetCaretPos(m_nCaret - m_wsDel.GetLength(), TRUE);
return TRUE;
}
void CFDE_TxtEdtDoRecord_FieldDelete::Serialize(
CFX_ByteString& bsDoRecord) const {
CFX_ArchiveSaver ArchiveSaver;
ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATDEL);
ArchiveSaver << int32_t(m_pEngine);
ArchiveSaver << m_nCaret;
ArchiveSaver << int32_t(m_pField);
ArchiveSaver << m_nIndexInField;
ArchiveSaver << m_nFieldBgn;
ArchiveSaver << m_nOldFieldLength;
ArchiveSaver << m_nNewFieldLength;
ArchiveSaver << m_wsDel;
ArchiveSaver << m_bSel;
int32_t nLength = ArchiveSaver.GetLength();
const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
bsDoRecord.ReleaseBuffer(nLength);
}
void CFDE_TxtEdtDoRecord_FieldDelete::Deserialize(
const CFX_ByteStringC& bsDoRecord) {
CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
bsDoRecord.GetLength());
int32_t nType = 0;
ArchiveLoader >> nType;
FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATDEL);
int32_t nEngine = 0;
ArchiveLoader >> nEngine;
m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
ArchiveLoader >> m_nCaret;
int32_t nField = 0;
ArchiveLoader >> nField;
m_pField = (CFDE_TxtEdtField*)nField;
ArchiveLoader >> m_nIndexInField;
ArchiveLoader >> m_nFieldBgn;
ArchiveLoader >> m_nOldFieldLength;
ArchiveLoader >> m_nNewFieldLength;
ArchiveLoader >> m_wsDel;
ArchiveLoader >> m_bSel;
}
CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace(
const CFX_ByteStringC& bsDoRecord) {
Deserialize(bsDoRecord);
}
CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace(
CFDE_TxtEdtEngine* pEngine,
int32_t nCaret,
int32_t nNewCaret,
CFDE_TxtEdtField* pField,
int32_t nIndexInField,
int32_t nFieldBgn,
int32_t nFieldNewLength,
const CFX_WideString& wsDel,
const CFX_WideString& wsIns,
FX_BOOL bSel)
: m_pEngine(pEngine),
m_nCaret(nCaret),
m_nNewCaret(nNewCaret),
m_pField(pField),
m_nIndexInField(nIndexInField),
m_nFieldBgn(nFieldBgn),
m_nFieldNewLength(nFieldNewLength),
m_wsDel(wsDel),
m_wsIns(wsIns),
m_bSel(bSel) {
FXSYS_assert(m_pEngine);
FXSYS_assert(m_pField);
}
CFDE_TxtEdtDoRecord_FieldReplace::~CFDE_TxtEdtDoRecord_FieldReplace() {}
void CFDE_TxtEdtDoRecord_FieldReplace::Release() {
delete this;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Undo() {
CFX_WideString wsDel;
int32_t nCaret = 0;
FX_BOOL bBefore = FALSE;
int32_t nRet = m_pField->Replace(m_nIndexInField, m_wsIns.GetLength(),
m_wsDel, wsDel, nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE &&
nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay);
m_pEngine->SetCaretPos(m_nCaret, TRUE);
return TRUE;
}
FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Redo() {
CFX_WideString wsDel;
int32_t nCaret = 0;
FX_BOOL bBefore = FALSE;
int32_t nRet = m_pField->Replace(m_nIndexInField, m_wsDel.GetLength(),
m_wsIns, wsDel, nCaret, bBefore);
FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE &&
nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
CFX_WideString wsDisplay;
m_pField->GetDisplayText(wsDisplay);
m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay);
m_pEngine->SetCaretPos(m_nNewCaret, TRUE);
return TRUE;
}
void CFDE_TxtEdtDoRecord_FieldReplace::Serialize(
CFX_ByteString& bsDoRecord) const {
CFX_ArchiveSaver ArchiveSaver;
ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATREP);
ArchiveSaver << int32_t(m_pEngine);
ArchiveSaver << m_nCaret;
ArchiveSaver << m_nNewCaret;
ArchiveSaver << int32_t(m_pField);
ArchiveSaver << m_nIndexInField;
ArchiveSaver << m_nFieldBgn;
ArchiveSaver << m_nFieldNewLength;
ArchiveSaver << m_wsDel;
ArchiveSaver << m_wsIns;
ArchiveSaver << m_bSel;
int32_t nLength = ArchiveSaver.GetLength();
const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
bsDoRecord.ReleaseBuffer(nLength);
}
void CFDE_TxtEdtDoRecord_FieldReplace::Deserialize(
const CFX_ByteStringC& bsDoRecord) {
CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
bsDoRecord.GetLength());
int32_t nType = 0;
ArchiveLoader >> nType;
FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATREP);
int32_t nEngine = 0;
ArchiveLoader >> nEngine;
m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
ArchiveLoader >> m_nCaret;
ArchiveLoader >> m_nNewCaret;
int32_t nField = 0;
ArchiveLoader >> nField;
m_pField = (CFDE_TxtEdtField*)nField;
ArchiveLoader >> m_nIndexInField;
ArchiveLoader >> m_nFieldBgn;
ArchiveLoader >> m_nFieldNewLength;
ArchiveLoader >> m_wsDel;
ArchiveLoader >> m_wsIns;
ArchiveLoader >> m_bSel;
}
#endif