| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| 6 | |
| 7 #include "xfa/src/fee/fde_txtedtengine.h" | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "xfa/src/fde/tto/fde_textout.h" | |
| 12 #include "xfa/src/fee/fde_txtedtbuf.h" | |
| 13 #include "xfa/src/fee/fde_txtedtparag.h" | |
| 14 #include "xfa/src/fee/ifde_txtedtbuf.h" | |
| 15 #include "xfa/src/fee/ifde_txtedtengine.h" | |
| 16 #include "xfa/src/fee/ifde_txtedtpage.h" | |
| 17 | |
| 18 #define FDE_PAGEWIDTH_MAX 0xFFFF | |
| 19 #define FDE_TXTPLATESIZE (1024 * 12) | |
| 20 #define FDE_UNICODE_PARAGRAPH_SPERATOR (0x2029) | |
| 21 #define FDE_TXTEDT_DORECORD_INS 0 | |
| 22 #define FDE_TXTEDT_DORECORD_DEL 1 | |
| 23 | |
| 24 IFDE_TxtEdtEngine* IFDE_TxtEdtEngine::Create() { | |
| 25 return new CFDE_TxtEdtEngine(); | |
| 26 } | |
| 27 CFDE_TxtEdtEngine::CFDE_TxtEdtEngine() | |
| 28 : m_pTextBreak(nullptr), | |
| 29 m_nPageLineCount(20), | |
| 30 m_nLineCount(0), | |
| 31 m_nAnchorPos(-1), | |
| 32 m_nLayoutPos(0), | |
| 33 m_fCaretPosReserve(0.0), | |
| 34 m_nCaret(0), | |
| 35 m_bBefore(TRUE), | |
| 36 m_nCaretPage(0), | |
| 37 m_dwFindFlags(0), | |
| 38 m_bLock(FALSE), | |
| 39 m_nLimit(0), | |
| 40 m_wcAliasChar(L'*'), | |
| 41 m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto), | |
| 42 m_bAutoLineEnd(TRUE), | |
| 43 m_wLineEnd(FDE_UNICODE_PARAGRAPH_SPERATOR) { | |
| 44 FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF)); | |
| 45 m_pTxtBuf = new CFDE_TxtEdtBuf(); | |
| 46 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); | |
| 47 } | |
| 48 CFDE_TxtEdtEngine::~CFDE_TxtEdtEngine() { | |
| 49 if (m_pTxtBuf) { | |
| 50 m_pTxtBuf->Release(); | |
| 51 m_pTxtBuf = NULL; | |
| 52 } | |
| 53 if (m_pTextBreak) { | |
| 54 m_pTextBreak->Release(); | |
| 55 m_pTextBreak = NULL; | |
| 56 } | |
| 57 RemoveAllParags(); | |
| 58 RemoveAllPages(); | |
| 59 m_Param.pEventSink = NULL; | |
| 60 ClearSelection(); | |
| 61 } | |
| 62 void CFDE_TxtEdtEngine::Release() { | |
| 63 delete this; | |
| 64 } | |
| 65 void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS& params) { | |
| 66 if (m_pTextBreak == NULL) { | |
| 67 m_pTextBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None); | |
| 68 } | |
| 69 FXSYS_memcpy(&m_Param, ¶ms, sizeof(FDE_TXTEDTPARAMS)); | |
| 70 m_wLineEnd = params.wLineBreakChar; | |
| 71 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); | |
| 72 UpdateTxtBreak(); | |
| 73 } | |
| 74 const FDE_TXTEDTPARAMS* CFDE_TxtEdtEngine::GetEditParams() const { | |
| 75 return &m_Param; | |
| 76 } | |
| 77 int32_t CFDE_TxtEdtEngine::CountPages() const { | |
| 78 if (m_nLineCount == 0) { | |
| 79 return 0; | |
| 80 } | |
| 81 return ((m_nLineCount - 1) / m_nPageLineCount) + 1; | |
| 82 } | |
| 83 IFDE_TxtEdtPage* CFDE_TxtEdtEngine::GetPage(int32_t nIndex) { | |
| 84 if (m_PagePtrArray.GetSize() <= nIndex) { | |
| 85 return NULL; | |
| 86 } | |
| 87 return (IFDE_TxtEdtPage*)m_PagePtrArray[nIndex]; | |
| 88 } | |
| 89 FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(int32_t nChunkSize) { | |
| 90 return m_pTxtBuf->SetChunkSize(nChunkSize); | |
| 91 } | |
| 92 void CFDE_TxtEdtEngine::SetTextByStream(IFX_Stream* pStream) { | |
| 93 ResetEngine(); | |
| 94 int32_t nIndex = 0; | |
| 95 if (pStream != NULL && pStream->GetLength()) { | |
| 96 int32_t nStreamLength = pStream->GetLength(); | |
| 97 FX_BOOL bValid = TRUE; | |
| 98 if (m_nLimit > 0 && nStreamLength > m_nLimit) { | |
| 99 bValid = FALSE; | |
| 100 } | |
| 101 FX_BOOL bPreIsCR = FALSE; | |
| 102 if (bValid) { | |
| 103 uint8_t bom[4]; | |
| 104 int32_t nPos = pStream->GetBOM(bom); | |
| 105 pStream->Seek(FX_STREAMSEEK_Begin, nPos); | |
| 106 int32_t nPlateSize = std::min(nStreamLength, m_pTxtBuf->GetChunkSize()); | |
| 107 FX_WCHAR* lpwstr = FX_Alloc(FX_WCHAR, nPlateSize); | |
| 108 FX_BOOL bEos = false; | |
| 109 while (!bEos) { | |
| 110 int32_t nRead = pStream->ReadString(lpwstr, nPlateSize, bEos); | |
| 111 bPreIsCR = ReplaceParagEnd(lpwstr, nRead, bPreIsCR); | |
| 112 m_pTxtBuf->Insert(nIndex, lpwstr, nRead); | |
| 113 nIndex += nRead; | |
| 114 } | |
| 115 FX_Free(lpwstr); | |
| 116 } | |
| 117 } | |
| 118 m_pTxtBuf->Insert(nIndex, &m_wLineEnd, 1); | |
| 119 RebuildParagraphs(); | |
| 120 } | |
| 121 void CFDE_TxtEdtEngine::SetText(const CFX_WideString& wsText) { | |
| 122 ResetEngine(); | |
| 123 int32_t nLength = wsText.GetLength(); | |
| 124 if (nLength > 0) { | |
| 125 CFX_WideString wsTemp; | |
| 126 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength); | |
| 127 FXSYS_memcpy(lpBuffer, wsText.c_str(), nLength * sizeof(FX_WCHAR)); | |
| 128 ReplaceParagEnd(lpBuffer, nLength, FALSE); | |
| 129 wsTemp.ReleaseBuffer(nLength); | |
| 130 if (m_nLimit > 0 && nLength > m_nLimit) { | |
| 131 wsTemp.Delete(m_nLimit, nLength - m_nLimit); | |
| 132 nLength = m_nLimit; | |
| 133 } | |
| 134 m_pTxtBuf->SetText(wsTemp); | |
| 135 } | |
| 136 m_pTxtBuf->Insert(nLength, &m_wLineEnd, 1); | |
| 137 RebuildParagraphs(); | |
| 138 } | |
| 139 int32_t CFDE_TxtEdtEngine::GetTextLength() const { | |
| 140 return GetTextBufLength(); | |
| 141 } | |
| 142 void CFDE_TxtEdtEngine::GetText(CFX_WideString& wsText, | |
| 143 int32_t nStart, | |
| 144 int32_t nCount) { | |
| 145 int32_t nTextBufLength = GetTextBufLength(); | |
| 146 if (nCount == -1) { | |
| 147 nCount = nTextBufLength - nStart; | |
| 148 } | |
| 149 m_pTxtBuf->GetRange(wsText, nStart, nCount); | |
| 150 RecoverParagEnd(wsText); | |
| 151 } | |
| 152 | |
| 153 void CFDE_TxtEdtEngine::ClearText() { | |
| 154 DeleteRange(0, -1); | |
| 155 } | |
| 156 int32_t CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret) const { | |
| 157 rtCaret = m_rtCaret; | |
| 158 return m_nCaret; | |
| 159 } | |
| 160 int32_t CFDE_TxtEdtEngine::GetCaretPos() const { | |
| 161 if (IsLocked()) { | |
| 162 return 0; | |
| 163 } | |
| 164 return m_nCaret + (m_bBefore ? 0 : 1); | |
| 165 } | |
| 166 int32_t CFDE_TxtEdtEngine::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) { | |
| 167 if (IsLocked()) { | |
| 168 return 0; | |
| 169 } | |
| 170 FXSYS_assert(nIndex >= 0 && nIndex <= GetTextBufLength()); | |
| 171 if (m_PagePtrArray.GetSize() <= m_nCaretPage) { | |
| 172 return 0; | |
| 173 } | |
| 174 m_bBefore = bBefore; | |
| 175 m_nCaret = nIndex; | |
| 176 MovePage2Char(m_nCaret); | |
| 177 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore); | |
| 178 if (!m_bBefore) { | |
| 179 m_nCaret++; | |
| 180 m_bBefore = TRUE; | |
| 181 } | |
| 182 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) | |
| 183 ? m_rtCaret.top | |
| 184 : m_rtCaret.left; | |
| 185 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0); | |
| 186 m_nAnchorPos = -1; | |
| 187 return m_nCaret; | |
| 188 } | |
| 189 int32_t CFDE_TxtEdtEngine::MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret, | |
| 190 FX_BOOL bShift, | |
| 191 FX_BOOL bCtrl) { | |
| 192 if (IsLocked()) { | |
| 193 return 0; | |
| 194 } | |
| 195 if (m_PagePtrArray.GetSize() <= m_nCaretPage) { | |
| 196 return 0; | |
| 197 } | |
| 198 FX_BOOL bSelChange = FALSE; | |
| 199 if (IsSelect()) { | |
| 200 ClearSelection(); | |
| 201 bSelChange = TRUE; | |
| 202 } | |
| 203 if (bShift) { | |
| 204 if (m_nAnchorPos == -1) { | |
| 205 m_nAnchorPos = m_nCaret; | |
| 206 } | |
| 207 } else { | |
| 208 m_nAnchorPos = -1; | |
| 209 } | |
| 210 FX_BOOL bVertical = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical; | |
| 211 switch (eMoveCaret) { | |
| 212 case MC_Left: { | |
| 213 if (bVertical) { | |
| 214 CFX_PointF ptCaret; | |
| 215 if (MoveUp(ptCaret)) { | |
| 216 UpdateCaretIndex(ptCaret); | |
| 217 } | |
| 218 } else { | |
| 219 FX_BOOL bBefore = TRUE; | |
| 220 int32_t nIndex = MoveBackward(bBefore); | |
| 221 if (nIndex >= 0) { | |
| 222 UpdateCaretRect(nIndex, bBefore); | |
| 223 } | |
| 224 } | |
| 225 } break; | |
| 226 case MC_Right: { | |
| 227 if (bVertical) { | |
| 228 CFX_PointF ptCaret; | |
| 229 if (MoveDown(ptCaret)) { | |
| 230 UpdateCaretIndex(ptCaret); | |
| 231 } | |
| 232 } else { | |
| 233 FX_BOOL bBefore = TRUE; | |
| 234 int32_t nIndex = MoveForward(bBefore); | |
| 235 if (nIndex >= 0) { | |
| 236 UpdateCaretRect(nIndex, bBefore); | |
| 237 } | |
| 238 } | |
| 239 } break; | |
| 240 case MC_Up: { | |
| 241 if (bVertical) { | |
| 242 FX_BOOL bBefore = TRUE; | |
| 243 int32_t nIndex = MoveBackward(bBefore); | |
| 244 if (nIndex >= 0) { | |
| 245 UpdateCaretRect(nIndex, bBefore); | |
| 246 } | |
| 247 } else { | |
| 248 CFX_PointF ptCaret; | |
| 249 if (MoveUp(ptCaret)) { | |
| 250 UpdateCaretIndex(ptCaret); | |
| 251 } | |
| 252 } | |
| 253 } break; | |
| 254 case MC_Down: { | |
| 255 if (bVertical) { | |
| 256 FX_BOOL bBefore = TRUE; | |
| 257 int32_t nIndex = MoveForward(bBefore); | |
| 258 if (nIndex >= 0) { | |
| 259 UpdateCaretRect(nIndex, bBefore); | |
| 260 } | |
| 261 } else { | |
| 262 CFX_PointF ptCaret; | |
| 263 if (MoveDown(ptCaret)) { | |
| 264 UpdateCaretIndex(ptCaret); | |
| 265 } | |
| 266 } | |
| 267 } break; | |
| 268 case MC_WordBackward: | |
| 269 break; | |
| 270 case MC_WordForward: | |
| 271 break; | |
| 272 case MC_LineStart: | |
| 273 MoveLineStart(); | |
| 274 break; | |
| 275 case MC_LineEnd: | |
| 276 MoveLineEnd(); | |
| 277 break; | |
| 278 case MC_ParagStart: | |
| 279 MoveParagStart(); | |
| 280 break; | |
| 281 case MC_ParagEnd: | |
| 282 MoveParagEnd(); | |
| 283 break; | |
| 284 case MC_PageDown: | |
| 285 break; | |
| 286 case MC_PageUp: | |
| 287 break; | |
| 288 case MC_Home: | |
| 289 MoveHome(); | |
| 290 break; | |
| 291 case MC_End: | |
| 292 MoveEnd(); | |
| 293 break; | |
| 294 default: | |
| 295 break; | |
| 296 } | |
| 297 if (bShift && m_nAnchorPos != -1 && (m_nAnchorPos != m_nCaret)) { | |
| 298 AddSelRange(std::min(m_nAnchorPos, m_nCaret), | |
| 299 FXSYS_abs(m_nAnchorPos - m_nCaret)); | |
| 300 m_Param.pEventSink->On_SelChanged(this); | |
| 301 } | |
| 302 if (bSelChange) { | |
| 303 m_Param.pEventSink->On_SelChanged(this); | |
| 304 } | |
| 305 return m_nCaret; | |
| 306 } | |
| 307 void CFDE_TxtEdtEngine::Lock() { | |
| 308 m_bLock = TRUE; | |
| 309 } | |
| 310 void CFDE_TxtEdtEngine::Unlock() { | |
| 311 m_bLock = FALSE; | |
| 312 } | |
| 313 FX_BOOL CFDE_TxtEdtEngine::IsLocked() const { | |
| 314 return m_bLock; | |
| 315 } | |
| 316 int32_t CFDE_TxtEdtEngine::Insert(int32_t nStart, | |
| 317 const FX_WCHAR* lpText, | |
| 318 int32_t nLength) { | |
| 319 if (IsLocked()) { | |
| 320 return FDE_TXTEDT_MODIFY_RET_F_Locked; | |
| 321 } | |
| 322 CFX_WideString wsTemp; | |
| 323 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength); | |
| 324 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR)); | |
| 325 ReplaceParagEnd(lpBuffer, nLength, FALSE); | |
| 326 wsTemp.ReleaseBuffer(nLength); | |
| 327 FX_BOOL bPart = FALSE; | |
| 328 if (m_nLimit > 0) { | |
| 329 int32_t nTotalLength = GetTextBufLength(); | |
| 330 int32_t nCount = m_SelRangePtrArr.GetSize(); | |
| 331 for (int32_t i = 0; i < nCount; i++) { | |
| 332 FDE_LPTXTEDTSELRANGE lpSelRange = m_SelRangePtrArr.GetAt(i); | |
| 333 nTotalLength -= lpSelRange->nCount; | |
| 334 } | |
| 335 int32_t nExpectLength = nTotalLength + nLength; | |
| 336 if (nTotalLength == m_nLimit) { | |
| 337 return FDE_TXTEDT_MODIFY_RET_F_Full; | |
| 338 } | |
| 339 if (nExpectLength > m_nLimit) { | |
| 340 nLength -= (nExpectLength - m_nLimit); | |
| 341 bPart = TRUE; | |
| 342 } | |
| 343 } | |
| 344 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || | |
| 345 (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) { | |
| 346 int32_t nTemp = nLength; | |
| 347 if (m_Param.dwMode & FDE_TEXTEDITMODE_Password) { | |
| 348 CFX_WideString wsText; | |
| 349 while (nLength > 0) { | |
| 350 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); | |
| 351 int32_t nTotal = wsText.GetLength(); | |
| 352 FX_WCHAR* lpBuf = wsText.GetBuffer(nTotal); | |
| 353 for (int32_t i = 0; i < nTotal; i++) { | |
| 354 lpBuf[i] = m_wcAliasChar; | |
| 355 } | |
| 356 wsText.ReleaseBuffer(nTotal); | |
| 357 if (IsFitArea(wsText)) { | |
| 358 break; | |
| 359 } | |
| 360 nLength--; | |
| 361 } | |
| 362 } else { | |
| 363 CFX_WideString wsText; | |
| 364 while (nLength > 0) { | |
| 365 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); | |
| 366 if (IsFitArea(wsText)) { | |
| 367 break; | |
| 368 } | |
| 369 nLength--; | |
| 370 } | |
| 371 } | |
| 372 if (nLength == 0) { | |
| 373 return FDE_TXTEDT_MODIFY_RET_F_Full; | |
| 374 } | |
| 375 if (nLength < nTemp) { | |
| 376 bPart = TRUE; | |
| 377 } | |
| 378 } | |
| 379 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { | |
| 380 CFX_WideString wsText; | |
| 381 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); | |
| 382 if (!m_Param.pEventSink->On_Validate(this, wsText)) { | |
| 383 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; | |
| 384 } | |
| 385 } | |
| 386 if (IsSelect()) { | |
| 387 DeleteSelect(); | |
| 388 } | |
| 389 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { | |
| 390 IFDE_TxtEdtDoRecord* pRecord = | |
| 391 new CFDE_TxtEdtDoRecord_Insert(this, m_nCaret, lpBuffer, nLength); | |
| 392 CFX_ByteString bsDoRecord; | |
| 393 pRecord->Serialize(bsDoRecord); | |
| 394 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); | |
| 395 pRecord->Release(); | |
| 396 } | |
| 397 GetText(m_ChangeInfo.wsPrevText, 0); | |
| 398 Inner_Insert(m_nCaret, lpBuffer, nLength); | |
| 399 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; | |
| 400 m_ChangeInfo.wsInsert = CFX_WideString(lpBuffer, nLength); | |
| 401 nStart = m_nCaret; | |
| 402 nStart += nLength; | |
| 403 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1); | |
| 404 FX_BOOL bBefore = TRUE; | |
| 405 if (wChar != L'\n' && wChar != L'\r') { | |
| 406 nStart--; | |
| 407 bBefore = FALSE; | |
| 408 } | |
| 409 SetCaretPos(nStart, bBefore); | |
| 410 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); | |
| 411 return bPart ? FDE_TXTEDT_MODIFY_RET_S_Part : FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 412 } | |
| 413 int32_t CFDE_TxtEdtEngine::Delete(int32_t nStart, FX_BOOL bBackspace) { | |
| 414 if (IsLocked()) { | |
| 415 return FDE_TXTEDT_MODIFY_RET_F_Locked; | |
| 416 } | |
| 417 if (IsSelect()) { | |
| 418 DeleteSelect(); | |
| 419 return FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 420 } | |
| 421 | |
| 422 int32_t nCount = 1; | |
| 423 if (bBackspace) { | |
| 424 if (nStart == 0) { | |
| 425 return FDE_TXTEDT_MODIFY_RET_F_Boundary; | |
| 426 } | |
| 427 if (nStart > 2 && m_pTxtBuf->GetCharByIndex(nStart - 1) == L'\n' && | |
| 428 m_pTxtBuf->GetCharByIndex(nStart - 2) == L'\r') { | |
| 429 nStart--; | |
| 430 nCount++; | |
| 431 } | |
| 432 nStart--; | |
| 433 } else { | |
| 434 if (nStart == GetTextBufLength()) { | |
| 435 return FDE_TXTEDT_MODIFY_RET_F_Full; | |
| 436 } | |
| 437 if ((nStart + 1 < GetTextBufLength()) && | |
| 438 (m_pTxtBuf->GetCharByIndex(nStart) == L'\r') && | |
| 439 (m_pTxtBuf->GetCharByIndex(nStart + 1) == L'\n')) { | |
| 440 nCount++; | |
| 441 } | |
| 442 } | |
| 443 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { | |
| 444 CFX_WideString wsText; | |
| 445 GetPreDeleteText(wsText, nStart, nCount); | |
| 446 if (!m_Param.pEventSink->On_Validate(this, wsText)) { | |
| 447 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; | |
| 448 } | |
| 449 } | |
| 450 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { | |
| 451 CFX_WideString wsRange; | |
| 452 m_pTxtBuf->GetRange(wsRange, nStart, nCount); | |
| 453 IFDE_TxtEdtDoRecord* pRecord = | |
| 454 new CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, wsRange); | |
| 455 CFX_ByteString bsDoRecord; | |
| 456 pRecord->Serialize(bsDoRecord); | |
| 457 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); | |
| 458 pRecord->Release(); | |
| 459 } | |
| 460 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; | |
| 461 GetText(m_ChangeInfo.wsDelete, nStart, nCount); | |
| 462 Inner_DeleteRange(nStart, nCount); | |
| 463 SetCaretPos(nStart + ((!bBackspace && nStart > 0) ? -1 : 0), | |
| 464 (bBackspace || nStart == 0)); | |
| 465 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); | |
| 466 return FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 467 } | |
| 468 int32_t CFDE_TxtEdtEngine::DeleteRange(int32_t nStart, int32_t nCount) { | |
| 469 if (IsLocked()) { | |
| 470 return FDE_TXTEDT_MODIFY_RET_F_Locked; | |
| 471 } | |
| 472 if (nCount == -1) { | |
| 473 nCount = GetTextBufLength(); | |
| 474 } | |
| 475 if (nCount == 0) { | |
| 476 return FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 477 } | |
| 478 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { | |
| 479 CFX_WideString wsText; | |
| 480 GetPreDeleteText(wsText, nStart, nCount); | |
| 481 if (!m_Param.pEventSink->On_Validate(this, wsText)) { | |
| 482 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; | |
| 483 } | |
| 484 } | |
| 485 DeleteRange_DoRecord(nStart, nCount); | |
| 486 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); | |
| 487 SetCaretPos(nStart, TRUE); | |
| 488 return FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 489 } | |
| 490 int32_t CFDE_TxtEdtEngine::Replace(int32_t nStart, | |
| 491 int32_t nLength, | |
| 492 const CFX_WideString& wsReplace) { | |
| 493 if (IsLocked()) { | |
| 494 return FDE_TXTEDT_MODIFY_RET_F_Locked; | |
| 495 } | |
| 496 if (nStart < 0 || (nStart + nLength > GetTextBufLength())) { | |
| 497 return FDE_TXTEDT_MODIFY_RET_F_Boundary; | |
| 498 } | |
| 499 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { | |
| 500 CFX_WideString wsText; | |
| 501 GetPreReplaceText(wsText, nStart, nLength, wsReplace.c_str(), | |
| 502 wsReplace.GetLength()); | |
| 503 if (!m_Param.pEventSink->On_Validate(this, wsText)) { | |
| 504 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; | |
| 505 } | |
| 506 } | |
| 507 if (IsSelect()) { | |
| 508 ClearSelection(); | |
| 509 } | |
| 510 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Replace; | |
| 511 GetText(m_ChangeInfo.wsDelete, nStart, nLength); | |
| 512 if (nLength > 0) { | |
| 513 Inner_DeleteRange(nStart, nLength); | |
| 514 } | |
| 515 int32_t nTextLength = wsReplace.GetLength(); | |
| 516 if (nTextLength > 0) { | |
| 517 Inner_Insert(nStart, wsReplace.c_str(), nTextLength); | |
| 518 } | |
| 519 m_ChangeInfo.wsInsert = CFX_WideString(wsReplace.c_str(), nTextLength); | |
| 520 nStart += nTextLength; | |
| 521 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1); | |
| 522 FX_BOOL bBefore = TRUE; | |
| 523 if (wChar != L'\n' && wChar != L'\r') { | |
| 524 nStart--; | |
| 525 bBefore = FALSE; | |
| 526 } | |
| 527 SetCaretPos(nStart, bBefore); | |
| 528 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 529 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 530 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); | |
| 531 return FDE_TXTEDT_MODIFY_RET_S_Normal; | |
| 532 } | |
| 533 void CFDE_TxtEdtEngine::SetLimit(int32_t nLimit) { | |
| 534 m_nLimit = nLimit; | |
| 535 } | |
| 536 void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias) { | |
| 537 m_wcAliasChar = wcAlias; | |
| 538 } | |
| 539 | |
| 540 void CFDE_TxtEdtEngine::RemoveSelRange(int32_t nStart, int32_t nCount) { | |
| 541 FDE_LPTXTEDTSELRANGE lpTemp = NULL; | |
| 542 int32_t nRangeCount = m_SelRangePtrArr.GetSize(); | |
| 543 int32_t i = 0; | |
| 544 for (i = 0; i < nRangeCount; i++) { | |
| 545 lpTemp = m_SelRangePtrArr[i]; | |
| 546 if (lpTemp->nStart == nStart && lpTemp->nCount == nCount) { | |
| 547 delete lpTemp; | |
| 548 m_SelRangePtrArr.RemoveAt(i); | |
| 549 return; | |
| 550 } | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 void CFDE_TxtEdtEngine::AddSelRange(int32_t nStart, int32_t nCount) { | |
| 555 if (nCount == -1) { | |
| 556 nCount = GetTextLength() - nStart; | |
| 557 } | |
| 558 int32_t nSize = m_SelRangePtrArr.GetSize(); | |
| 559 if (nSize <= 0) { | |
| 560 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; | |
| 561 lpSelRange->nStart = nStart; | |
| 562 lpSelRange->nCount = nCount; | |
| 563 m_SelRangePtrArr.Add(lpSelRange); | |
| 564 m_Param.pEventSink->On_SelChanged(this); | |
| 565 return; | |
| 566 } | |
| 567 FDE_LPTXTEDTSELRANGE lpTemp = NULL; | |
| 568 lpTemp = m_SelRangePtrArr[nSize - 1]; | |
| 569 if (nStart >= lpTemp->nStart + lpTemp->nCount) { | |
| 570 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; | |
| 571 lpSelRange->nStart = nStart; | |
| 572 lpSelRange->nCount = nCount; | |
| 573 m_SelRangePtrArr.Add(lpSelRange); | |
| 574 m_Param.pEventSink->On_SelChanged(this); | |
| 575 return; | |
| 576 } | |
| 577 int32_t nEnd = nStart + nCount - 1; | |
| 578 FX_BOOL bBegin = FALSE; | |
| 579 int32_t nRangeBgn = 0; | |
| 580 int32_t nRangeCnt = 0; | |
| 581 for (int32_t i = 0; i < nSize; i++) { | |
| 582 lpTemp = m_SelRangePtrArr[i]; | |
| 583 int32_t nTempBgn = lpTemp->nStart; | |
| 584 int32_t nTempEnd = nTempBgn + lpTemp->nCount - 1; | |
| 585 if (bBegin) { | |
| 586 if (nEnd < nTempBgn) { | |
| 587 break; | |
| 588 } else if (nStart >= nTempBgn && nStart <= nTempEnd) { | |
| 589 nRangeCnt++; | |
| 590 break; | |
| 591 } | |
| 592 nRangeCnt++; | |
| 593 } else { | |
| 594 if (nStart <= nTempEnd) { | |
| 595 nRangeBgn = i; | |
| 596 if (nEnd < nTempBgn) { | |
| 597 break; | |
| 598 } | |
| 599 nRangeCnt = 1; | |
| 600 bBegin = TRUE; | |
| 601 } | |
| 602 } | |
| 603 } | |
| 604 if (nRangeCnt == 0) { | |
| 605 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; | |
| 606 lpSelRange->nStart = nStart; | |
| 607 lpSelRange->nCount = nCount; | |
| 608 m_SelRangePtrArr.InsertAt(nRangeBgn, lpSelRange); | |
| 609 } else { | |
| 610 lpTemp = m_SelRangePtrArr[nRangeBgn]; | |
| 611 lpTemp->nStart = nStart; | |
| 612 lpTemp->nCount = nCount; | |
| 613 nRangeCnt--; | |
| 614 nRangeBgn++; | |
| 615 while (nRangeCnt--) { | |
| 616 delete m_SelRangePtrArr[nRangeBgn]; | |
| 617 m_SelRangePtrArr.RemoveAt(nRangeBgn); | |
| 618 } | |
| 619 } | |
| 620 m_Param.pEventSink->On_SelChanged(this); | |
| 621 } | |
| 622 | |
| 623 int32_t CFDE_TxtEdtEngine::CountSelRanges() { | |
| 624 return m_SelRangePtrArr.GetSize(); | |
| 625 } | |
| 626 int32_t CFDE_TxtEdtEngine::GetSelRange(int32_t nIndex, int32_t& nStart) { | |
| 627 nStart = m_SelRangePtrArr[nIndex]->nStart; | |
| 628 return m_SelRangePtrArr[nIndex]->nCount; | |
| 629 } | |
| 630 void CFDE_TxtEdtEngine::ClearSelection() { | |
| 631 int32_t nCount = m_SelRangePtrArr.GetSize(); | |
| 632 FDE_LPTXTEDTSELRANGE lpRange = NULL; | |
| 633 int32_t i = 0; | |
| 634 for (i = 0; i < nCount; i++) { | |
| 635 lpRange = m_SelRangePtrArr[i]; | |
| 636 if (lpRange != NULL) { | |
| 637 delete lpRange; | |
| 638 lpRange = NULL; | |
| 639 } | |
| 640 } | |
| 641 m_SelRangePtrArr.RemoveAll(); | |
| 642 if (nCount && m_Param.pEventSink) { | |
| 643 m_Param.pEventSink->On_SelChanged(this); | |
| 644 } | |
| 645 } | |
| 646 FX_BOOL CFDE_TxtEdtEngine::Redo(const CFX_ByteStringC& bsRedo) { | |
| 647 if (IsLocked()) { | |
| 648 return FALSE; | |
| 649 } | |
| 650 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) { | |
| 651 return FALSE; | |
| 652 } | |
| 653 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsRedo); | |
| 654 FXSYS_assert(pDoRecord); | |
| 655 if (pDoRecord == NULL) { | |
| 656 return FALSE; | |
| 657 } | |
| 658 FX_BOOL bOK = pDoRecord->Redo(); | |
| 659 pDoRecord->Release(); | |
| 660 return bOK; | |
| 661 } | |
| 662 FX_BOOL CFDE_TxtEdtEngine::Undo(const CFX_ByteStringC& bsUndo) { | |
| 663 if (IsLocked()) { | |
| 664 return FALSE; | |
| 665 } | |
| 666 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) { | |
| 667 return FALSE; | |
| 668 } | |
| 669 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsUndo); | |
| 670 FXSYS_assert(pDoRecord); | |
| 671 if (pDoRecord == NULL) { | |
| 672 return FALSE; | |
| 673 } | |
| 674 FX_BOOL bOK = pDoRecord->Undo(); | |
| 675 pDoRecord->Release(); | |
| 676 return bOK; | |
| 677 } | |
| 678 int32_t CFDE_TxtEdtEngine::StartLayout() { | |
| 679 Lock(); | |
| 680 RemoveAllPages(); | |
| 681 m_nLayoutPos = 0; | |
| 682 m_nLineCount = 0; | |
| 683 return 0; | |
| 684 } | |
| 685 int32_t CFDE_TxtEdtEngine::DoLayout(IFX_Pause* pPause) { | |
| 686 int32_t nCount = m_ParagPtrArray.GetSize(); | |
| 687 CFDE_TxtEdtParag* pParag = NULL; | |
| 688 int32_t nLineCount = 0; | |
| 689 for (; m_nLayoutPos < nCount; m_nLayoutPos++) { | |
| 690 pParag = m_ParagPtrArray[m_nLayoutPos]; | |
| 691 pParag->CalcLines(); | |
| 692 nLineCount += pParag->m_nLineCount; | |
| 693 if ((pPause != NULL) && (nLineCount > m_nPageLineCount) && | |
| 694 pPause->NeedToPauseNow()) { | |
| 695 m_nLineCount += nLineCount; | |
| 696 return (++m_nLayoutPos * 100) / nCount; | |
| 697 } | |
| 698 } | |
| 699 m_nLineCount += nLineCount; | |
| 700 return 100; | |
| 701 } | |
| 702 void CFDE_TxtEdtEngine::EndLayout() { | |
| 703 UpdatePages(); | |
| 704 int32_t nLength = GetTextLength(); | |
| 705 if (m_nCaret > nLength) { | |
| 706 m_nCaret = nLength; | |
| 707 } | |
| 708 int32_t nIndex = m_nCaret; | |
| 709 if (!m_bBefore) { | |
| 710 nIndex--; | |
| 711 } | |
| 712 m_rtCaret.Set(0, 0, 1, m_Param.fFontSize); | |
| 713 Unlock(); | |
| 714 } | |
| 715 FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause* pPause) { | |
| 716 return m_pTxtBuf->Optimize(pPause); | |
| 717 } | |
| 718 IFDE_TxtEdtBuf* CFDE_TxtEdtEngine::GetTextBuf() const { | |
| 719 return (IFDE_TxtEdtBuf*)m_pTxtBuf; | |
| 720 } | |
| 721 int32_t CFDE_TxtEdtEngine::GetTextBufLength() const { | |
| 722 return m_pTxtBuf->GetTextLength() - 1; | |
| 723 } | |
| 724 IFX_TxtBreak* CFDE_TxtEdtEngine::GetTextBreak() const { | |
| 725 return m_pTextBreak; | |
| 726 } | |
| 727 int32_t CFDE_TxtEdtEngine::GetLineCount() const { | |
| 728 return m_nLineCount; | |
| 729 } | |
| 730 int32_t CFDE_TxtEdtEngine::GetPageLineCount() const { | |
| 731 return m_nPageLineCount; | |
| 732 } | |
| 733 int32_t CFDE_TxtEdtEngine::CountParags() const { | |
| 734 return m_ParagPtrArray.GetSize(); | |
| 735 } | |
| 736 IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const { | |
| 737 return m_ParagPtrArray[nParagIndex]; | |
| 738 } | |
| 739 IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() { | |
| 740 if (!m_pTxtBuf) { | |
| 741 return NULL; | |
| 742 } | |
| 743 return new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf); | |
| 744 } | |
| 745 int32_t CFDE_TxtEdtEngine::Line2Parag(int32_t nStartParag, | |
| 746 int32_t nStartLineofParag, | |
| 747 int32_t nLineIndex, | |
| 748 int32_t& nStartLine) const { | |
| 749 int32_t nLineTotal = nStartLineofParag; | |
| 750 int32_t nCount = m_ParagPtrArray.GetSize(); | |
| 751 CFDE_TxtEdtParag* pParag = NULL; | |
| 752 int32_t i = nStartParag; | |
| 753 for (; i < nCount; i++) { | |
| 754 pParag = m_ParagPtrArray[i]; | |
| 755 nLineTotal += pParag->m_nLineCount; | |
| 756 if (nLineTotal > nLineIndex) { | |
| 757 break; | |
| 758 } | |
| 759 } | |
| 760 nStartLine = nLineTotal - pParag->m_nLineCount; | |
| 761 return i; | |
| 762 } | |
| 763 void CFDE_TxtEdtEngine::GetPreDeleteText(CFX_WideString& wsText, | |
| 764 int32_t nIndex, | |
| 765 int32_t nLength) { | |
| 766 GetText(wsText, 0, GetTextBufLength()); | |
| 767 wsText.Delete(nIndex, nLength); | |
| 768 } | |
| 769 void CFDE_TxtEdtEngine::GetPreInsertText(CFX_WideString& wsText, | |
| 770 int32_t nIndex, | |
| 771 const FX_WCHAR* lpText, | |
| 772 int32_t nLength) { | |
| 773 GetText(wsText, 0, GetTextBufLength()); | |
| 774 int32_t nSelIndex = 0; | |
| 775 int32_t nSelLength = 0; | |
| 776 int32_t nSelCount = CountSelRanges(); | |
| 777 while (nSelCount--) { | |
| 778 nSelLength = GetSelRange(nSelCount, nSelIndex); | |
| 779 wsText.Delete(nSelIndex, nSelLength); | |
| 780 nIndex = nSelIndex; | |
| 781 } | |
| 782 CFX_WideString wsTemp; | |
| 783 int32_t nOldLength = wsText.GetLength(); | |
| 784 const FX_WCHAR* pOldBuffer = wsText.c_str(); | |
| 785 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nOldLength + nLength); | |
| 786 FXSYS_memcpy(lpBuffer, pOldBuffer, (nIndex) * sizeof(FX_WCHAR)); | |
| 787 FXSYS_memcpy(lpBuffer + nIndex, lpText, nLength * sizeof(FX_WCHAR)); | |
| 788 FXSYS_memcpy(lpBuffer + nIndex + nLength, pOldBuffer + nIndex, | |
| 789 (nOldLength - nIndex) * sizeof(FX_WCHAR)); | |
| 790 wsTemp.ReleaseBuffer(nOldLength + nLength); | |
| 791 wsText = wsTemp; | |
| 792 } | |
| 793 void CFDE_TxtEdtEngine::GetPreReplaceText(CFX_WideString& wsText, | |
| 794 int32_t nIndex, | |
| 795 int32_t nOriginLength, | |
| 796 const FX_WCHAR* lpText, | |
| 797 int32_t nLength) { | |
| 798 GetText(wsText, 0, GetTextBufLength()); | |
| 799 int32_t nSelIndex = 0; | |
| 800 int32_t nSelLength = 0; | |
| 801 int32_t nSelCount = CountSelRanges(); | |
| 802 while (nSelCount--) { | |
| 803 nSelLength = GetSelRange(nSelCount, nSelIndex); | |
| 804 wsText.Delete(nSelIndex, nSelLength); | |
| 805 } | |
| 806 wsText.Delete(nIndex, nOriginLength); | |
| 807 int32_t i = 0; | |
| 808 for (i = 0; i < nLength; i++) { | |
| 809 wsText.Insert(nIndex++, lpText[i]); | |
| 810 } | |
| 811 } | |
| 812 void CFDE_TxtEdtEngine::Inner_Insert(int32_t nStart, | |
| 813 const FX_WCHAR* lpText, | |
| 814 int32_t nLength) { | |
| 815 FXSYS_assert(nLength > 0); | |
| 816 FDE_TXTEDTPARAGPOS ParagPos; | |
| 817 TextPos2ParagPos(nStart, ParagPos); | |
| 818 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 819 int32_t nParagCount = m_ParagPtrArray.GetSize(); | |
| 820 int32_t i = 0; | |
| 821 for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) { | |
| 822 m_ParagPtrArray[i]->m_nCharStart += nLength; | |
| 823 } | |
| 824 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; | |
| 825 int32_t nReserveLineCount = pParag->m_nLineCount; | |
| 826 int32_t nReserveCharStart = pParag->m_nCharStart; | |
| 827 int32_t nLeavePart = ParagPos.nCharIndex; | |
| 828 int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex; | |
| 829 int32_t nTextStart = 0; | |
| 830 FX_WCHAR wCurChar = L' '; | |
| 831 const FX_WCHAR* lpPos = lpText; | |
| 832 FX_BOOL bFirst = TRUE; | |
| 833 int32_t nParagIndex = ParagPos.nParagIndex; | |
| 834 for (i = 0; i < nLength; i++, lpPos++) { | |
| 835 wCurChar = *lpPos; | |
| 836 if (wCurChar == m_wLineEnd) { | |
| 837 if (bFirst) { | |
| 838 pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1); | |
| 839 pParag->m_nLineCount = -1; | |
| 840 nReserveCharStart += pParag->m_nCharCount; | |
| 841 bFirst = FALSE; | |
| 842 } else { | |
| 843 pParag = new CFDE_TxtEdtParag(this); | |
| 844 pParag->m_nLineCount = -1; | |
| 845 pParag->m_nCharCount = i - nTextStart + 1; | |
| 846 pParag->m_nCharStart = nReserveCharStart; | |
| 847 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); | |
| 848 nReserveCharStart += pParag->m_nCharCount; | |
| 849 } | |
| 850 nTextStart = i + 1; | |
| 851 } | |
| 852 } | |
| 853 if (bFirst) { | |
| 854 pParag->m_nCharCount += nLength; | |
| 855 pParag->m_nLineCount = -1; | |
| 856 bFirst = FALSE; | |
| 857 } else { | |
| 858 pParag = new CFDE_TxtEdtParag(this); | |
| 859 pParag->m_nLineCount = -1; | |
| 860 pParag->m_nCharCount = nLength - nTextStart + nCutPart; | |
| 861 pParag->m_nCharStart = nReserveCharStart; | |
| 862 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); | |
| 863 } | |
| 864 m_pTxtBuf->Insert(nStart, lpText, nLength); | |
| 865 int32_t nTotalLineCount = 0; | |
| 866 for (i = ParagPos.nParagIndex; i <= nParagIndex; i++) { | |
| 867 pParag = m_ParagPtrArray[i]; | |
| 868 pParag->CalcLines(); | |
| 869 nTotalLineCount += pParag->m_nLineCount; | |
| 870 } | |
| 871 m_nLineCount += nTotalLineCount - nReserveLineCount; | |
| 872 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 873 UpdatePages(); | |
| 874 } | |
| 875 | |
| 876 void CFDE_TxtEdtEngine::Inner_DeleteRange(int32_t nStart, int32_t nCount) { | |
| 877 if (nCount == -1) { | |
| 878 nCount = m_pTxtBuf->GetTextLength() - nStart; | |
| 879 } | |
| 880 int32_t nEnd = nStart + nCount - 1; | |
| 881 FXSYS_assert(nStart >= 0 && nEnd < m_pTxtBuf->GetTextLength()); | |
| 882 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 883 FDE_TXTEDTPARAGPOS ParagPosBgn, ParagPosEnd; | |
| 884 TextPos2ParagPos(nStart, ParagPosBgn); | |
| 885 TextPos2ParagPos(nEnd, ParagPosEnd); | |
| 886 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPosEnd.nParagIndex]; | |
| 887 FX_BOOL bLastParag = FALSE; | |
| 888 if (ParagPosEnd.nCharIndex == pParag->m_nCharCount - 1) { | |
| 889 if (ParagPosEnd.nParagIndex < m_ParagPtrArray.GetSize() - 1) { | |
| 890 ParagPosEnd.nParagIndex++; | |
| 891 } else { | |
| 892 bLastParag = TRUE; | |
| 893 } | |
| 894 } | |
| 895 int32_t nTotalLineCount = 0; | |
| 896 int32_t nTotalCharCount = 0; | |
| 897 int32_t i = 0; | |
| 898 for (i = ParagPosBgn.nParagIndex; i <= ParagPosEnd.nParagIndex; i++) { | |
| 899 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i]; | |
| 900 pParag->CalcLines(); | |
| 901 nTotalLineCount += pParag->m_nLineCount; | |
| 902 nTotalCharCount += pParag->m_nCharCount; | |
| 903 } | |
| 904 m_pTxtBuf->Delete(nStart, nCount); | |
| 905 int32_t nNextParagIndex = (ParagPosBgn.nCharIndex == 0 && bLastParag) | |
| 906 ? ParagPosBgn.nParagIndex | |
| 907 : (ParagPosBgn.nParagIndex + 1); | |
| 908 for (i = nNextParagIndex; i <= ParagPosEnd.nParagIndex; i++) { | |
| 909 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nNextParagIndex]; | |
| 910 delete pParag; | |
| 911 m_ParagPtrArray.RemoveAt(nNextParagIndex); | |
| 912 } | |
| 913 if (!(bLastParag && ParagPosBgn.nCharIndex == 0)) { | |
| 914 pParag = m_ParagPtrArray[ParagPosBgn.nParagIndex]; | |
| 915 pParag->m_nCharCount = nTotalCharCount - nCount; | |
| 916 pParag->CalcLines(); | |
| 917 nTotalLineCount -= pParag->m_nLineCount; | |
| 918 } | |
| 919 int32_t nParagCount = m_ParagPtrArray.GetSize(); | |
| 920 for (i = nNextParagIndex; i < nParagCount; i++) { | |
| 921 m_ParagPtrArray[i]->m_nCharStart -= nCount; | |
| 922 } | |
| 923 m_nLineCount -= nTotalLineCount; | |
| 924 UpdatePages(); | |
| 925 int32_t nPageCount = CountPages(); | |
| 926 if (m_nCaretPage >= nPageCount) { | |
| 927 m_nCaretPage = nPageCount - 1; | |
| 928 } | |
| 929 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 930 } | |
| 931 void CFDE_TxtEdtEngine::DeleteRange_DoRecord(int32_t nStart, | |
| 932 int32_t nCount, | |
| 933 FX_BOOL bSel) { | |
| 934 FXSYS_assert(nStart >= 0); | |
| 935 if (nCount == -1) { | |
| 936 nCount = GetTextLength() - nStart; | |
| 937 } | |
| 938 FXSYS_assert((nStart + nCount) <= m_pTxtBuf->GetTextLength()); | |
| 939 | |
| 940 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { | |
| 941 CFX_WideString wsRange; | |
| 942 m_pTxtBuf->GetRange(wsRange, nStart, nCount); | |
| 943 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_DeleteRange( | |
| 944 this, nStart, m_nCaret, wsRange, bSel); | |
| 945 CFX_ByteString bsDoRecord; | |
| 946 pRecord->Serialize(bsDoRecord); | |
| 947 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); | |
| 948 pRecord->Release(); | |
| 949 } | |
| 950 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; | |
| 951 GetText(m_ChangeInfo.wsDelete, nStart, nCount); | |
| 952 Inner_DeleteRange(nStart, nCount); | |
| 953 } | |
| 954 void CFDE_TxtEdtEngine::ResetEngine() { | |
| 955 RemoveAllPages(); | |
| 956 RemoveAllParags(); | |
| 957 ClearSelection(); | |
| 958 m_nCaret = 0; | |
| 959 m_pTxtBuf->Clear(FALSE); | |
| 960 m_nCaret = 0; | |
| 961 } | |
| 962 void CFDE_TxtEdtEngine::RebuildParagraphs() { | |
| 963 RemoveAllParags(); | |
| 964 FX_WCHAR wChar = L' '; | |
| 965 int32_t nParagStart = 0; | |
| 966 int32_t nIndex = 0; | |
| 967 IFX_CharIter* pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf); | |
| 968 pIter->SetAt(0); | |
| 969 do { | |
| 970 wChar = pIter->GetChar(); | |
| 971 nIndex = pIter->GetAt(); | |
| 972 if (wChar == m_wLineEnd) { | |
| 973 CFDE_TxtEdtParag* pParag = new CFDE_TxtEdtParag(this); | |
| 974 pParag->m_nCharStart = nParagStart; | |
| 975 pParag->m_nCharCount = nIndex - nParagStart + 1; | |
| 976 pParag->m_nLineCount = -1; | |
| 977 m_ParagPtrArray.Add(pParag); | |
| 978 nParagStart = nIndex + 1; | |
| 979 } | |
| 980 } while (pIter->Next()); | |
| 981 pIter->Release(); | |
| 982 } | |
| 983 void CFDE_TxtEdtEngine::RemoveAllParags() { | |
| 984 int32_t nCount = m_ParagPtrArray.GetSize(); | |
| 985 int32_t i = 0; | |
| 986 for (i = 0; i < nCount; i++) { | |
| 987 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i]; | |
| 988 if (pParag) { | |
| 989 delete pParag; | |
| 990 } | |
| 991 } | |
| 992 m_ParagPtrArray.RemoveAll(); | |
| 993 } | |
| 994 void CFDE_TxtEdtEngine::RemoveAllPages() { | |
| 995 int32_t nCount = m_PagePtrArray.GetSize(); | |
| 996 int32_t i = 0; | |
| 997 for (i = 0; i < nCount; i++) { | |
| 998 IFDE_TxtEdtPage* pPage = m_PagePtrArray[i]; | |
| 999 if (pPage) { | |
| 1000 pPage->Release(); | |
| 1001 } | |
| 1002 } | |
| 1003 m_PagePtrArray.RemoveAll(); | |
| 1004 } | |
| 1005 void CFDE_TxtEdtEngine::UpdateParags() { | |
| 1006 int32_t nCount = m_ParagPtrArray.GetSize(); | |
| 1007 if (nCount == 0) { | |
| 1008 return; | |
| 1009 } | |
| 1010 CFDE_TxtEdtParag* pParag = NULL; | |
| 1011 int32_t nLineCount = 0; | |
| 1012 int32_t i = 0; | |
| 1013 for (i = 0; i < nCount; i++) { | |
| 1014 pParag = m_ParagPtrArray[i]; | |
| 1015 if (pParag->m_nLineCount == -1) { | |
| 1016 pParag->CalcLines(); | |
| 1017 } | |
| 1018 nLineCount += pParag->m_nLineCount; | |
| 1019 } | |
| 1020 m_nLineCount = nLineCount; | |
| 1021 } | |
| 1022 void CFDE_TxtEdtEngine::UpdatePages() { | |
| 1023 if (m_nLineCount == 0) { | |
| 1024 return; | |
| 1025 } | |
| 1026 int32_t nPageCount = (m_nLineCount - 1) / (m_nPageLineCount) + 1; | |
| 1027 int32_t nSize = m_PagePtrArray.GetSize(); | |
| 1028 if (nSize == nPageCount) { | |
| 1029 return; | |
| 1030 } | |
| 1031 if (nSize > nPageCount) { | |
| 1032 IFDE_TxtEdtPage* pPage = NULL; | |
| 1033 int32_t i = 0; | |
| 1034 for (i = nSize - 1; i >= nPageCount; i--) { | |
| 1035 pPage = m_PagePtrArray[i]; | |
| 1036 if (pPage) { | |
| 1037 pPage->Release(); | |
| 1038 } | |
| 1039 m_PagePtrArray.RemoveAt(i); | |
| 1040 } | |
| 1041 m_Param.pEventSink->On_PageCountChanged(this); | |
| 1042 return; | |
| 1043 } | |
| 1044 if (nSize < nPageCount) { | |
| 1045 IFDE_TxtEdtPage* pPage = NULL; | |
| 1046 int32_t i = 0; | |
| 1047 for (i = nSize; i < nPageCount; i++) { | |
| 1048 pPage = IFDE_TxtEdtPage::Create(this, i); | |
| 1049 m_PagePtrArray.Add(pPage); | |
| 1050 } | |
| 1051 m_Param.pEventSink->On_PageCountChanged(this); | |
| 1052 return; | |
| 1053 } | |
| 1054 } | |
| 1055 void CFDE_TxtEdtEngine::UpdateTxtBreak() { | |
| 1056 FX_DWORD dwStyle = m_pTextBreak->GetLayoutStyles(); | |
| 1057 if (m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines) { | |
| 1058 dwStyle &= ~FX_TXTLAYOUTSTYLE_SingleLine; | |
| 1059 } else { | |
| 1060 dwStyle |= FX_TXTLAYOUTSTYLE_SingleLine; | |
| 1061 } | |
| 1062 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
| 1063 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalLayout; | |
| 1064 } else { | |
| 1065 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalLayout; | |
| 1066 } | |
| 1067 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve) { | |
| 1068 dwStyle |= FX_TXTLAYOUTSTYLE_ReverseLine; | |
| 1069 } else { | |
| 1070 dwStyle &= ~FX_TXTLAYOUTSTYLE_ReverseLine; | |
| 1071 } | |
| 1072 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_RTL) { | |
| 1073 dwStyle |= FX_TXTLAYOUTSTYLE_RTLReadingOrder; | |
| 1074 } else { | |
| 1075 dwStyle &= ~FX_TXTLAYOUTSTYLE_RTLReadingOrder; | |
| 1076 } | |
| 1077 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) { | |
| 1078 dwStyle |= FX_TXTLAYOUTSTYLE_CombText; | |
| 1079 } else { | |
| 1080 dwStyle &= ~FX_TXTLAYOUTSTYLE_CombText; | |
| 1081 } | |
| 1082 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CharVertial) { | |
| 1083 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalChars; | |
| 1084 } else { | |
| 1085 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalChars; | |
| 1086 } | |
| 1087 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ExpandTab) { | |
| 1088 dwStyle |= FX_TXTLAYOUTSTYLE_ExpandTab; | |
| 1089 } else { | |
| 1090 dwStyle &= ~FX_TXTLAYOUTSTYLE_ExpandTab; | |
| 1091 } | |
| 1092 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicContext) { | |
| 1093 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicContext; | |
| 1094 } else { | |
| 1095 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicContext; | |
| 1096 } | |
| 1097 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicShapes) { | |
| 1098 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicShapes; | |
| 1099 } else { | |
| 1100 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicShapes; | |
| 1101 } | |
| 1102 m_pTextBreak->SetLayoutStyles(dwStyle); | |
| 1103 FX_DWORD dwAligment = 0; | |
| 1104 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Justified) { | |
| 1105 dwAligment |= FX_TXTLINEALIGNMENT_Justified; | |
| 1106 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Distributed) { | |
| 1107 dwAligment |= FX_TXTLINEALIGNMENT_Distributed; | |
| 1108 } | |
| 1109 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Center) { | |
| 1110 dwAligment |= FX_TXTLINEALIGNMENT_Center; | |
| 1111 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Right) { | |
| 1112 dwAligment |= FX_TXTLINEALIGNMENT_Right; | |
| 1113 } | |
| 1114 m_pTextBreak->SetAlignment(dwAligment); | |
| 1115 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
| 1116 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { | |
| 1117 m_pTextBreak->SetLineWidth(m_Param.fPlateHeight); | |
| 1118 } else { | |
| 1119 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX); | |
| 1120 } | |
| 1121 } else { | |
| 1122 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { | |
| 1123 m_pTextBreak->SetLineWidth(m_Param.fPlateWidth); | |
| 1124 } else { | |
| 1125 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX); | |
| 1126 } | |
| 1127 } | |
| 1128 m_nPageLineCount = m_Param.nLineCount; | |
| 1129 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) { | |
| 1130 FX_FLOAT fCombWidth = | |
| 1131 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical | |
| 1132 ? m_Param.fPlateHeight | |
| 1133 : m_Param.fPlateWidth; | |
| 1134 if (m_nLimit > 0) { | |
| 1135 fCombWidth /= m_nLimit; | |
| 1136 } | |
| 1137 m_pTextBreak->SetCombWidth(fCombWidth); | |
| 1138 } | |
| 1139 m_pTextBreak->SetFont(m_Param.pFont); | |
| 1140 m_pTextBreak->SetFontSize(m_Param.fFontSize); | |
| 1141 m_pTextBreak->SetTabWidth(m_Param.fTabWidth, m_Param.bTabEquidistant); | |
| 1142 m_pTextBreak->SetDefaultChar(m_Param.wDefChar); | |
| 1143 m_pTextBreak->SetParagraphBreakChar(m_Param.wLineBreakChar); | |
| 1144 m_pTextBreak->SetCharRotation(m_Param.nCharRotation); | |
| 1145 m_pTextBreak->SetLineBreakTolerance(m_Param.fFontSize * 0.2f); | |
| 1146 m_pTextBreak->SetHorizontalScale(m_Param.nHorzScale); | |
| 1147 m_pTextBreak->SetCharSpace(m_Param.fCharSpace); | |
| 1148 } | |
| 1149 FX_BOOL CFDE_TxtEdtEngine::ReplaceParagEnd(FX_WCHAR*& lpText, | |
| 1150 int32_t& nLength, | |
| 1151 FX_BOOL bPreIsCR) { | |
| 1152 for (int32_t i = 0; i < nLength; i++) { | |
| 1153 FX_WCHAR wc = lpText[i]; | |
| 1154 switch (wc) { | |
| 1155 case L'\r': { | |
| 1156 lpText[i] = m_wLineEnd; | |
| 1157 bPreIsCR = TRUE; | |
| 1158 } break; | |
| 1159 case L'\n': { | |
| 1160 if (bPreIsCR == TRUE) { | |
| 1161 int32_t nNext = i + 1; | |
| 1162 if (nNext < nLength) { | |
| 1163 FXSYS_memmove(lpText + i, lpText + nNext, | |
| 1164 (nLength - nNext) * sizeof(FX_WCHAR)); | |
| 1165 } | |
| 1166 i--; | |
| 1167 nLength--; | |
| 1168 bPreIsCR = FALSE; | |
| 1169 if (m_bAutoLineEnd) { | |
| 1170 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CRLF; | |
| 1171 m_bAutoLineEnd = FALSE; | |
| 1172 } | |
| 1173 } else { | |
| 1174 lpText[i] = m_wLineEnd; | |
| 1175 if (m_bAutoLineEnd) { | |
| 1176 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_LF; | |
| 1177 m_bAutoLineEnd = FALSE; | |
| 1178 } | |
| 1179 } | |
| 1180 } break; | |
| 1181 default: { | |
| 1182 if (bPreIsCR && m_bAutoLineEnd) { | |
| 1183 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CR; | |
| 1184 m_bAutoLineEnd = FALSE; | |
| 1185 } | |
| 1186 bPreIsCR = FALSE; | |
| 1187 } break; | |
| 1188 } | |
| 1189 } | |
| 1190 return bPreIsCR; | |
| 1191 } | |
| 1192 void CFDE_TxtEdtEngine::RecoverParagEnd(CFX_WideString& wsText) { | |
| 1193 FX_WCHAR wc = (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CR) ? L'\n' : L'\r'; | |
| 1194 if (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CRLF) { | |
| 1195 CFX_ArrayTemplate<int32_t> PosArr; | |
| 1196 int32_t nLength = wsText.GetLength(); | |
| 1197 int32_t i = 0; | |
| 1198 FX_WCHAR* lpPos = (FX_WCHAR*)(const FX_WCHAR*)wsText; | |
| 1199 for (i = 0; i < nLength; i++, lpPos++) { | |
| 1200 if (*lpPos == m_wLineEnd) { | |
| 1201 *lpPos = wc; | |
| 1202 PosArr.Add(i); | |
| 1203 } | |
| 1204 } | |
| 1205 const FX_WCHAR* lpSrcBuf = wsText.c_str(); | |
| 1206 CFX_WideString wsTemp; | |
| 1207 int32_t nCount = PosArr.GetSize(); | |
| 1208 FX_WCHAR* lpDstBuf = wsTemp.GetBuffer(nLength + nCount); | |
| 1209 int32_t nDstPos = 0; | |
| 1210 int32_t nSrcPos = 0; | |
| 1211 for (i = 0; i < nCount; i++) { | |
| 1212 int32_t nPos = PosArr[i]; | |
| 1213 int32_t nCopyLen = nPos - nSrcPos + 1; | |
| 1214 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, | |
| 1215 nCopyLen * sizeof(FX_WCHAR)); | |
| 1216 nDstPos += nCopyLen; | |
| 1217 nSrcPos += nCopyLen; | |
| 1218 lpDstBuf[nDstPos] = L'\n'; | |
| 1219 nDstPos++; | |
| 1220 } | |
| 1221 if (nSrcPos < nLength) { | |
| 1222 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, | |
| 1223 (nLength - nSrcPos) * sizeof(FX_WCHAR)); | |
| 1224 } | |
| 1225 wsTemp.ReleaseBuffer(nLength + nCount); | |
| 1226 wsText = wsTemp; | |
| 1227 } else { | |
| 1228 int32_t nLength = wsText.GetLength(); | |
| 1229 FX_WCHAR* lpBuf = (FX_WCHAR*)(const FX_WCHAR*)wsText; | |
| 1230 for (int32_t i = 0; i < nLength; i++, lpBuf++) { | |
| 1231 if (*lpBuf == m_wLineEnd) { | |
| 1232 *lpBuf = wc; | |
| 1233 } | |
| 1234 } | |
| 1235 } | |
| 1236 } | |
| 1237 int32_t CFDE_TxtEdtEngine::MovePage2Char(int32_t nIndex) { | |
| 1238 FXSYS_assert(nIndex >= 0); | |
| 1239 FXSYS_assert(nIndex <= m_pTxtBuf->GetTextLength()); | |
| 1240 if (m_nCaretPage >= 0) { | |
| 1241 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; | |
| 1242 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 1243 int32_t nPageCharStart = pPage->GetCharStart(); | |
| 1244 int32_t nPageCharCount = pPage->GetCharCount(); | |
| 1245 if (nIndex >= nPageCharStart && nIndex < nPageCharStart + nPageCharCount) { | |
| 1246 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 1247 return m_nCaretPage; | |
| 1248 } | |
| 1249 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 1250 } | |
| 1251 CFDE_TxtEdtParag* pParag = NULL; | |
| 1252 int32_t nLineCount = 0; | |
| 1253 int32_t nParagCount = m_ParagPtrArray.GetSize(); | |
| 1254 int32_t i = 0; | |
| 1255 for (i = 0; i < nParagCount; i++) { | |
| 1256 pParag = m_ParagPtrArray[i]; | |
| 1257 if (pParag->m_nCharStart <= nIndex && | |
| 1258 nIndex < (pParag->m_nCharStart + pParag->m_nCharCount)) { | |
| 1259 break; | |
| 1260 } | |
| 1261 nLineCount += pParag->m_nLineCount; | |
| 1262 } | |
| 1263 pParag->LoadParag(); | |
| 1264 int32_t nLineStart = -1; | |
| 1265 int32_t nLineCharCount = -1; | |
| 1266 for (i = 0; i < pParag->m_nLineCount; i++) { | |
| 1267 pParag->GetLineRange(i, nLineStart, nLineCharCount); | |
| 1268 if (nLineStart <= nIndex && nIndex < (nLineStart + nLineCharCount)) { | |
| 1269 break; | |
| 1270 } | |
| 1271 } | |
| 1272 FXSYS_assert(i < pParag->m_nLineCount); | |
| 1273 nLineCount += (i + 1); | |
| 1274 m_nCaretPage = (nLineCount - 1) / m_nPageLineCount + 1 - 1; | |
| 1275 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); | |
| 1276 pParag->UnloadParag(); | |
| 1277 return m_nCaretPage; | |
| 1278 } | |
| 1279 void CFDE_TxtEdtEngine::TextPos2ParagPos(int32_t nIndex, | |
| 1280 FDE_TXTEDTPARAGPOS& ParagPos) const { | |
| 1281 FXSYS_assert(nIndex >= 0 && nIndex < m_pTxtBuf->GetTextLength()); | |
| 1282 int32_t nCount = m_ParagPtrArray.GetSize(); | |
| 1283 int32_t nBgn = 0; | |
| 1284 int32_t nMid = 0; | |
| 1285 int32_t nEnd = nCount - 1; | |
| 1286 while (nEnd > nBgn) { | |
| 1287 nMid = (nBgn + nEnd) / 2; | |
| 1288 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nMid]; | |
| 1289 if (nIndex < pParag->m_nCharStart) { | |
| 1290 nEnd = nMid - 1; | |
| 1291 } else if (nIndex >= (pParag->m_nCharStart + pParag->m_nCharCount)) { | |
| 1292 nBgn = nMid + 1; | |
| 1293 } else { | |
| 1294 break; | |
| 1295 } | |
| 1296 } | |
| 1297 if (nBgn == nEnd) { | |
| 1298 nMid = nBgn; | |
| 1299 } | |
| 1300 FXSYS_assert(nIndex >= m_ParagPtrArray[nMid]->m_nCharStart && | |
| 1301 (nIndex < m_ParagPtrArray[nMid]->m_nCharStart + | |
| 1302 m_ParagPtrArray[nMid]->m_nCharCount)); | |
| 1303 ParagPos.nParagIndex = nMid; | |
| 1304 ParagPos.nCharIndex = nIndex - m_ParagPtrArray[nMid]->m_nCharStart; | |
| 1305 } | |
| 1306 int32_t CFDE_TxtEdtEngine::MoveForward(FX_BOOL& bBefore) { | |
| 1307 if (m_nCaret == m_pTxtBuf->GetTextLength() - 1) { | |
| 1308 return -1; | |
| 1309 } | |
| 1310 int32_t nCaret = m_nCaret; | |
| 1311 if ((nCaret + 1 < m_pTxtBuf->GetTextLength()) && | |
| 1312 (m_pTxtBuf->GetCharByIndex(nCaret) == L'\r') && | |
| 1313 (m_pTxtBuf->GetCharByIndex(nCaret + 1) == L'\n')) { | |
| 1314 nCaret++; | |
| 1315 } | |
| 1316 nCaret++; | |
| 1317 bBefore = TRUE; | |
| 1318 return nCaret; | |
| 1319 } | |
| 1320 int32_t CFDE_TxtEdtEngine::MoveBackward(FX_BOOL& bBefore) { | |
| 1321 if (m_nCaret == 0) { | |
| 1322 return FALSE; | |
| 1323 } | |
| 1324 int32_t nCaret = m_nCaret; | |
| 1325 if (nCaret > 2 && m_pTxtBuf->GetCharByIndex(nCaret - 1) == L'\n' && | |
| 1326 m_pTxtBuf->GetCharByIndex(nCaret - 2) == L'\r') { | |
| 1327 nCaret--; | |
| 1328 } | |
| 1329 nCaret--; | |
| 1330 bBefore = TRUE; | |
| 1331 return nCaret; | |
| 1332 } | |
| 1333 FX_BOOL CFDE_TxtEdtEngine::MoveUp(CFX_PointF& ptCaret) { | |
| 1334 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage); | |
| 1335 const CFX_RectF& rtContent = pPage->GetContentsBox(); | |
| 1336 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
| 1337 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 - m_Param.fLineSpace; | |
| 1338 ptCaret.y = m_fCaretPosReserve; | |
| 1339 FX_BOOL bLineReserve = | |
| 1340 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; | |
| 1341 if (ptCaret.x < rtContent.left) { | |
| 1342 if (bLineReserve) { | |
| 1343 if (m_nCaretPage == CountPages() - 1) { | |
| 1344 return FALSE; | |
| 1345 } | |
| 1346 } else { | |
| 1347 if (m_nCaretPage == 0) { | |
| 1348 return FALSE; | |
| 1349 } | |
| 1350 } | |
| 1351 if (bLineReserve) { | |
| 1352 m_nCaretPage++; | |
| 1353 } else { | |
| 1354 m_nCaretPage--; | |
| 1355 } | |
| 1356 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); | |
| 1357 ptCaret.x -= rtContent.left; | |
| 1358 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); | |
| 1359 ptCaret.x += pCurPage->GetContentsBox().right(); | |
| 1360 } | |
| 1361 } else { | |
| 1362 ptCaret.x = m_fCaretPosReserve; | |
| 1363 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 - m_Param.fLineSpace; | |
| 1364 if (ptCaret.y < rtContent.top) { | |
| 1365 if (m_nCaretPage == 0) { | |
| 1366 return FALSE; | |
| 1367 } | |
| 1368 ptCaret.y -= rtContent.top; | |
| 1369 m_nCaretPage--; | |
| 1370 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); | |
| 1371 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); | |
| 1372 ptCaret.y += pCurPage->GetContentsBox().bottom(); | |
| 1373 } | |
| 1374 } | |
| 1375 return TRUE; | |
| 1376 } | |
| 1377 FX_BOOL CFDE_TxtEdtEngine::MoveDown(CFX_PointF& ptCaret) { | |
| 1378 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage); | |
| 1379 const CFX_RectF& rtContent = pPage->GetContentsBox(); | |
| 1380 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
| 1381 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 + m_Param.fLineSpace; | |
| 1382 ptCaret.y = m_fCaretPosReserve; | |
| 1383 if (ptCaret.x >= rtContent.right()) { | |
| 1384 FX_BOOL bLineReserve = | |
| 1385 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; | |
| 1386 if (bLineReserve) { | |
| 1387 if (m_nCaretPage == 0) { | |
| 1388 return FALSE; | |
| 1389 } | |
| 1390 } else { | |
| 1391 if (m_nCaretPage == CountPages() - 1) { | |
| 1392 return FALSE; | |
| 1393 } | |
| 1394 } | |
| 1395 if (bLineReserve) { | |
| 1396 m_nCaretPage--; | |
| 1397 } else { | |
| 1398 m_nCaretPage++; | |
| 1399 } | |
| 1400 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); | |
| 1401 ptCaret.x -= rtContent.right(); | |
| 1402 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); | |
| 1403 ptCaret.x += pCurPage->GetContentsBox().left; | |
| 1404 } | |
| 1405 } else { | |
| 1406 ptCaret.x = m_fCaretPosReserve; | |
| 1407 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 + m_Param.fLineSpace; | |
| 1408 if (ptCaret.y >= rtContent.bottom()) { | |
| 1409 if (m_nCaretPage == CountPages() - 1) { | |
| 1410 return FALSE; | |
| 1411 } | |
| 1412 ptCaret.y -= rtContent.bottom(); | |
| 1413 m_nCaretPage++; | |
| 1414 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); | |
| 1415 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); | |
| 1416 ptCaret.y += pCurPage->GetContentsBox().top; | |
| 1417 } | |
| 1418 } | |
| 1419 return TRUE; | |
| 1420 } | |
| 1421 FX_BOOL CFDE_TxtEdtEngine::MoveLineStart() { | |
| 1422 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; | |
| 1423 FDE_TXTEDTPARAGPOS ParagPos; | |
| 1424 TextPos2ParagPos(nIndex, ParagPos); | |
| 1425 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; | |
| 1426 pParag->LoadParag(); | |
| 1427 int32_t nLineCount = pParag->m_nLineCount; | |
| 1428 int32_t i = 0; | |
| 1429 int32_t nStart = 0; | |
| 1430 int32_t nCount = 0; | |
| 1431 for (; i < nLineCount; i++) { | |
| 1432 pParag->GetLineRange(i, nStart, nCount); | |
| 1433 if (nIndex >= nStart && nIndex < nStart + nCount) { | |
| 1434 break; | |
| 1435 } | |
| 1436 } | |
| 1437 UpdateCaretRect(nStart, TRUE); | |
| 1438 pParag->UnloadParag(); | |
| 1439 return TRUE; | |
| 1440 } | |
| 1441 FX_BOOL CFDE_TxtEdtEngine::MoveLineEnd() { | |
| 1442 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; | |
| 1443 FDE_TXTEDTPARAGPOS ParagPos; | |
| 1444 TextPos2ParagPos(nIndex, ParagPos); | |
| 1445 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; | |
| 1446 pParag->LoadParag(); | |
| 1447 int32_t nLineCount = pParag->m_nLineCount; | |
| 1448 int32_t i = 0; | |
| 1449 int32_t nStart = 0; | |
| 1450 int32_t nCount = 0; | |
| 1451 for (; i < nLineCount; i++) { | |
| 1452 pParag->GetLineRange(i, nStart, nCount); | |
| 1453 if (nIndex >= nStart && nIndex < nStart + nCount) { | |
| 1454 break; | |
| 1455 } | |
| 1456 } | |
| 1457 nIndex = nStart + nCount - 1; | |
| 1458 FXSYS_assert(nIndex <= GetTextBufLength()); | |
| 1459 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex); | |
| 1460 FX_BOOL bBefore = FALSE; | |
| 1461 if (nIndex <= GetTextBufLength()) { | |
| 1462 if (wChar == L'\r') { | |
| 1463 bBefore = TRUE; | |
| 1464 } else if (wChar == L'\n' && nIndex > nStart) { | |
| 1465 bBefore = TRUE; | |
| 1466 nIndex--; | |
| 1467 wChar = m_pTxtBuf->GetCharByIndex(nIndex); | |
| 1468 if (wChar != L'\r') { | |
| 1469 nIndex++; | |
| 1470 } | |
| 1471 } | |
| 1472 } | |
| 1473 UpdateCaretRect(nIndex, bBefore); | |
| 1474 pParag->UnloadParag(); | |
| 1475 return TRUE; | |
| 1476 } | |
| 1477 FX_BOOL CFDE_TxtEdtEngine::MoveParagStart() { | |
| 1478 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; | |
| 1479 FDE_TXTEDTPARAGPOS ParagPos; | |
| 1480 TextPos2ParagPos(nIndex, ParagPos); | |
| 1481 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; | |
| 1482 UpdateCaretRect(pParag->m_nCharStart, TRUE); | |
| 1483 return TRUE; | |
| 1484 } | |
| 1485 FX_BOOL CFDE_TxtEdtEngine::MoveParagEnd() { | |
| 1486 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; | |
| 1487 FDE_TXTEDTPARAGPOS ParagPos; | |
| 1488 TextPos2ParagPos(nIndex, ParagPos); | |
| 1489 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; | |
| 1490 nIndex = pParag->m_nCharStart + pParag->m_nCharCount - 1; | |
| 1491 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex); | |
| 1492 if (wChar == L'\n' && nIndex > 0) { | |
| 1493 nIndex--; | |
| 1494 wChar = m_pTxtBuf->GetCharByIndex(nIndex); | |
| 1495 if (wChar != L'\r') { | |
| 1496 nIndex++; | |
| 1497 } | |
| 1498 } | |
| 1499 UpdateCaretRect(nIndex, TRUE); | |
| 1500 return TRUE; | |
| 1501 } | |
| 1502 FX_BOOL CFDE_TxtEdtEngine::MoveHome() { | |
| 1503 UpdateCaretRect(0, TRUE); | |
| 1504 return TRUE; | |
| 1505 } | |
| 1506 FX_BOOL CFDE_TxtEdtEngine::MoveEnd() { | |
| 1507 UpdateCaretRect(GetTextBufLength(), TRUE); | |
| 1508 return TRUE; | |
| 1509 } | |
| 1510 | |
| 1511 FX_BOOL CFDE_TxtEdtEngine::IsFitArea(CFX_WideString& wsText) { | |
| 1512 IFDE_TextOut* pTextOut = IFDE_TextOut::Create(); | |
| 1513 pTextOut->SetLineSpace(m_Param.fLineSpace); | |
| 1514 pTextOut->SetFont(m_Param.pFont); | |
| 1515 pTextOut->SetFontSize(m_Param.fFontSize); | |
| 1516 CFX_RectF rcText; | |
| 1517 FXSYS_memset(&rcText, 0, sizeof(rcText)); | |
| 1518 FX_DWORD dwStyle = 0; | |
| 1519 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) { | |
| 1520 dwStyle |= FDE_TTOSTYLE_SingleLine; | |
| 1521 } | |
| 1522 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { | |
| 1523 dwStyle |= FDE_TTOSTYLE_LineWrap; | |
| 1524 rcText.width = m_Param.fPlateWidth; | |
| 1525 } else { | |
| 1526 rcText.width = 65535; | |
| 1527 } | |
| 1528 pTextOut->SetStyles(dwStyle); | |
| 1529 wsText += L"\n"; | |
| 1530 pTextOut->CalcLogicSize(wsText, wsText.GetLength(), rcText); | |
| 1531 pTextOut->Release(); | |
| 1532 wsText.Delete(wsText.GetLength() - 1); | |
| 1533 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz) && | |
| 1534 (rcText.width > m_Param.fPlateWidth)) { | |
| 1535 return FALSE; | |
| 1536 } | |
| 1537 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) && | |
| 1538 (rcText.height > m_Param.fLineSpace * m_Param.nLineCount)) { | |
| 1539 return FALSE; | |
| 1540 } | |
| 1541 return TRUE; | |
| 1542 } | |
| 1543 void CFDE_TxtEdtEngine::UpdateCaretRect(int32_t nIndex, FX_BOOL bBefore) { | |
| 1544 MovePage2Char(nIndex); | |
| 1545 GetCaretRect(m_rtCaret, m_nCaretPage, nIndex, bBefore); | |
| 1546 m_nCaret = nIndex; | |
| 1547 m_bBefore = bBefore; | |
| 1548 if (!m_bBefore) { | |
| 1549 m_nCaret++; | |
| 1550 m_bBefore = TRUE; | |
| 1551 } | |
| 1552 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) | |
| 1553 ? m_rtCaret.top | |
| 1554 : m_rtCaret.left; | |
| 1555 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0); | |
| 1556 } | |
| 1557 void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret, | |
| 1558 int32_t nPageIndex, | |
| 1559 int32_t nCaret, | |
| 1560 FX_BOOL bBefore) { | |
| 1561 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; | |
| 1562 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 1563 FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText; | |
| 1564 int32_t nIndexInpage = nCaret - pPage->GetCharStart(); | |
| 1565 if (bBefore && bCombText && nIndexInpage > 0) { | |
| 1566 nIndexInpage--; | |
| 1567 bBefore = FALSE; | |
| 1568 } | |
| 1569 int32_t nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText); | |
| 1570 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
| 1571 if ((!FX_IsOdd(nBIDILevel) && !bBefore) || | |
| 1572 (FX_IsOdd(nBIDILevel) && bBefore)) { | |
| 1573 rtCaret.Offset(0, rtCaret.height - 1.0f); | |
| 1574 } | |
| 1575 if (rtCaret.height == 0 && rtCaret.top > 1.0f) { | |
| 1576 rtCaret.top -= 1.0f; | |
| 1577 } | |
| 1578 rtCaret.height = 1.0f; | |
| 1579 } else { | |
| 1580 if ((!FX_IsOdd(nBIDILevel) && !bBefore) || | |
| 1581 (FX_IsOdd(nBIDILevel) && bBefore)) { | |
| 1582 rtCaret.Offset(rtCaret.width - 1.0f, 0); | |
| 1583 } | |
| 1584 if (rtCaret.width == 0 && rtCaret.left > 1.0f) { | |
| 1585 rtCaret.left -= 1.0f; | |
| 1586 } | |
| 1587 rtCaret.width = 1.0f; | |
| 1588 } | |
| 1589 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 1590 } | |
| 1591 void CFDE_TxtEdtEngine::UpdateCaretIndex(const CFX_PointF& ptCaret) { | |
| 1592 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; | |
| 1593 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); | |
| 1594 m_nCaret = pPage->GetCharIndex(ptCaret, m_bBefore); | |
| 1595 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore); | |
| 1596 if (!m_bBefore) { | |
| 1597 m_nCaret++; | |
| 1598 m_bBefore = TRUE; | |
| 1599 } | |
| 1600 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage); | |
| 1601 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); | |
| 1602 } | |
| 1603 FX_BOOL CFDE_TxtEdtEngine::IsSelect() { | |
| 1604 return m_SelRangePtrArr.GetSize() > 0; | |
| 1605 } | |
| 1606 void CFDE_TxtEdtEngine::DeleteSelect() { | |
| 1607 int32_t nCountRange = CountSelRanges(); | |
| 1608 if (nCountRange > 0) { | |
| 1609 int32_t nSelStart; | |
| 1610 int32_t nSelCount; | |
| 1611 while (nCountRange > 0) { | |
| 1612 nSelCount = GetSelRange(--nCountRange, nSelStart); | |
| 1613 FDE_LPTXTEDTSELRANGE lpTemp = m_SelRangePtrArr[nCountRange]; | |
| 1614 delete lpTemp; | |
| 1615 m_SelRangePtrArr.RemoveAt(nCountRange); | |
| 1616 DeleteRange_DoRecord(nSelStart, nSelCount, TRUE); | |
| 1617 } | |
| 1618 ClearSelection(); | |
| 1619 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); | |
| 1620 m_Param.pEventSink->On_SelChanged(this); | |
| 1621 SetCaretPos(nSelStart, TRUE); | |
| 1622 return; | |
| 1623 } | |
| 1624 } | |
| 1625 IFDE_TxtEdtDoRecord* IFDE_TxtEdtDoRecord::Create( | |
| 1626 const CFX_ByteStringC& bsDoRecord) { | |
| 1627 const FX_CHAR* lpBuf = bsDoRecord.GetCStr(); | |
| 1628 int32_t nType = *((int32_t*)lpBuf); | |
| 1629 switch (nType) { | |
| 1630 case FDE_TXTEDT_DORECORD_INS: | |
| 1631 return new CFDE_TxtEdtDoRecord_Insert(bsDoRecord); | |
| 1632 case FDE_TXTEDT_DORECORD_DEL: | |
| 1633 return new CFDE_TxtEdtDoRecord_DeleteRange(bsDoRecord); | |
| 1634 default: | |
| 1635 break; | |
| 1636 } | |
| 1637 return NULL; | |
| 1638 } | |
| 1639 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert( | |
| 1640 const CFX_ByteStringC& bsDoRecord) { | |
| 1641 Deserialize(bsDoRecord); | |
| 1642 } | |
| 1643 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert( | |
| 1644 CFDE_TxtEdtEngine* pEngine, | |
| 1645 int32_t nCaret, | |
| 1646 const FX_WCHAR* lpText, | |
| 1647 int32_t nLength) | |
| 1648 : m_pEngine(pEngine), m_nCaret(nCaret) { | |
| 1649 FXSYS_assert(pEngine); | |
| 1650 FX_WCHAR* lpBuffer = m_wsInsert.GetBuffer(nLength); | |
| 1651 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR)); | |
| 1652 m_wsInsert.ReleaseBuffer(); | |
| 1653 } | |
| 1654 CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert() {} | |
| 1655 void CFDE_TxtEdtDoRecord_Insert::Release() { | |
| 1656 delete this; | |
| 1657 } | |
| 1658 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Undo() { | |
| 1659 if (m_pEngine->IsSelect()) { | |
| 1660 m_pEngine->ClearSelection(); | |
| 1661 } | |
| 1662 m_pEngine->Inner_DeleteRange(m_nCaret, m_wsInsert.GetLength()); | |
| 1663 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; | |
| 1664 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; | |
| 1665 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert; | |
| 1666 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); | |
| 1667 m_pEngine->SetCaretPos(m_nCaret, TRUE); | |
| 1668 return TRUE; | |
| 1669 } | |
| 1670 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Redo() { | |
| 1671 m_pEngine->Inner_Insert(m_nCaret, m_wsInsert.c_str(), m_wsInsert.GetLength()); | |
| 1672 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; | |
| 1673 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; | |
| 1674 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert; | |
| 1675 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); | |
| 1676 m_pEngine->SetCaretPos(m_nCaret, FALSE); | |
| 1677 return TRUE; | |
| 1678 } | |
| 1679 void CFDE_TxtEdtDoRecord_Insert::Serialize(CFX_ByteString& bsDoRecord) const { | |
| 1680 CFX_ArchiveSaver ArchiveSaver; | |
| 1681 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_INS); | |
| 1682 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine; | |
| 1683 ArchiveSaver << m_nCaret; | |
| 1684 ArchiveSaver << m_wsInsert; | |
| 1685 int32_t nLength = ArchiveSaver.GetLength(); | |
| 1686 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); | |
| 1687 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); | |
| 1688 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); | |
| 1689 bsDoRecord.ReleaseBuffer(nLength); | |
| 1690 } | |
| 1691 void CFDE_TxtEdtDoRecord_Insert::Deserialize( | |
| 1692 const CFX_ByteStringC& bsDoRecord) { | |
| 1693 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), | |
| 1694 bsDoRecord.GetLength()); | |
| 1695 int32_t nType = 0; | |
| 1696 ArchiveLoader >> nType; | |
| 1697 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_INS); | |
| 1698 int32_t nEngine = 0; | |
| 1699 ArchiveLoader >> nEngine; | |
| 1700 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; | |
| 1701 ArchiveLoader >> m_nCaret; | |
| 1702 ArchiveLoader >> m_wsInsert; | |
| 1703 } | |
| 1704 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange( | |
| 1705 const CFX_ByteStringC& bsDoRecord) { | |
| 1706 Deserialize(bsDoRecord); | |
| 1707 } | |
| 1708 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange( | |
| 1709 CFDE_TxtEdtEngine* pEngine, | |
| 1710 int32_t nIndex, | |
| 1711 int32_t nCaret, | |
| 1712 const CFX_WideString& wsRange, | |
| 1713 FX_BOOL bSel) | |
| 1714 : m_pEngine(pEngine), | |
| 1715 m_bSel(bSel), | |
| 1716 m_nIndex(nIndex), | |
| 1717 m_nCaret(nCaret), | |
| 1718 m_wsRange(wsRange) { | |
| 1719 FXSYS_assert(pEngine); | |
| 1720 } | |
| 1721 CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange() {} | |
| 1722 void CFDE_TxtEdtDoRecord_DeleteRange::Release() { | |
| 1723 delete this; | |
| 1724 } | |
| 1725 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Undo() { | |
| 1726 if (m_pEngine->IsSelect()) { | |
| 1727 m_pEngine->ClearSelection(); | |
| 1728 } | |
| 1729 m_pEngine->Inner_Insert(m_nIndex, m_wsRange.c_str(), m_wsRange.GetLength()); | |
| 1730 if (m_bSel) { | |
| 1731 m_pEngine->AddSelRange(m_nIndex, m_wsRange.GetLength()); | |
| 1732 } | |
| 1733 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; | |
| 1734 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; | |
| 1735 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange; | |
| 1736 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); | |
| 1737 m_pEngine->SetCaretPos(m_nCaret, TRUE); | |
| 1738 return TRUE; | |
| 1739 } | |
| 1740 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Redo() { | |
| 1741 m_pEngine->Inner_DeleteRange(m_nIndex, m_wsRange.GetLength()); | |
| 1742 if (m_bSel) { | |
| 1743 m_pEngine->RemoveSelRange(m_nIndex, m_wsRange.GetLength()); | |
| 1744 } | |
| 1745 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; | |
| 1746 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; | |
| 1747 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange; | |
| 1748 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); | |
| 1749 m_pEngine->SetCaretPos(m_nIndex, TRUE); | |
| 1750 return TRUE; | |
| 1751 } | |
| 1752 void CFDE_TxtEdtDoRecord_DeleteRange::Serialize( | |
| 1753 CFX_ByteString& bsDoRecord) const { | |
| 1754 CFX_ArchiveSaver ArchiveSaver; | |
| 1755 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_DEL); | |
| 1756 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine; | |
| 1757 ArchiveSaver << (int32_t)m_bSel; | |
| 1758 ArchiveSaver << m_nIndex; | |
| 1759 ArchiveSaver << m_nCaret; | |
| 1760 ArchiveSaver << m_wsRange; | |
| 1761 int32_t nLength = ArchiveSaver.GetLength(); | |
| 1762 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); | |
| 1763 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); | |
| 1764 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); | |
| 1765 bsDoRecord.ReleaseBuffer(nLength); | |
| 1766 } | |
| 1767 void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize( | |
| 1768 const CFX_ByteStringC& bsDoRecord) { | |
| 1769 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), | |
| 1770 bsDoRecord.GetLength()); | |
| 1771 int32_t nType = 0; | |
| 1772 ArchiveLoader >> nType; | |
| 1773 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_DEL); | |
| 1774 int32_t nEngine = 0; | |
| 1775 ArchiveLoader >> nEngine; | |
| 1776 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; | |
| 1777 int32_t iSel = 0; | |
| 1778 ArchiveLoader >> iSel; | |
| 1779 m_bSel = !!iSel; | |
| 1780 ArchiveLoader >> m_nIndex; | |
| 1781 ArchiveLoader >> m_nCaret; | |
| 1782 ArchiveLoader >> m_wsRange; | |
| 1783 } | |
| OLD | NEW |