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 <algorithm> 8 9 #include "xfa/src/foxitlib.h" 10 #include "xfa/src/fee/include/ifde_txtedtengine.h" 11 #include "xfa/src/fee/include/ifde_txtedtbuf.h" 12 #include "xfa/src/fee/include/ifde_txtedtpage.h" 13 #include "fde_txtedtengine.h" 14 #include "fde_txtedtparag.h" 15 #include "fde_txtedtbuf.h" 16 #ifdef FDE_USEFORMATBLOCK 17 #include "fde_txtedtblock.h" 18 #endif 19 #define FDE_PAGEWIDTH_MAX 0xFFFF 20 #define FDE_TXTPLATESIZE (1024 * 12) 21 #define FDE_UNICODE_PARAGRAPH_SPERATOR (0x2029) 22 #define FDE_TXTEDT_DORECORD_INS 0 23 #define FDE_TXTEDT_DORECORD_DEL 1 24 #ifdef FDE_USEFORMATBLOCK 25 #define FDE_TXTEDT_DORECORD_FORMATINS 3 26 #define FDE_TXTEDT_DORECORD_FORMATDEL 4 27 #define FDE_TXTEDT_DORECORD_FORMATREP 5 28 #define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9 29 #define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB 30 #endif 31 IFDE_TxtEdtEngine* IFDE_TxtEdtEngine::Create() { 32 return new CFDE_TxtEdtEngine(); 33 } 34 CFDE_TxtEdtEngine::CFDE_TxtEdtEngine() 35 : m_pTextBreak(nullptr), 36 m_nPageLineCount(20), 37 m_nLineCount(0), 38 m_nAnchorPos(-1), 39 m_nLayoutPos(0), 40 m_fCaretPosReserve(0.0), 41 m_nCaret(0), 42 m_bBefore(TRUE), 43 m_nCaretPage(0), 44 m_dwFindFlags(0), 45 m_bLock(FALSE), 46 m_nLimit(0), 47 m_wcAliasChar(L'*'), 48 #ifdef FDE_USEFORMATBLOCK 49 m_nFixLength(-1), // FIXME: no such member => USEFORMATBLOCK can't work. 50 #endif 51 m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto), 52 m_bAutoLineEnd(TRUE), 53 m_wLineEnd(FDE_UNICODE_PARAGRAPH_SPERATOR) { 54 FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF)); 55 m_pTxtBuf = new CFDE_TxtEdtBuf(); 56 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); 57 } 58 CFDE_TxtEdtEngine::~CFDE_TxtEdtEngine() { 59 if (m_pTxtBuf) { 60 m_pTxtBuf->Release(); 61 m_pTxtBuf = NULL; 62 } 63 if (m_pTextBreak) { 64 m_pTextBreak->Release(); 65 m_pTextBreak = NULL; 66 } 67 #ifdef FDE_USEFORMATBLOCK 68 int32_t nBlockCount = m_BlockArray.GetSize(); 69 if (nBlockCount > 0) { 70 int32_t i = 0; 71 for (; i < nBlockCount; i++) { 72 CFDE_TxtEdtBlock* pBlock = m_BlockArray[i]; 73 delete pBlock; 74 } 75 m_BlockArray.RemoveAll(); 76 } 77 #endif 78 RemoveAllParags(); 79 RemoveAllPages(); 80 m_Param.pEventSink = NULL; 81 ClearSelection(); 82 } 83 void CFDE_TxtEdtEngine::Release() { 84 delete this; 85 } 86 void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS& params) { 87 if (m_pTextBreak == NULL) { 88 m_pTextBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None); 89 } 90 FXSYS_memcpy(&m_Param, ¶ms, sizeof(FDE_TXTEDTPARAMS)); 91 m_wLineEnd = params.wLineBreakChar; 92 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); 93 UpdateTxtBreak(); 94 } 95 const FDE_TXTEDTPARAMS* CFDE_TxtEdtEngine::GetEditParams() const { 96 return &m_Param; 97 } 98 int32_t CFDE_TxtEdtEngine::CountPages() const { 99 if (m_nLineCount == 0) { 100 return 0; 101 } 102 return ((m_nLineCount - 1) / m_nPageLineCount) + 1; 103 } 104 IFDE_TxtEdtPage* CFDE_TxtEdtEngine::GetPage(int32_t nIndex) { 105 if (m_PagePtrArray.GetSize() <= nIndex) { 106 return NULL; 107 } 108 return (IFDE_TxtEdtPage*)m_PagePtrArray[nIndex]; 109 } 110 FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(int32_t nChunkSize) { 111 return m_pTxtBuf->SetChunkSize(nChunkSize); 112 } 113 void CFDE_TxtEdtEngine::SetTextByStream(IFX_Stream* pStream) { 114 ResetEngine(); 115 int32_t nIndex = 0; 116 if (pStream != NULL && pStream->GetLength()) { 117 int32_t nStreamLength = pStream->GetLength(); 118 FX_BOOL bValid = TRUE; 119 if (m_nLimit > 0 && nStreamLength > m_nLimit) { 120 bValid = FALSE; 121 } 122 FX_BOOL bPreIsCR = FALSE; 123 if (bValid) { 124 uint8_t bom[4]; 125 int32_t nPos = pStream->GetBOM(bom); 126 pStream->Seek(FX_STREAMSEEK_Begin, nPos); 127 int32_t nPlateSize = std::min(nStreamLength, m_pTxtBuf->GetChunkSize()); 128 FX_WCHAR* lpwstr = FX_Alloc(FX_WCHAR, nPlateSize); 129 FX_BOOL bEos = false; 130 while (!bEos) { 131 int32_t nRead = pStream->ReadString(lpwstr, nPlateSize, bEos); 132 bPreIsCR = ReplaceParagEnd(lpwstr, nRead, bPreIsCR); 133 m_pTxtBuf->Insert(nIndex, lpwstr, nRead); 134 nIndex += nRead; 135 } 136 FX_Free(lpwstr); 137 } 138 } 139 m_pTxtBuf->Insert(nIndex, &m_wLineEnd, 1); 140 RebuildParagraphs(); 141 } 142 void CFDE_TxtEdtEngine::SetText(const CFX_WideString& wsText) { 143 ResetEngine(); 144 int32_t nLength = wsText.GetLength(); 145 if (nLength > 0) { 146 CFX_WideString wsTemp; 147 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength); 148 FXSYS_memcpy(lpBuffer, wsText.c_str(), nLength * sizeof(FX_WCHAR)); 149 ReplaceParagEnd(lpBuffer, nLength, FALSE); 150 wsTemp.ReleaseBuffer(nLength); 151 if (m_nLimit > 0 && nLength > m_nLimit) { 152 wsTemp.Delete(m_nLimit, nLength - m_nLimit); 153 nLength = m_nLimit; 154 } 155 m_pTxtBuf->SetText(wsTemp); 156 } 157 m_pTxtBuf->Insert(nLength, &m_wLineEnd, 1); 158 RebuildParagraphs(); 159 } 160 int32_t CFDE_TxtEdtEngine::GetTextLength() const { 161 return GetTextBufLength(); 162 } 163 void CFDE_TxtEdtEngine::GetText(CFX_WideString& wsText, 164 int32_t nStart, 165 int32_t nCount) { 166 int32_t nTextBufLength = GetTextBufLength(); 167 if (nCount == -1) { 168 nCount = nTextBufLength - nStart; 169 } 170 #ifdef FDE_USEFORMATBLOCK 171 int32_t nBlockCount = m_BlockArray.GetSize(); 172 if (nBlockCount == 0 || m_wsFixText.IsEmpty()) { 173 m_pTxtBuf->GetRange(wsText, nStart, nCount); 174 return; 175 } 176 CFX_WideString wsTemp; 177 const FX_WCHAR* lpFixBuffer = const FX_WCHAR * (m_wsFixText); 178 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nTextBufLength); 179 int32_t nRealLength = 0; 180 int32_t nPrePos = 0; 181 for (int32_t i = 0; i < nBlockCount; i++) { 182 CFDE_TxtEdtBlock* pBlock = m_BlockArray[i]; 183 int32_t nPos = pBlock->GetPos(); 184 int32_t nCopyLength = nPos - nPrePos; 185 FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos, 186 nCopyLength * sizeof(FX_WCHAR)); 187 nRealLength += nCopyLength; 188 nPrePos = nPos; 189 CFX_WideString wsBlock; 190 pBlock->GetRealText(wsBlock); 191 nCopyLength = wsBlock.GetLength(); 192 FXSYS_memcpy(lpBuffer + nRealLength, const FX_WCHAR*(wsBlock), 193 nCopyLength * sizeof(FX_WCHAR)); 194 nRealLength += nCopyLength; 195 } 196 int32_t nLeftLength = m_wsFixText.GetLength() - nPrePos; 197 if (nLeftLength > 0) { 198 FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos, 199 nLeftLength * sizeof(FX_WCHAR)); 200 nRealLength += nLeftLength; 201 } 202 wsTemp.ReleaseBuffer(nRealLength); 203 int32_t nRealBgn = GetRealIndex(nStart); 204 int32_t nRealEnd = GetRealIndex(nStart + nCount - 1); 205 int32_t nRealCount = nRealEnd - nRealBgn; 206 FX_WCHAR* lpDestBuf = wsText.GetBuffer(nRealCount); 207 FXSYS_memcpy(lpDestBuf, const FX_WCHAR*(wsTemp) + nRealBgn, 208 nRealCount * sizeof(FX_WCHAR)); 209 wsText.ReleaseBuffer(); 210 #else 211 m_pTxtBuf->GetRange(wsText, nStart, nCount); 212 RecoverParagEnd(wsText); 213 return; 214 #endif 215 } 216 void CFDE_TxtEdtEngine::ClearText() { 217 DeleteRange(0, -1); 218 } 219 int32_t CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret) const { 220 rtCaret = m_rtCaret; 221 return m_nCaret; 222 } 223 int32_t CFDE_TxtEdtEngine::GetCaretPos() const { 224 if (IsLocked()) { 225 return 0; 226 } 227 return m_nCaret + (m_bBefore ? 0 : 1); 228 } 229 int32_t CFDE_TxtEdtEngine::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) { 230 if (IsLocked()) { 231 return 0; 232 } 233 FXSYS_assert(nIndex >= 0 && nIndex <= GetTextBufLength()); 234 if (m_PagePtrArray.GetSize() <= m_nCaretPage) { 235 return 0; 236 } 237 #ifdef FDE_USEFORMATBLOCK 238 if (m_BlockArray.GetSize() > 0) { 239 nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_MIDDLE, bBefore); 240 } 241 #endif 242 m_bBefore = bBefore; 243 m_nCaret = nIndex; 244 MovePage2Char(m_nCaret); 245 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore); 246 if (!m_bBefore) { 247 m_nCaret++; 248 m_bBefore = TRUE; 249 } 250 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) 251 ? m_rtCaret.top 252 : m_rtCaret.left; 253 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0); 254 m_nAnchorPos = -1; 255 return m_nCaret; 256 } 257 int32_t CFDE_TxtEdtEngine::MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret, 258 FX_BOOL bShift, 259 FX_BOOL bCtrl) { 260 if (IsLocked()) { 261 return 0; 262 } 263 if (m_PagePtrArray.GetSize() <= m_nCaretPage) { 264 return 0; 265 } 266 FX_BOOL bSelChange = FALSE; 267 if (IsSelect()) { 268 ClearSelection(); 269 bSelChange = TRUE; 270 } 271 if (bShift) { 272 if (m_nAnchorPos == -1) { 273 m_nAnchorPos = m_nCaret; 274 } 275 } else { 276 m_nAnchorPos = -1; 277 } 278 FX_BOOL bVertical = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical; 279 switch (eMoveCaret) { 280 case MC_Left: { 281 if (bVertical) { 282 CFX_PointF ptCaret; 283 if (MoveUp(ptCaret)) { 284 UpdateCaretIndex(ptCaret); 285 } 286 } else { 287 FX_BOOL bBefore = TRUE; 288 int32_t nIndex = MoveBackward(bBefore); 289 #ifdef FDE_USEFORMATBLOCK 290 if (m_BlockArray.GetSize()) { 291 nIndex = 292 NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore); 293 if (nIndex < 0) { 294 return m_nCaret; 295 } 296 } 297 #endif 298 if (nIndex >= 0) { 299 UpdateCaretRect(nIndex, bBefore); 300 } 301 } 302 } break; 303 case MC_Right: { 304 if (bVertical) { 305 CFX_PointF ptCaret; 306 if (MoveDown(ptCaret)) { 307 UpdateCaretIndex(ptCaret); 308 } 309 } else { 310 FX_BOOL bBefore = TRUE; 311 int32_t nIndex = MoveForward(bBefore); 312 #ifdef FDE_USEFORMATBLOCK 313 if (m_BlockArray.GetSize()) { 314 if (nIndex == -1) { 315 nIndex = GetTextBufLength(); 316 } 317 nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore); 318 } 319 #endif 320 if (nIndex >= 0) { 321 UpdateCaretRect(nIndex, bBefore); 322 } 323 } 324 } break; 325 case MC_Up: { 326 if (bVertical) { 327 FX_BOOL bBefore = TRUE; 328 int32_t nIndex = MoveBackward(bBefore); 329 #ifdef FDE_USEFORMATBLOCK 330 if (m_BlockArray.GetSize()) { 331 nIndex = 332 NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore); 333 } 334 #endif 335 if (nIndex >= 0) { 336 UpdateCaretRect(nIndex, bBefore); 337 } 338 } else { 339 CFX_PointF ptCaret; 340 if (MoveUp(ptCaret)) { 341 UpdateCaretIndex(ptCaret); 342 } 343 } 344 } break; 345 case MC_Down: { 346 if (bVertical) { 347 FX_BOOL bBefore = TRUE; 348 int32_t nIndex = MoveForward(bBefore); 349 #ifdef FDE_USEFORMATBLOCK 350 if (m_BlockArray.GetSize()) { 351 nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore); 352 } 353 #endif 354 if (nIndex >= 0) { 355 UpdateCaretRect(nIndex, bBefore); 356 } 357 } else { 358 CFX_PointF ptCaret; 359 if (MoveDown(ptCaret)) { 360 UpdateCaretIndex(ptCaret); 361 } 362 } 363 } break; 364 case MC_WordBackward: 365 break; 366 case MC_WordForward: 367 break; 368 case MC_LineStart: 369 MoveLineStart(); 370 break; 371 case MC_LineEnd: 372 MoveLineEnd(); 373 break; 374 case MC_ParagStart: 375 MoveParagStart(); 376 break; 377 case MC_ParagEnd: 378 MoveParagEnd(); 379 break; 380 case MC_PageDown: 381 break; 382 case MC_PageUp: 383 break; 384 case MC_Home: 385 MoveHome(); 386 break; 387 case MC_End: 388 MoveEnd(); 389 break; 390 default: 391 break; 392 } 393 if (bShift && m_nAnchorPos != -1 && (m_nAnchorPos != m_nCaret)) { 394 AddSelRange(std::min(m_nAnchorPos, m_nCaret), 395 FXSYS_abs(m_nAnchorPos - m_nCaret)); 396 m_Param.pEventSink->On_SelChanged(this); 397 } 398 if (bSelChange) { 399 m_Param.pEventSink->On_SelChanged(this); 400 } 401 return m_nCaret; 402 } 403 void CFDE_TxtEdtEngine::Lock() { 404 m_bLock = TRUE; 405 } 406 void CFDE_TxtEdtEngine::Unlock() { 407 m_bLock = FALSE; 408 } 409 FX_BOOL CFDE_TxtEdtEngine::IsLocked() const { 410 return m_bLock; 411 } 412 int32_t CFDE_TxtEdtEngine::Insert(int32_t nStart, 413 const FX_WCHAR* lpText, 414 int32_t nLength) { 415 if (IsLocked()) { 416 return FDE_TXTEDT_MODIFY_RET_F_Locked; 417 } 418 #ifdef FDE_USEFORMATBLOCK 419 int32_t nBlockCount = m_BlockArray.GetSize(); 420 if (nBlockCount) { 421 if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_TAB && nLength == 1 && 422 lpText[0] == L'\t') { 423 return Move2NextEditableField(nStart) ? FDE_TXTEDT_MODIFY_RET_T_Tab 424 : FDE_TXTEDT_MODIFY_RET_F_Tab; 425 } 426 int32_t nSelRangeCount = CountSelRanges(); 427 if (nSelRangeCount > 0) { 428 if (nSelRangeCount > 1) { 429 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 430 } 431 int32_t nSelStart; 432 int32_t nSelCount; 433 nSelCount = GetSelRange(0, nSelStart); 434 int32_t nSelEnd = nSelStart + nSelCount; 435 int32_t nBgn = 0; 436 int32_t nEnd = 0; 437 CFDE_TxtEdtField* pField = NULL; 438 FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField); 439 if (nSelEnd > nEnd) { 440 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 441 } 442 if (bInField) { 443 pField->Backup(); 444 FX_BOOL bBefore = FALSE; 445 CFX_WideString wsDel; 446 int32_t nCaret; 447 int32_t nIndexInField = nSelStart - nBgn; 448 int32_t nRet = pField->Replace(nSelStart - nBgn, nSelCount, 449 CFX_WideStringC(lpText, nLength), wsDel, 450 nCaret, bBefore); 451 switch (nRet) { 452 case FDE_FORMAT_FIELD_INSERT_RET_F_FULL: 453 pField->Restore(); 454 return FDE_TXTEDT_MODIFY_RET_F_Full; 455 case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE: 456 pField->Restore(); 457 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 458 default: 459 break; 460 } 461 CFX_WideString wsField; 462 pField->GetFieldText(wsField); 463 if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(), 464 pField->GetIndex(), wsField, 465 0)) { 466 pField->Restore(); 467 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 468 } 469 CFX_WideString wsDisplay; 470 pField->GetDisplayText(wsDisplay); 471 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || 472 (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) { 473 CFX_WideString wsText; 474 GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1, 475 const FX_WCHAR*(wsDisplay), wsDisplay.GetLength()); 476 if (!IsFitArea(wsText)) { 477 pField->Restore(); 478 return FDE_TXTEDT_MODIFY_RET_F_Full; 479 } 480 } 481 Replace(nBgn, nEnd - nBgn + 1, wsDisplay); 482 int32_t nNewCaret = nBgn + nCaret; 483 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 484 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldReplace( 485 this, m_nCaret, nNewCaret, pField, nIndexInField, nBgn, 486 wsDisplay.GetLength(), wsDel, CFX_WideStringC(lpText, nLength), 487 TRUE); 488 CFX_ByteString bsDoRecord; 489 pRecord->Serialize(bsDoRecord); 490 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 491 pRecord->Release(); 492 } 493 SetCaretPos(nBgn + nCaret, bBefore); 494 return FDE_TXTEDT_MODIFY_RET_S_Normal; 495 } 496 } 497 int32_t nBgn = 0; 498 int32_t nEnd = 0; 499 CFDE_TxtEdtField* pField = NULL; 500 FX_BOOL bInField = GetFieldBoundary(m_nCaret, nBgn, nEnd, pField); 501 int32_t nCaretInField = m_nCaret - nBgn; 502 FX_BOOL bBefore = FALSE; 503 if (bInField) { 504 pField->Backup(); 505 CFX_WideStringC wsIns(lpText, nLength); 506 int32_t nRet = 507 pField->Insert(nCaretInField, wsIns, nCaretInField, bBefore); 508 FX_BOOL bFull = FALSE; 509 switch (nRet) { 510 case FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL: 511 break; 512 case FDE_FORMAT_FIELD_INSERT_RET_S_FULL: 513 bFull = TRUE; 514 break; 515 case FDE_FORMAT_FIELD_INSERT_RET_F_FULL: 516 return FDE_TXTEDT_MODIFY_RET_F_Full; 517 case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE: 518 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 519 default: 520 return FDE_TXTEDT_MODIFY_RET_F_Normal; 521 } 522 CFX_WideString wsField; 523 pField->GetFieldText(wsField); 524 if (!m_Param.pEventSink->On_ValidateField( 525 this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) { 526 pField->Restore(); 527 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 528 } 529 CFX_WideString wsDisplay; 530 pField->GetDisplayText(wsDisplay); 531 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || 532 (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) { 533 CFX_WideString wsText; 534 GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1, 535 const FX_WCHAR*(wsDisplay), wsDisplay.GetLength()); 536 if (!IsFitArea(wsText)) { 537 pField->Restore(); 538 return FDE_TXTEDT_MODIFY_RET_F_Full; 539 } 540 } 541 Replace(nBgn, nEnd - nBgn + 1, wsDisplay); 542 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 543 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldInsert( 544 this, m_nCaret, pField, m_nCaret - nBgn, nBgn, nEnd - nBgn + 1, 545 wsDisplay.GetLength(), CFX_WideStringC(lpText, nLength), FALSE); 546 CFX_ByteString bsDoRecord; 547 pRecord->Serialize(bsDoRecord); 548 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 549 pRecord->Release(); 550 } 551 int32_t nCaretPos = nBgn + nCaretInField; 552 if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_AUTO && bFull && 553 nCaretPos == nEnd) { 554 if (Move2NextEditableField(nEnd, TRUE, FALSE)) { 555 return TRUE; 556 } 557 } 558 SetCaretPos(nCaretPos, bBefore); 559 return bFull ? FDE_TXTEDT_MODIFY_RET_S_Full 560 : FDE_TXTEDT_MODIFY_RET_S_Normal; 561 } 562 FXSYS_assert(0); 563 return FDE_TXTEDT_MODIFY_RET_F_Normal; 564 } 565 #endif 566 CFX_WideString wsTemp; 567 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength); 568 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR)); 569 ReplaceParagEnd(lpBuffer, nLength, FALSE); 570 wsTemp.ReleaseBuffer(nLength); 571 FX_BOOL bPart = FALSE; 572 if (m_nLimit > 0) { 573 int32_t nTotalLength = GetTextBufLength(); 574 int32_t nCount = m_SelRangePtrArr.GetSize(); 575 for (int32_t i = 0; i < nCount; i++) { 576 FDE_LPTXTEDTSELRANGE lpSelRange = m_SelRangePtrArr.GetAt(i); 577 nTotalLength -= lpSelRange->nCount; 578 } 579 int32_t nExpectLength = nTotalLength + nLength; 580 if (nTotalLength == m_nLimit) { 581 return FDE_TXTEDT_MODIFY_RET_F_Full; 582 } 583 if (nExpectLength > m_nLimit) { 584 nLength -= (nExpectLength - m_nLimit); 585 bPart = TRUE; 586 } 587 } 588 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || 589 (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) { 590 int32_t nTemp = nLength; 591 if (m_Param.dwMode & FDE_TEXTEDITMODE_Password) { 592 CFX_WideString wsText; 593 while (nLength > 0) { 594 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); 595 int32_t nTotal = wsText.GetLength(); 596 FX_WCHAR* lpBuf = wsText.GetBuffer(nTotal); 597 for (int32_t i = 0; i < nTotal; i++) { 598 lpBuf[i] = m_wcAliasChar; 599 } 600 wsText.ReleaseBuffer(nTotal); 601 if (IsFitArea(wsText)) { 602 break; 603 } 604 nLength--; 605 } 606 } else { 607 CFX_WideString wsText; 608 while (nLength > 0) { 609 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); 610 if (IsFitArea(wsText)) { 611 break; 612 } 613 nLength--; 614 } 615 } 616 if (nLength == 0) { 617 return FDE_TXTEDT_MODIFY_RET_F_Full; 618 } 619 if (nLength < nTemp) { 620 bPart = TRUE; 621 } 622 } 623 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { 624 CFX_WideString wsText; 625 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength); 626 if (!m_Param.pEventSink->On_Validate(this, wsText)) { 627 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 628 } 629 } 630 if (IsSelect()) { 631 DeleteSelect(); 632 } 633 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 634 IFDE_TxtEdtDoRecord* pRecord = 635 new CFDE_TxtEdtDoRecord_Insert(this, m_nCaret, lpBuffer, nLength); 636 CFX_ByteString bsDoRecord; 637 pRecord->Serialize(bsDoRecord); 638 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 639 pRecord->Release(); 640 } 641 GetText(m_ChangeInfo.wsPrevText, 0); 642 Inner_Insert(m_nCaret, lpBuffer, nLength); 643 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; 644 m_ChangeInfo.wsInsert = CFX_WideString(lpBuffer, nLength); 645 nStart = m_nCaret; 646 nStart += nLength; 647 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1); 648 FX_BOOL bBefore = TRUE; 649 if (wChar != L'\n' && wChar != L'\r') { 650 nStart--; 651 bBefore = FALSE; 652 } 653 SetCaretPos(nStart, bBefore); 654 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); 655 return bPart ? FDE_TXTEDT_MODIFY_RET_S_Part : FDE_TXTEDT_MODIFY_RET_S_Normal; 656 } 657 int32_t CFDE_TxtEdtEngine::Delete(int32_t nStart, FX_BOOL bBackspace) { 658 if (IsLocked()) { 659 return FDE_TXTEDT_MODIFY_RET_F_Locked; 660 } 661 if (IsSelect()) { 662 DeleteSelect(); 663 return FDE_TXTEDT_MODIFY_RET_S_Normal; 664 } 665 #ifdef FDE_USEFORMATBLOCK 666 int32_t nBlockCount = m_BlockArray.GetSize(); 667 if (nBlockCount > 0) { 668 if (bBackspace) { 669 nStart--; 670 } 671 int32_t nCount = 1; 672 int32_t nBgn = 0; 673 int32_t nEnd = 0; 674 CFDE_TxtEdtField* pField = NULL; 675 FX_BOOL bInField = GetFieldBoundary(nStart, nBgn, nEnd, pField); 676 int32_t nCaretInField = nStart - nBgn; 677 FX_BOOL bBefore = FALSE; 678 if (bInField && !pField->IsFix()) { 679 pField->Backup(); 680 CFX_WideString wsDel; 681 int32_t nCaret = 0; 682 int32_t nRet = 683 pField->Delete(nCaretInField, nCount, wsDel, nCaret, bBefore); 684 nCaret += nBgn; 685 switch (nRet) { 686 case FDE_FORMAT_FIELD_DELETE_RET_S: 687 break; 688 case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE: 689 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 690 case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY: 691 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 692 default: 693 FXSYS_assert(0); 694 break; 695 } 696 CFX_WideString wsField; 697 pField->GetFieldText(wsField); 698 if (!m_Param.pEventSink->On_ValidateField( 699 this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) { 700 pField->Restore(); 701 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 702 } 703 CFX_WideString wsDisplay; 704 pField->GetDisplayText(wsDisplay); 705 Replace(nBgn, nEnd - nBgn + 1, wsDisplay); 706 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 707 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldDelete( 708 this, nStart, pField, nCaretInField, nBgn, nEnd - nBgn + 1, 709 wsDisplay.GetLength(), wsDel, FALSE); 710 CFX_ByteString bsDoRecord; 711 pRecord->Serialize(bsDoRecord); 712 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 713 pRecord->Release(); 714 } 715 SetCaretPos(nStart, bBefore); 716 return FDE_TXTEDT_MODIFY_RET_S_Normal; 717 } 718 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 719 } 720 #endif 721 int32_t nCount = 1; 722 if (bBackspace) { 723 if (nStart == 0) { 724 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 725 } 726 if (nStart > 2 && m_pTxtBuf->GetCharByIndex(nStart - 1) == L'\n' && 727 m_pTxtBuf->GetCharByIndex(nStart - 2) == L'\r') { 728 nStart--; 729 nCount++; 730 } 731 nStart--; 732 } else { 733 if (nStart == GetTextBufLength()) { 734 return FDE_TXTEDT_MODIFY_RET_F_Full; 735 } 736 if ((nStart + 1 < GetTextBufLength()) && 737 (m_pTxtBuf->GetCharByIndex(nStart) == L'\r') && 738 (m_pTxtBuf->GetCharByIndex(nStart + 1) == L'\n')) { 739 nCount++; 740 } 741 } 742 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { 743 CFX_WideString wsText; 744 GetPreDeleteText(wsText, nStart, nCount); 745 if (!m_Param.pEventSink->On_Validate(this, wsText)) { 746 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 747 } 748 } 749 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 750 CFX_WideString wsRange; 751 m_pTxtBuf->GetRange(wsRange, nStart, nCount); 752 IFDE_TxtEdtDoRecord* pRecord = 753 new CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, wsRange); 754 CFX_ByteString bsDoRecord; 755 pRecord->Serialize(bsDoRecord); 756 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 757 pRecord->Release(); 758 } 759 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; 760 GetText(m_ChangeInfo.wsDelete, nStart, nCount); 761 Inner_DeleteRange(nStart, nCount); 762 SetCaretPos(nStart + ((!bBackspace && nStart > 0) ? -1 : 0), 763 (bBackspace || nStart == 0)); 764 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); 765 return FDE_TXTEDT_MODIFY_RET_S_Normal; 766 } 767 int32_t CFDE_TxtEdtEngine::DeleteRange(int32_t nStart, int32_t nCount) { 768 if (IsLocked()) { 769 return FDE_TXTEDT_MODIFY_RET_F_Locked; 770 } 771 if (nCount == -1) { 772 nCount = GetTextBufLength(); 773 } 774 if (nCount == 0) { 775 return FDE_TXTEDT_MODIFY_RET_S_Normal; 776 } 777 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { 778 CFX_WideString wsText; 779 GetPreDeleteText(wsText, nStart, nCount); 780 if (!m_Param.pEventSink->On_Validate(this, wsText)) { 781 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 782 } 783 } 784 DeleteRange_DoRecord(nStart, nCount); 785 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); 786 SetCaretPos(nStart, TRUE); 787 return FDE_TXTEDT_MODIFY_RET_S_Normal; 788 } 789 int32_t CFDE_TxtEdtEngine::Replace(int32_t nStart, 790 int32_t nLength, 791 const CFX_WideString& wsReplace) { 792 if (IsLocked()) { 793 return FDE_TXTEDT_MODIFY_RET_F_Locked; 794 } 795 if (nStart < 0 || (nStart + nLength > GetTextBufLength())) { 796 return FDE_TXTEDT_MODIFY_RET_F_Boundary; 797 } 798 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) { 799 CFX_WideString wsText; 800 GetPreReplaceText(wsText, nStart, nLength, wsReplace.c_str(), 801 wsReplace.GetLength()); 802 if (!m_Param.pEventSink->On_Validate(this, wsText)) { 803 return FDE_TXTEDT_MODIFY_RET_F_Invalidate; 804 } 805 } 806 if (IsSelect()) { 807 ClearSelection(); 808 } 809 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Replace; 810 GetText(m_ChangeInfo.wsDelete, nStart, nLength); 811 if (nLength > 0) { 812 Inner_DeleteRange(nStart, nLength); 813 } 814 int32_t nTextLength = wsReplace.GetLength(); 815 if (nTextLength > 0) { 816 Inner_Insert(nStart, wsReplace.c_str(), nTextLength); 817 } 818 m_ChangeInfo.wsInsert = CFX_WideString(wsReplace.c_str(), nTextLength); 819 nStart += nTextLength; 820 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1); 821 FX_BOOL bBefore = TRUE; 822 if (wChar != L'\n' && wChar != L'\r') { 823 nStart--; 824 bBefore = FALSE; 825 } 826 SetCaretPos(nStart, bBefore); 827 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 828 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 829 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); 830 return FDE_TXTEDT_MODIFY_RET_S_Normal; 831 } 832 void CFDE_TxtEdtEngine::SetLimit(int32_t nLimit) { 833 m_nLimit = nLimit; 834 } 835 void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias) { 836 m_wcAliasChar = wcAlias; 837 } 838 void CFDE_TxtEdtEngine::SetFormatBlock(int32_t nIndex, 839 const CFX_WideString& wsBlockFormat) { 840 #ifdef FDE_USEFORMATBLOCK 841 if (m_nFixLength == -1) { 842 m_nFixLength = GetTextLength(); 843 FXSYS_assert(m_wsFixText.IsEmpty()); 844 GetText(m_wsFixText, 0, -1); 845 } 846 FX_BOOL bInBlock = FALSE; 847 int32_t nCharIndex = 0; 848 int32_t nBlockIndex = 0; 849 int32_t nBlockPos = -1; 850 FX_WCHAR wc; 851 CFDE_TxtEdtBufIter* pIter = 852 new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE); 853 pIter->SetAt(0); 854 do { 855 wc = pIter->GetChar(); 856 if (bInBlock) { 857 if (wc == FDE_TXTEDT_FORMATBLOCK_END) { 858 nBlockIndex++; 859 bInBlock = FALSE; 860 } 861 } else { 862 if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) { 863 bInBlock = TRUE; 864 } else { 865 if (nCharIndex++ == nIndex) { 866 nBlockPos = pIter->GetAt(); 867 break; 868 } 869 } 870 } 871 } while (pIter->Next()); 872 pIter->Release(); 873 if (nBlockPos == -1) { 874 nBlockPos = GetTextBufLength(); 875 } 876 CFDE_TxtEdtBlock* pEditBlock = 877 new CFDE_TxtEdtBlock(this, wsBlockFormat, nIndex); 878 m_BlockArray.InsertAt(m_BlockArray.GetSize(), pEditBlock); 879 CFX_WideString wsDisplay; 880 pEditBlock->GetDisplayText(wsDisplay); 881 m_nCaret = nBlockPos; 882 if (wsDisplay.GetLength() > 0) { 883 RawInsert(nBlockPos, const FX_WCHAR*(wsDisplay), wsDisplay.GetLength()); 884 } 885 #endif 886 } 887 int32_t CFDE_TxtEdtEngine::CountEditBlocks() const { 888 #ifdef FDE_USEFORMATBLOCK 889 return m_BlockArray.GetSize(); 890 #else 891 return 0; 892 #endif 893 } 894 void CFDE_TxtEdtEngine::GetEditBlockText(int32_t nIndex, 895 CFX_WideString& wsBlockText) const { 896 #ifdef FDE_USEFORMATBLOCK 897 CFDE_TxtEdtBlock* pBlock = m_BlockArray[nIndex]; 898 pBlock->GetBlockText(wsBlockText); 899 #endif 900 } 901 int32_t CFDE_TxtEdtEngine::CountEditFields(int32_t nBlockIndex) const { 902 #ifdef FDE_USEFORMATBLOCK 903 CFDE_TxtEdtBlock* pBlock = m_BlockArray[nBlockIndex]; 904 return pBlock->CountField(); 905 #else 906 return 0; 907 #endif 908 } 909 void CFDE_TxtEdtEngine::GetEditFieldText(int32_t nBlockIndex, 910 int32_t nFieldIndex, 911 CFX_WideString& wsFieldText) const { 912 #ifdef FDE_USEFORMATBLOCK 913 CFDE_TxtEdtBlock* pBlock = m_BlockArray[nBlockIndex]; 914 pBlock->GetFieldText(nFieldIndex, wsFieldText); 915 #endif 916 } 917 void CFDE_TxtEdtEngine::StartEdit() { 918 #ifdef FDE_USEFORMATBLOCK 919 #endif 920 } 921 void CFDE_TxtEdtEngine::EndEdit() { 922 #ifdef FDE_USEFORMATBLOCK 923 #endif 924 } 925 void CFDE_TxtEdtEngine::RemoveSelRange(int32_t nStart, int32_t nCount) { 926 FDE_LPTXTEDTSELRANGE lpTemp = NULL; 927 int32_t nRangeCount = m_SelRangePtrArr.GetSize(); 928 int32_t i = 0; 929 for (i = 0; i < nRangeCount; i++) { 930 lpTemp = m_SelRangePtrArr[i]; 931 if (lpTemp->nStart == nStart && lpTemp->nCount == nCount) { 932 delete lpTemp; 933 m_SelRangePtrArr.RemoveAt(i); 934 return; 935 } 936 } 937 return; 938 } 939 void CFDE_TxtEdtEngine::AddSelRange(int32_t nStart, int32_t nCount) { 940 if (nCount == -1) { 941 nCount = GetTextLength() - nStart; 942 } 943 int32_t nSize = m_SelRangePtrArr.GetSize(); 944 if (nSize <= 0) { 945 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; 946 lpSelRange->nStart = nStart; 947 lpSelRange->nCount = nCount; 948 m_SelRangePtrArr.Add(lpSelRange); 949 m_Param.pEventSink->On_SelChanged(this); 950 return; 951 } 952 FDE_LPTXTEDTSELRANGE lpTemp = NULL; 953 lpTemp = m_SelRangePtrArr[nSize - 1]; 954 if (nStart >= lpTemp->nStart + lpTemp->nCount) { 955 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; 956 lpSelRange->nStart = nStart; 957 lpSelRange->nCount = nCount; 958 m_SelRangePtrArr.Add(lpSelRange); 959 m_Param.pEventSink->On_SelChanged(this); 960 return; 961 } 962 int32_t nEnd = nStart + nCount - 1; 963 FX_BOOL bBegin = FALSE; 964 int32_t nRangeBgn = 0; 965 int32_t nRangeCnt = 0; 966 for (int32_t i = 0; i < nSize; i++) { 967 lpTemp = m_SelRangePtrArr[i]; 968 int32_t nTempBgn = lpTemp->nStart; 969 int32_t nTempEnd = nTempBgn + lpTemp->nCount - 1; 970 if (bBegin) { 971 if (nEnd < nTempBgn) { 972 break; 973 } else if (nStart >= nTempBgn && nStart <= nTempEnd) { 974 nRangeCnt++; 975 break; 976 } 977 nRangeCnt++; 978 } else { 979 if (nStart <= nTempEnd) { 980 nRangeBgn = i; 981 if (nEnd < nTempBgn) { 982 break; 983 } 984 nRangeCnt = 1; 985 bBegin = TRUE; 986 } 987 } 988 } 989 if (nRangeCnt == 0) { 990 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE; 991 lpSelRange->nStart = nStart; 992 lpSelRange->nCount = nCount; 993 m_SelRangePtrArr.InsertAt(nRangeBgn, lpSelRange); 994 } else { 995 lpTemp = m_SelRangePtrArr[nRangeBgn]; 996 lpTemp->nStart = nStart; 997 lpTemp->nCount = nCount; 998 nRangeCnt--; 999 nRangeBgn++; 1000 while (nRangeCnt--) { 1001 delete m_SelRangePtrArr[nRangeBgn]; 1002 m_SelRangePtrArr.RemoveAt(nRangeBgn); 1003 } 1004 } 1005 m_Param.pEventSink->On_SelChanged(this); 1006 return; 1007 } 1008 int32_t CFDE_TxtEdtEngine::CountSelRanges() { 1009 return m_SelRangePtrArr.GetSize(); 1010 } 1011 int32_t CFDE_TxtEdtEngine::GetSelRange(int32_t nIndex, int32_t& nStart) { 1012 nStart = m_SelRangePtrArr[nIndex]->nStart; 1013 return m_SelRangePtrArr[nIndex]->nCount; 1014 } 1015 void CFDE_TxtEdtEngine::ClearSelection() { 1016 int32_t nCount = m_SelRangePtrArr.GetSize(); 1017 FDE_LPTXTEDTSELRANGE lpRange = NULL; 1018 int32_t i = 0; 1019 for (i = 0; i < nCount; i++) { 1020 lpRange = m_SelRangePtrArr[i]; 1021 if (lpRange != NULL) { 1022 delete lpRange; 1023 lpRange = NULL; 1024 } 1025 } 1026 m_SelRangePtrArr.RemoveAll(); 1027 if (nCount && m_Param.pEventSink) { 1028 m_Param.pEventSink->On_SelChanged(this); 1029 } 1030 } 1031 FX_BOOL CFDE_TxtEdtEngine::Redo(const CFX_ByteStringC& bsRedo) { 1032 if (IsLocked()) { 1033 return FALSE; 1034 } 1035 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) { 1036 return FALSE; 1037 } 1038 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsRedo); 1039 FXSYS_assert(pDoRecord); 1040 if (pDoRecord == NULL) { 1041 return FALSE; 1042 } 1043 FX_BOOL bOK = pDoRecord->Redo(); 1044 pDoRecord->Release(); 1045 return bOK; 1046 } 1047 FX_BOOL CFDE_TxtEdtEngine::Undo(const CFX_ByteStringC& bsUndo) { 1048 if (IsLocked()) { 1049 return FALSE; 1050 } 1051 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) { 1052 return FALSE; 1053 } 1054 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsUndo); 1055 FXSYS_assert(pDoRecord); 1056 if (pDoRecord == NULL) { 1057 return FALSE; 1058 } 1059 FX_BOOL bOK = pDoRecord->Undo(); 1060 pDoRecord->Release(); 1061 return bOK; 1062 } 1063 int32_t CFDE_TxtEdtEngine::StartLayout() { 1064 Lock(); 1065 RemoveAllPages(); 1066 m_nLayoutPos = 0; 1067 m_nLineCount = 0; 1068 return 0; 1069 } 1070 int32_t CFDE_TxtEdtEngine::DoLayout(IFX_Pause* pPause) { 1071 int32_t nCount = m_ParagPtrArray.GetSize(); 1072 CFDE_TxtEdtParag* pParag = NULL; 1073 int32_t nLineCount = 0; 1074 for (; m_nLayoutPos < nCount; m_nLayoutPos++) { 1075 pParag = m_ParagPtrArray[m_nLayoutPos]; 1076 pParag->CalcLines(); 1077 nLineCount += pParag->m_nLineCount; 1078 if ((pPause != NULL) && (nLineCount > m_nPageLineCount) && 1079 pPause->NeedToPauseNow()) { 1080 m_nLineCount += nLineCount; 1081 return (++m_nLayoutPos * 100) / nCount; 1082 } 1083 } 1084 m_nLineCount += nLineCount; 1085 return 100; 1086 } 1087 void CFDE_TxtEdtEngine::EndLayout() { 1088 UpdatePages(); 1089 int32_t nLength = GetTextLength(); 1090 if (m_nCaret > nLength) { 1091 m_nCaret = nLength; 1092 } 1093 int32_t nIndex = m_nCaret; 1094 if (!m_bBefore) { 1095 nIndex--; 1096 } 1097 m_rtCaret.Set(0, 0, 1, m_Param.fFontSize); 1098 Unlock(); 1099 } 1100 FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause* pPause) { 1101 return m_pTxtBuf->Optimize(pPause); 1102 } 1103 IFDE_TxtEdtBuf* CFDE_TxtEdtEngine::GetTextBuf() const { 1104 return (IFDE_TxtEdtBuf*)m_pTxtBuf; 1105 } 1106 int32_t CFDE_TxtEdtEngine::GetTextBufLength() const { 1107 return m_pTxtBuf->GetTextLength() - 1; 1108 } 1109 IFX_TxtBreak* CFDE_TxtEdtEngine::GetTextBreak() const { 1110 return m_pTextBreak; 1111 } 1112 int32_t CFDE_TxtEdtEngine::GetLineCount() const { 1113 return m_nLineCount; 1114 } 1115 int32_t CFDE_TxtEdtEngine::GetPageLineCount() const { 1116 return m_nPageLineCount; 1117 } 1118 int32_t CFDE_TxtEdtEngine::CountParags() const { 1119 return m_ParagPtrArray.GetSize(); 1120 } 1121 IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const { 1122 return m_ParagPtrArray[nParagIndex]; 1123 } 1124 IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() { 1125 if (!m_pTxtBuf) { 1126 return NULL; 1127 } 1128 return new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf); 1129 } 1130 int32_t CFDE_TxtEdtEngine::Line2Parag(int32_t nStartParag, 1131 int32_t nStartLineofParag, 1132 int32_t nLineIndex, 1133 int32_t& nStartLine) const { 1134 int32_t nLineTotal = nStartLineofParag; 1135 int32_t nCount = m_ParagPtrArray.GetSize(); 1136 CFDE_TxtEdtParag* pParag = NULL; 1137 int32_t i = nStartParag; 1138 for (; i < nCount; i++) { 1139 pParag = m_ParagPtrArray[i]; 1140 nLineTotal += pParag->m_nLineCount; 1141 if (nLineTotal > nLineIndex) { 1142 break; 1143 } 1144 } 1145 nStartLine = nLineTotal - pParag->m_nLineCount; 1146 return i; 1147 } 1148 void CFDE_TxtEdtEngine::GetPreDeleteText(CFX_WideString& wsText, 1149 int32_t nIndex, 1150 int32_t nLength) { 1151 GetText(wsText, 0, GetTextBufLength()); 1152 wsText.Delete(nIndex, nLength); 1153 } 1154 void CFDE_TxtEdtEngine::GetPreInsertText(CFX_WideString& wsText, 1155 int32_t nIndex, 1156 const FX_WCHAR* lpText, 1157 int32_t nLength) { 1158 GetText(wsText, 0, GetTextBufLength()); 1159 int32_t nSelIndex = 0; 1160 int32_t nSelLength = 0; 1161 int32_t nSelCount = CountSelRanges(); 1162 while (nSelCount--) { 1163 nSelLength = GetSelRange(nSelCount, nSelIndex); 1164 wsText.Delete(nSelIndex, nSelLength); 1165 nIndex = nSelIndex; 1166 } 1167 CFX_WideString wsTemp; 1168 int32_t nOldLength = wsText.GetLength(); 1169 const FX_WCHAR* pOldBuffer = wsText.c_str(); 1170 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nOldLength + nLength); 1171 FXSYS_memcpy(lpBuffer, pOldBuffer, (nIndex) * sizeof(FX_WCHAR)); 1172 FXSYS_memcpy(lpBuffer + nIndex, lpText, nLength * sizeof(FX_WCHAR)); 1173 FXSYS_memcpy(lpBuffer + nIndex + nLength, pOldBuffer + nIndex, 1174 (nOldLength - nIndex) * sizeof(FX_WCHAR)); 1175 wsTemp.ReleaseBuffer(nOldLength + nLength); 1176 wsText = wsTemp; 1177 } 1178 void CFDE_TxtEdtEngine::GetPreReplaceText(CFX_WideString& wsText, 1179 int32_t nIndex, 1180 int32_t nOriginLength, 1181 const FX_WCHAR* lpText, 1182 int32_t nLength) { 1183 GetText(wsText, 0, GetTextBufLength()); 1184 int32_t nSelIndex = 0; 1185 int32_t nSelLength = 0; 1186 int32_t nSelCount = CountSelRanges(); 1187 while (nSelCount--) { 1188 nSelLength = GetSelRange(nSelCount, nSelIndex); 1189 wsText.Delete(nSelIndex, nSelLength); 1190 } 1191 wsText.Delete(nIndex, nOriginLength); 1192 int32_t i = 0; 1193 for (i = 0; i < nLength; i++) { 1194 wsText.Insert(nIndex++, lpText[i]); 1195 } 1196 } 1197 void CFDE_TxtEdtEngine::Inner_Insert(int32_t nStart, 1198 const FX_WCHAR* lpText, 1199 int32_t nLength) { 1200 FXSYS_assert(nLength > 0); 1201 FDE_TXTEDTPARAGPOS ParagPos; 1202 TextPos2ParagPos(nStart, ParagPos); 1203 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 1204 int32_t nParagCount = m_ParagPtrArray.GetSize(); 1205 int32_t i = 0; 1206 for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) { 1207 m_ParagPtrArray[i]->m_nCharStart += nLength; 1208 } 1209 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1210 int32_t nReserveLineCount = pParag->m_nLineCount; 1211 int32_t nReserveCharStart = pParag->m_nCharStart; 1212 int32_t nLeavePart = ParagPos.nCharIndex; 1213 int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex; 1214 int32_t nTextStart = 0; 1215 FX_WCHAR wCurChar = L' '; 1216 const FX_WCHAR* lpPos = lpText; 1217 FX_BOOL bFirst = TRUE; 1218 int32_t nParagIndex = ParagPos.nParagIndex; 1219 for (i = 0; i < nLength; i++, lpPos++) { 1220 wCurChar = *lpPos; 1221 if (wCurChar == m_wLineEnd) { 1222 if (bFirst) { 1223 pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1); 1224 pParag->m_nLineCount = -1; 1225 nReserveCharStart += pParag->m_nCharCount; 1226 bFirst = FALSE; 1227 } else { 1228 pParag = new CFDE_TxtEdtParag(this); 1229 pParag->m_nLineCount = -1; 1230 pParag->m_nCharCount = i - nTextStart + 1; 1231 pParag->m_nCharStart = nReserveCharStart; 1232 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); 1233 nReserveCharStart += pParag->m_nCharCount; 1234 } 1235 nTextStart = i + 1; 1236 } 1237 } 1238 if (bFirst) { 1239 pParag->m_nCharCount += nLength; 1240 pParag->m_nLineCount = -1; 1241 bFirst = FALSE; 1242 } else { 1243 pParag = new CFDE_TxtEdtParag(this); 1244 pParag->m_nLineCount = -1; 1245 pParag->m_nCharCount = nLength - nTextStart + nCutPart; 1246 pParag->m_nCharStart = nReserveCharStart; 1247 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); 1248 } 1249 m_pTxtBuf->Insert(nStart, lpText, nLength); 1250 int32_t nTotalLineCount = 0; 1251 for (i = ParagPos.nParagIndex; i <= nParagIndex; i++) { 1252 pParag = m_ParagPtrArray[i]; 1253 pParag->CalcLines(); 1254 nTotalLineCount += pParag->m_nLineCount; 1255 } 1256 m_nLineCount += nTotalLineCount - nReserveLineCount; 1257 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 1258 UpdatePages(); 1259 } 1260 #ifdef FDE_USEFORMATBLOCK 1261 void CFDE_TxtEdtEngine::RawInsert(int32_t nStart, 1262 const FX_WCHAR* lpText, 1263 int32_t nLength) { 1264 FXSYS_assert(nLength > 0); 1265 FDE_TXTEDTPARAGPOS ParagPos; 1266 TextPos2ParagPos(nStart, ParagPos); 1267 int32_t nParagCount = m_ParagPtrArray.GetSize(); 1268 int32_t i = 0; 1269 for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) { 1270 m_ParagPtrArray[i]->m_nCharStart += nLength; 1271 } 1272 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1273 int32_t nReserveLineCount = pParag->m_nLineCount; 1274 int32_t nReserveCharStart = pParag->m_nCharStart; 1275 int32_t nLeavePart = ParagPos.nCharIndex; 1276 int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex; 1277 int32_t nTextStart = 0; 1278 FX_WCHAR wCurChar = L' '; 1279 const FX_WCHAR* lpPos = lpText; 1280 FX_BOOL bFirst = TRUE; 1281 int32_t nParagIndex = ParagPos.nParagIndex; 1282 for (i = 0; i < nLength; i++, lpPos++) { 1283 wCurChar = *lpPos; 1284 if (wCurChar == m_wLineEnd) { 1285 if (bFirst) { 1286 pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1); 1287 pParag->m_nLineCount = -1; 1288 nReserveCharStart += pParag->m_nCharCount; 1289 bFirst = FALSE; 1290 } else { 1291 pParag = new CFDE_TxtEdtParag(this); 1292 pParag->m_nLineCount = -1; 1293 pParag->m_nCharCount = i - nTextStart + 1; 1294 pParag->m_nCharStart = nReserveCharStart; 1295 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); 1296 nReserveCharStart += pParag->m_nCharCount; 1297 } 1298 nTextStart = i + 1; 1299 } 1300 } 1301 if (bFirst) { 1302 pParag->m_nCharCount += nLength; 1303 pParag->m_nLineCount = -1; 1304 bFirst = FALSE; 1305 } else { 1306 pParag = new CFDE_TxtEdtParag(this); 1307 pParag->m_nLineCount = -1; 1308 pParag->m_nCharCount = nLength - nTextStart + nCutPart; 1309 pParag->m_nCharStart = nReserveCharStart; 1310 m_ParagPtrArray.InsertAt(++nParagIndex, pParag); 1311 } 1312 m_pTxtBuf->Insert(nStart, lpText, nLength); 1313 } 1314 #endif 1315 void CFDE_TxtEdtEngine::Inner_DeleteRange(int32_t nStart, int32_t nCount) { 1316 if (nCount == -1) { 1317 nCount = m_pTxtBuf->GetTextLength() - nStart; 1318 } 1319 int32_t nEnd = nStart + nCount - 1; 1320 FXSYS_assert(nStart >= 0 && nEnd < m_pTxtBuf->GetTextLength()); 1321 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 1322 FDE_TXTEDTPARAGPOS ParagPosBgn, ParagPosEnd; 1323 TextPos2ParagPos(nStart, ParagPosBgn); 1324 TextPos2ParagPos(nEnd, ParagPosEnd); 1325 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPosEnd.nParagIndex]; 1326 FX_BOOL bLastParag = FALSE; 1327 if (ParagPosEnd.nCharIndex == pParag->m_nCharCount - 1) { 1328 if (ParagPosEnd.nParagIndex < m_ParagPtrArray.GetSize() - 1) { 1329 ParagPosEnd.nParagIndex++; 1330 } else { 1331 bLastParag = TRUE; 1332 } 1333 } 1334 int32_t nTotalLineCount = 0; 1335 int32_t nTotalCharCount = 0; 1336 int32_t i = 0; 1337 for (i = ParagPosBgn.nParagIndex; i <= ParagPosEnd.nParagIndex; i++) { 1338 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i]; 1339 pParag->CalcLines(); 1340 nTotalLineCount += pParag->m_nLineCount; 1341 nTotalCharCount += pParag->m_nCharCount; 1342 } 1343 m_pTxtBuf->Delete(nStart, nCount); 1344 int32_t nNextParagIndex = (ParagPosBgn.nCharIndex == 0 && bLastParag) 1345 ? ParagPosBgn.nParagIndex 1346 : (ParagPosBgn.nParagIndex + 1); 1347 for (i = nNextParagIndex; i <= ParagPosEnd.nParagIndex; i++) { 1348 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nNextParagIndex]; 1349 delete pParag; 1350 m_ParagPtrArray.RemoveAt(nNextParagIndex); 1351 } 1352 if (!(bLastParag && ParagPosBgn.nCharIndex == 0)) { 1353 pParag = m_ParagPtrArray[ParagPosBgn.nParagIndex]; 1354 pParag->m_nCharCount = nTotalCharCount - nCount; 1355 pParag->CalcLines(); 1356 nTotalLineCount -= pParag->m_nLineCount; 1357 } 1358 int32_t nParagCount = m_ParagPtrArray.GetSize(); 1359 for (i = nNextParagIndex; i < nParagCount; i++) { 1360 m_ParagPtrArray[i]->m_nCharStart -= nCount; 1361 } 1362 m_nLineCount -= nTotalLineCount; 1363 UpdatePages(); 1364 int32_t nPageCount = CountPages(); 1365 if (m_nCaretPage >= nPageCount) { 1366 m_nCaretPage = nPageCount - 1; 1367 } 1368 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 1369 } 1370 void CFDE_TxtEdtEngine::DeleteRange_DoRecord(int32_t nStart, 1371 int32_t nCount, 1372 FX_BOOL bSel) { 1373 FXSYS_assert(nStart >= 0); 1374 if (nCount == -1) { 1375 nCount = GetTextLength() - nStart; 1376 } 1377 FXSYS_assert((nStart + nCount) <= m_pTxtBuf->GetTextLength()); 1378 #ifdef FDE_USEFORMATBLOCK 1379 int32_t nBlockCount = m_BlockArray.GetSize(); 1380 if (nBlockCount > 0) { 1381 } 1382 #endif 1383 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 1384 CFX_WideString wsRange; 1385 m_pTxtBuf->GetRange(wsRange, nStart, nCount); 1386 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_DeleteRange( 1387 this, nStart, m_nCaret, wsRange, bSel); 1388 CFX_ByteString bsDoRecord; 1389 pRecord->Serialize(bsDoRecord); 1390 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 1391 pRecord->Release(); 1392 } 1393 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; 1394 GetText(m_ChangeInfo.wsDelete, nStart, nCount); 1395 Inner_DeleteRange(nStart, nCount); 1396 } 1397 void CFDE_TxtEdtEngine::ResetEngine() { 1398 RemoveAllPages(); 1399 RemoveAllParags(); 1400 ClearSelection(); 1401 m_nCaret = 0; 1402 m_pTxtBuf->Clear(FALSE); 1403 m_nCaret = 0; 1404 } 1405 void CFDE_TxtEdtEngine::RebuildParagraphs() { 1406 RemoveAllParags(); 1407 FX_WCHAR wChar = L' '; 1408 int32_t nParagStart = 0; 1409 int32_t nIndex = 0; 1410 IFX_CharIter* pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf); 1411 pIter->SetAt(0); 1412 do { 1413 wChar = pIter->GetChar(); 1414 nIndex = pIter->GetAt(); 1415 if (wChar == m_wLineEnd) { 1416 CFDE_TxtEdtParag* pParag = new CFDE_TxtEdtParag(this); 1417 pParag->m_nCharStart = nParagStart; 1418 pParag->m_nCharCount = nIndex - nParagStart + 1; 1419 pParag->m_nLineCount = -1; 1420 m_ParagPtrArray.Add(pParag); 1421 nParagStart = nIndex + 1; 1422 } 1423 } while (pIter->Next()); 1424 pIter->Release(); 1425 } 1426 void CFDE_TxtEdtEngine::RemoveAllParags() { 1427 int32_t nCount = m_ParagPtrArray.GetSize(); 1428 int32_t i = 0; 1429 for (i = 0; i < nCount; i++) { 1430 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i]; 1431 if (pParag) { 1432 delete pParag; 1433 } 1434 } 1435 m_ParagPtrArray.RemoveAll(); 1436 } 1437 void CFDE_TxtEdtEngine::RemoveAllPages() { 1438 int32_t nCount = m_PagePtrArray.GetSize(); 1439 int32_t i = 0; 1440 for (i = 0; i < nCount; i++) { 1441 IFDE_TxtEdtPage* pPage = m_PagePtrArray[i]; 1442 if (pPage) { 1443 pPage->Release(); 1444 } 1445 } 1446 m_PagePtrArray.RemoveAll(); 1447 } 1448 void CFDE_TxtEdtEngine::UpdateParags() { 1449 int32_t nCount = m_ParagPtrArray.GetSize(); 1450 if (nCount == 0) { 1451 return; 1452 } 1453 CFDE_TxtEdtParag* pParag = NULL; 1454 int32_t nLineCount = 0; 1455 int32_t i = 0; 1456 for (i = 0; i < nCount; i++) { 1457 pParag = m_ParagPtrArray[i]; 1458 if (pParag->m_nLineCount == -1) { 1459 pParag->CalcLines(); 1460 } 1461 nLineCount += pParag->m_nLineCount; 1462 } 1463 m_nLineCount = nLineCount; 1464 } 1465 void CFDE_TxtEdtEngine::UpdatePages() { 1466 if (m_nLineCount == 0) { 1467 return; 1468 } 1469 int32_t nPageCount = (m_nLineCount - 1) / (m_nPageLineCount) + 1; 1470 int32_t nSize = m_PagePtrArray.GetSize(); 1471 if (nSize == nPageCount) { 1472 return; 1473 } 1474 if (nSize > nPageCount) { 1475 IFDE_TxtEdtPage* pPage = NULL; 1476 int32_t i = 0; 1477 for (i = nSize - 1; i >= nPageCount; i--) { 1478 pPage = m_PagePtrArray[i]; 1479 if (pPage) { 1480 pPage->Release(); 1481 } 1482 m_PagePtrArray.RemoveAt(i); 1483 } 1484 m_Param.pEventSink->On_PageCountChanged(this); 1485 return; 1486 } 1487 if (nSize < nPageCount) { 1488 IFDE_TxtEdtPage* pPage = NULL; 1489 int32_t i = 0; 1490 for (i = nSize; i < nPageCount; i++) { 1491 pPage = IFDE_TxtEdtPage::Create(this, i); 1492 m_PagePtrArray.Add(pPage); 1493 } 1494 m_Param.pEventSink->On_PageCountChanged(this); 1495 return; 1496 } 1497 } 1498 void CFDE_TxtEdtEngine::UpdateTxtBreak() { 1499 FX_DWORD dwStyle = m_pTextBreak->GetLayoutStyles(); 1500 if (m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines) { 1501 dwStyle &= ~FX_TXTLAYOUTSTYLE_SingleLine; 1502 } else { 1503 dwStyle |= FX_TXTLAYOUTSTYLE_SingleLine; 1504 } 1505 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { 1506 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalLayout; 1507 } else { 1508 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalLayout; 1509 } 1510 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve) { 1511 dwStyle |= FX_TXTLAYOUTSTYLE_ReverseLine; 1512 } else { 1513 dwStyle &= ~FX_TXTLAYOUTSTYLE_ReverseLine; 1514 } 1515 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_RTL) { 1516 dwStyle |= FX_TXTLAYOUTSTYLE_RTLReadingOrder; 1517 } else { 1518 dwStyle &= ~FX_TXTLAYOUTSTYLE_RTLReadingOrder; 1519 } 1520 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) { 1521 dwStyle |= FX_TXTLAYOUTSTYLE_CombText; 1522 } else { 1523 dwStyle &= ~FX_TXTLAYOUTSTYLE_CombText; 1524 } 1525 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CharVertial) { 1526 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalChars; 1527 } else { 1528 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalChars; 1529 } 1530 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ExpandTab) { 1531 dwStyle |= FX_TXTLAYOUTSTYLE_ExpandTab; 1532 } else { 1533 dwStyle &= ~FX_TXTLAYOUTSTYLE_ExpandTab; 1534 } 1535 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicContext) { 1536 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicContext; 1537 } else { 1538 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicContext; 1539 } 1540 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicShapes) { 1541 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicShapes; 1542 } else { 1543 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicShapes; 1544 } 1545 m_pTextBreak->SetLayoutStyles(dwStyle); 1546 FX_DWORD dwAligment = 0; 1547 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Justified) { 1548 dwAligment |= FX_TXTLINEALIGNMENT_Justified; 1549 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Distributed) { 1550 dwAligment |= FX_TXTLINEALIGNMENT_Distributed; 1551 } 1552 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Center) { 1553 dwAligment |= FX_TXTLINEALIGNMENT_Center; 1554 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Right) { 1555 dwAligment |= FX_TXTLINEALIGNMENT_Right; 1556 } 1557 m_pTextBreak->SetAlignment(dwAligment); 1558 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { 1559 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { 1560 m_pTextBreak->SetLineWidth(m_Param.fPlateHeight); 1561 } else { 1562 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX); 1563 } 1564 } else { 1565 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { 1566 m_pTextBreak->SetLineWidth(m_Param.fPlateWidth); 1567 } else { 1568 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX); 1569 } 1570 } 1571 m_nPageLineCount = m_Param.nLineCount; 1572 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) { 1573 FX_FLOAT fCombWidth = 1574 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical 1575 ? m_Param.fPlateHeight 1576 : m_Param.fPlateWidth; 1577 if (m_nLimit > 0) { 1578 fCombWidth /= m_nLimit; 1579 } 1580 m_pTextBreak->SetCombWidth(fCombWidth); 1581 } 1582 m_pTextBreak->SetFont(m_Param.pFont); 1583 m_pTextBreak->SetFontSize(m_Param.fFontSize); 1584 m_pTextBreak->SetTabWidth(m_Param.fTabWidth, m_Param.bTabEquidistant); 1585 m_pTextBreak->SetDefaultChar(m_Param.wDefChar); 1586 m_pTextBreak->SetParagraphBreakChar(m_Param.wLineBreakChar); 1587 m_pTextBreak->SetCharRotation(m_Param.nCharRotation); 1588 m_pTextBreak->SetLineBreakTolerance(m_Param.fFontSize * 0.2f); 1589 m_pTextBreak->SetHorizontalScale(m_Param.nHorzScale); 1590 m_pTextBreak->SetCharSpace(m_Param.fCharSpace); 1591 } 1592 FX_BOOL CFDE_TxtEdtEngine::ReplaceParagEnd(FX_WCHAR*& lpText, 1593 int32_t& nLength, 1594 FX_BOOL bPreIsCR) { 1595 for (int32_t i = 0; i < nLength; i++) { 1596 FX_WCHAR wc = lpText[i]; 1597 switch (wc) { 1598 case L'\r': { 1599 lpText[i] = m_wLineEnd; 1600 bPreIsCR = TRUE; 1601 } break; 1602 case L'\n': { 1603 if (bPreIsCR == TRUE) { 1604 int32_t nNext = i + 1; 1605 if (nNext < nLength) { 1606 FXSYS_memmove(lpText + i, lpText + nNext, 1607 (nLength - nNext) * sizeof(FX_WCHAR)); 1608 } 1609 i--; 1610 nLength--; 1611 bPreIsCR = FALSE; 1612 if (m_bAutoLineEnd) { 1613 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CRLF; 1614 m_bAutoLineEnd = FALSE; 1615 } 1616 } else { 1617 lpText[i] = m_wLineEnd; 1618 if (m_bAutoLineEnd) { 1619 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_LF; 1620 m_bAutoLineEnd = FALSE; 1621 } 1622 } 1623 } break; 1624 default: { 1625 if (bPreIsCR && m_bAutoLineEnd) { 1626 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CR; 1627 m_bAutoLineEnd = FALSE; 1628 } 1629 bPreIsCR = FALSE; 1630 } break; 1631 } 1632 } 1633 return bPreIsCR; 1634 } 1635 void CFDE_TxtEdtEngine::RecoverParagEnd(CFX_WideString& wsText) { 1636 FX_WCHAR wc = (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CR) ? L'\n' : L'\r'; 1637 if (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CRLF) { 1638 CFX_ArrayTemplate<int32_t> PosArr; 1639 int32_t nLength = wsText.GetLength(); 1640 int32_t i = 0; 1641 FX_WCHAR* lpPos = (FX_WCHAR*)(const FX_WCHAR*)wsText; 1642 for (i = 0; i < nLength; i++, lpPos++) { 1643 if (*lpPos == m_wLineEnd) { 1644 *lpPos = wc; 1645 PosArr.Add(i); 1646 } 1647 } 1648 const FX_WCHAR* lpSrcBuf = wsText.c_str(); 1649 CFX_WideString wsTemp; 1650 int32_t nCount = PosArr.GetSize(); 1651 FX_WCHAR* lpDstBuf = wsTemp.GetBuffer(nLength + nCount); 1652 int32_t nDstPos = 0; 1653 int32_t nSrcPos = 0; 1654 for (i = 0; i < nCount; i++) { 1655 int32_t nPos = PosArr[i]; 1656 int32_t nCopyLen = nPos - nSrcPos + 1; 1657 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, 1658 nCopyLen * sizeof(FX_WCHAR)); 1659 nDstPos += nCopyLen; 1660 nSrcPos += nCopyLen; 1661 lpDstBuf[nDstPos] = L'\n'; 1662 nDstPos++; 1663 } 1664 if (nSrcPos < nLength) { 1665 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, 1666 (nLength - nSrcPos) * sizeof(FX_WCHAR)); 1667 } 1668 wsTemp.ReleaseBuffer(nLength + nCount); 1669 wsText = wsTemp; 1670 } else { 1671 int32_t nLength = wsText.GetLength(); 1672 FX_WCHAR* lpBuf = (FX_WCHAR*)(const FX_WCHAR*)wsText; 1673 for (int32_t i = 0; i < nLength; i++, lpBuf++) { 1674 if (*lpBuf == m_wLineEnd) { 1675 *lpBuf = wc; 1676 } 1677 } 1678 } 1679 } 1680 int32_t CFDE_TxtEdtEngine::MovePage2Char(int32_t nIndex) { 1681 FXSYS_assert(nIndex >= 0); 1682 FXSYS_assert(nIndex <= m_pTxtBuf->GetTextLength()); 1683 if (m_nCaretPage >= 0) { 1684 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; 1685 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 1686 int32_t nPageCharStart = pPage->GetCharStart(); 1687 int32_t nPageCharCount = pPage->GetCharCount(); 1688 if (nIndex >= nPageCharStart && nIndex < nPageCharStart + nPageCharCount) { 1689 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 1690 return m_nCaretPage; 1691 } 1692 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 1693 } 1694 CFDE_TxtEdtParag* pParag = NULL; 1695 int32_t nLineCount = 0; 1696 int32_t nParagCount = m_ParagPtrArray.GetSize(); 1697 int32_t i = 0; 1698 for (i = 0; i < nParagCount; i++) { 1699 pParag = m_ParagPtrArray[i]; 1700 if (pParag->m_nCharStart <= nIndex && 1701 nIndex < (pParag->m_nCharStart + pParag->m_nCharCount)) { 1702 break; 1703 } 1704 nLineCount += pParag->m_nLineCount; 1705 } 1706 pParag->LoadParag(); 1707 int32_t nLineStart = -1; 1708 int32_t nLineCharCount = -1; 1709 for (i = 0; i < pParag->m_nLineCount; i++) { 1710 pParag->GetLineRange(i, nLineStart, nLineCharCount); 1711 if (nLineStart <= nIndex && nIndex < (nLineStart + nLineCharCount)) { 1712 break; 1713 } 1714 } 1715 FXSYS_assert(i < pParag->m_nLineCount); 1716 nLineCount += (i + 1); 1717 m_nCaretPage = (nLineCount - 1) / m_nPageLineCount + 1 - 1; 1718 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); 1719 pParag->UnloadParag(); 1720 return m_nCaretPage; 1721 } 1722 void CFDE_TxtEdtEngine::TextPos2ParagPos(int32_t nIndex, 1723 FDE_TXTEDTPARAGPOS& ParagPos) const { 1724 FXSYS_assert(nIndex >= 0 && nIndex < m_pTxtBuf->GetTextLength()); 1725 int32_t nCount = m_ParagPtrArray.GetSize(); 1726 int32_t nBgn = 0; 1727 int32_t nMid = 0; 1728 int32_t nEnd = nCount - 1; 1729 while (nEnd > nBgn) { 1730 nMid = (nBgn + nEnd) / 2; 1731 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nMid]; 1732 if (nIndex < pParag->m_nCharStart) { 1733 nEnd = nMid - 1; 1734 } else if (nIndex >= (pParag->m_nCharStart + pParag->m_nCharCount)) { 1735 nBgn = nMid + 1; 1736 } else { 1737 break; 1738 } 1739 } 1740 if (nBgn == nEnd) { 1741 nMid = nBgn; 1742 } 1743 FXSYS_assert(nIndex >= m_ParagPtrArray[nMid]->m_nCharStart && 1744 (nIndex < m_ParagPtrArray[nMid]->m_nCharStart + 1745 m_ParagPtrArray[nMid]->m_nCharCount)); 1746 ParagPos.nParagIndex = nMid; 1747 ParagPos.nCharIndex = nIndex - m_ParagPtrArray[nMid]->m_nCharStart; 1748 } 1749 int32_t CFDE_TxtEdtEngine::MoveForward(FX_BOOL& bBefore) { 1750 if (m_nCaret == m_pTxtBuf->GetTextLength() - 1) { 1751 return -1; 1752 } 1753 int32_t nCaret = m_nCaret; 1754 if ((nCaret + 1 < m_pTxtBuf->GetTextLength()) && 1755 (m_pTxtBuf->GetCharByIndex(nCaret) == L'\r') && 1756 (m_pTxtBuf->GetCharByIndex(nCaret + 1) == L'\n')) { 1757 nCaret++; 1758 } 1759 nCaret++; 1760 bBefore = TRUE; 1761 return nCaret; 1762 } 1763 int32_t CFDE_TxtEdtEngine::MoveBackward(FX_BOOL& bBefore) { 1764 if (m_nCaret == 0) { 1765 return FALSE; 1766 } 1767 int32_t nCaret = m_nCaret; 1768 if (nCaret > 2 && m_pTxtBuf->GetCharByIndex(nCaret - 1) == L'\n' && 1769 m_pTxtBuf->GetCharByIndex(nCaret - 2) == L'\r') { 1770 nCaret--; 1771 } 1772 nCaret--; 1773 bBefore = TRUE; 1774 return nCaret; 1775 } 1776 FX_BOOL CFDE_TxtEdtEngine::MoveUp(CFX_PointF& ptCaret) { 1777 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage); 1778 const CFX_RectF& rtContent = pPage->GetContentsBox(); 1779 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { 1780 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 - m_Param.fLineSpace; 1781 ptCaret.y = m_fCaretPosReserve; 1782 FX_BOOL bLineReserve = 1783 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; 1784 if (ptCaret.x < rtContent.left) { 1785 if (bLineReserve) { 1786 if (m_nCaretPage == CountPages() - 1) { 1787 return FALSE; 1788 } 1789 } else { 1790 if (m_nCaretPage == 0) { 1791 return FALSE; 1792 } 1793 } 1794 if (bLineReserve) { 1795 m_nCaretPage++; 1796 } else { 1797 m_nCaretPage--; 1798 } 1799 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); 1800 ptCaret.x -= rtContent.left; 1801 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); 1802 ptCaret.x += pCurPage->GetContentsBox().right(); 1803 } 1804 } else { 1805 ptCaret.x = m_fCaretPosReserve; 1806 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 - m_Param.fLineSpace; 1807 if (ptCaret.y < rtContent.top) { 1808 if (m_nCaretPage == 0) { 1809 return FALSE; 1810 } 1811 ptCaret.y -= rtContent.top; 1812 m_nCaretPage--; 1813 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); 1814 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); 1815 ptCaret.y += pCurPage->GetContentsBox().bottom(); 1816 } 1817 } 1818 return TRUE; 1819 } 1820 FX_BOOL CFDE_TxtEdtEngine::MoveDown(CFX_PointF& ptCaret) { 1821 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage); 1822 const CFX_RectF& rtContent = pPage->GetContentsBox(); 1823 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { 1824 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 + m_Param.fLineSpace; 1825 ptCaret.y = m_fCaretPosReserve; 1826 if (ptCaret.x >= rtContent.right()) { 1827 FX_BOOL bLineReserve = 1828 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; 1829 if (bLineReserve) { 1830 if (m_nCaretPage == 0) { 1831 return FALSE; 1832 } 1833 } else { 1834 if (m_nCaretPage == CountPages() - 1) { 1835 return FALSE; 1836 } 1837 } 1838 if (bLineReserve) { 1839 m_nCaretPage--; 1840 } else { 1841 m_nCaretPage++; 1842 } 1843 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); 1844 ptCaret.x -= rtContent.right(); 1845 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); 1846 ptCaret.x += pCurPage->GetContentsBox().left; 1847 } 1848 } else { 1849 ptCaret.x = m_fCaretPosReserve; 1850 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 + m_Param.fLineSpace; 1851 if (ptCaret.y >= rtContent.bottom()) { 1852 if (m_nCaretPage == CountPages() - 1) { 1853 return FALSE; 1854 } 1855 ptCaret.y -= rtContent.bottom(); 1856 m_nCaretPage++; 1857 m_Param.pEventSink->On_PageChange(this, m_nCaretPage); 1858 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage); 1859 ptCaret.y += pCurPage->GetContentsBox().top; 1860 } 1861 } 1862 return TRUE; 1863 } 1864 FX_BOOL CFDE_TxtEdtEngine::MoveLineStart() { 1865 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; 1866 FDE_TXTEDTPARAGPOS ParagPos; 1867 TextPos2ParagPos(nIndex, ParagPos); 1868 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1869 pParag->LoadParag(); 1870 int32_t nLineCount = pParag->m_nLineCount; 1871 int32_t i = 0; 1872 int32_t nStart = 0; 1873 int32_t nCount = 0; 1874 for (; i < nLineCount; i++) { 1875 pParag->GetLineRange(i, nStart, nCount); 1876 if (nIndex >= nStart && nIndex < nStart + nCount) { 1877 break; 1878 } 1879 } 1880 UpdateCaretRect(nStart, TRUE); 1881 pParag->UnloadParag(); 1882 return TRUE; 1883 } 1884 FX_BOOL CFDE_TxtEdtEngine::MoveLineEnd() { 1885 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; 1886 FDE_TXTEDTPARAGPOS ParagPos; 1887 TextPos2ParagPos(nIndex, ParagPos); 1888 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1889 pParag->LoadParag(); 1890 int32_t nLineCount = pParag->m_nLineCount; 1891 int32_t i = 0; 1892 int32_t nStart = 0; 1893 int32_t nCount = 0; 1894 for (; i < nLineCount; i++) { 1895 pParag->GetLineRange(i, nStart, nCount); 1896 if (nIndex >= nStart && nIndex < nStart + nCount) { 1897 break; 1898 } 1899 } 1900 nIndex = nStart + nCount - 1; 1901 FXSYS_assert(nIndex <= GetTextBufLength()); 1902 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex); 1903 FX_BOOL bBefore = FALSE; 1904 if (nIndex <= GetTextBufLength()) { 1905 if (wChar == L'\r') { 1906 bBefore = TRUE; 1907 } else if (wChar == L'\n' && nIndex > nStart) { 1908 bBefore = TRUE; 1909 nIndex--; 1910 wChar = m_pTxtBuf->GetCharByIndex(nIndex); 1911 if (wChar != L'\r') { 1912 nIndex++; 1913 } 1914 } 1915 } 1916 UpdateCaretRect(nIndex, bBefore); 1917 pParag->UnloadParag(); 1918 return TRUE; 1919 } 1920 FX_BOOL CFDE_TxtEdtEngine::MoveParagStart() { 1921 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; 1922 FDE_TXTEDTPARAGPOS ParagPos; 1923 TextPos2ParagPos(nIndex, ParagPos); 1924 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1925 UpdateCaretRect(pParag->m_nCharStart, TRUE); 1926 return TRUE; 1927 } 1928 FX_BOOL CFDE_TxtEdtEngine::MoveParagEnd() { 1929 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1; 1930 FDE_TXTEDTPARAGPOS ParagPos; 1931 TextPos2ParagPos(nIndex, ParagPos); 1932 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex]; 1933 nIndex = pParag->m_nCharStart + pParag->m_nCharCount - 1; 1934 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex); 1935 if (wChar == L'\n' && nIndex > 0) { 1936 nIndex--; 1937 wChar = m_pTxtBuf->GetCharByIndex(nIndex); 1938 if (wChar != L'\r') { 1939 nIndex++; 1940 } 1941 } 1942 UpdateCaretRect(nIndex, TRUE); 1943 return TRUE; 1944 } 1945 FX_BOOL CFDE_TxtEdtEngine::MoveHome() { 1946 UpdateCaretRect(0, TRUE); 1947 return TRUE; 1948 } 1949 FX_BOOL CFDE_TxtEdtEngine::MoveEnd() { 1950 UpdateCaretRect(GetTextBufLength(), TRUE); 1951 return TRUE; 1952 } 1953 #ifdef FDE_USEFORMATBLOCK 1954 int32_t CFDE_TxtEdtEngine::NormalizeCaretPos(int32_t nIndex, 1955 int32_t nFlags, 1956 FX_BOOL& bBefore) { 1957 bBefore = TRUE; 1958 int32_t nBgn = 0, nEnd = 0; 1959 int32_t nRecord = -1; 1960 CFDE_TxtEdtField* pField = NULL; 1961 FX_BOOL bRet = GetFieldBoundary(nIndex, nBgn, nEnd, pField); 1962 int32_t nDelta = 0; 1963 if (bRet && !pField->IsFix()) { 1964 if (nIndex - nBgn < FDE_FORMAT_EDIT_FIELD_HADERSIZE) { 1965 if (nFlags == FDE_FORMAT_CARET_BACKWARD) { 1966 CFDE_TxtEdtField* pEditableField = NULL; 1967 if (FindEditableField(nIndex, nBgn, nEnd, pEditableField, FALSE)) { 1968 return pEditableField->NormalizeCaretPos(nEnd - nBgn, 1969 FDE_FORMAT_CARET_BACKWARD) + 1970 nBgn; 1971 } 1972 } 1973 nIndex = nBgn + FDE_FORMAT_EDIT_FIELD_HADERSIZE; 1974 } 1975 int32_t nRet = pField->NormalizeCaretPos( 1976 nIndex - nBgn, (FDE_FORMAT_CARET_DIRECTION)nFlags); 1977 if (nRet >= 0) { 1978 return nRet + nBgn; 1979 } 1980 if (nRet == -2) { 1981 int32_t nEditablePosBgn = 0, nEditablePosEnd = 0; 1982 pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd); 1983 nRecord = nBgn + nEditablePosBgn; 1984 nFlags = FDE_FORMAT_CARET_BACKWARD; 1985 } else { 1986 FXSYS_assert(nRet == -1); 1987 int32_t nEditablePosBgn = 0, nEditablePosEnd = 0; 1988 pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd); 1989 nRecord = nBgn + nEditablePosEnd; 1990 nFlags = FDE_FORMAT_CARET_FORWARD; 1991 } 1992 } else if (!bRet) { 1993 nDelta = FDE_FORMAT_EDIT_FIELD_HADERSIZE - FDE_FORMAT_EDIT_FIELD_TAILSIZE; 1994 } 1995 switch (nFlags) { 1996 case FDE_FORMAT_CARET_FORWARD: { 1997 if (FindEditableField(nIndex, nBgn, nEnd, pField)) { 1998 return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE, 1999 FDE_FORMAT_CARET_FORWARD) + 2000 nBgn; 2001 } else { 2002 if (nRecord != -1) { 2003 return nRecord; 2004 } 2005 bRet = FindEditableField(nIndex, nBgn, nEnd, pField, FALSE); 2006 FXSYS_assert(bRet); 2007 return pField->NormalizeCaretPos(nEnd - nBgn, 2008 FDE_FORMAT_CARET_BACKWARD) + 2009 nBgn; 2010 } 2011 } break; 2012 case FDE_FORMAT_CARET_MIDDLE: { 2013 int32_t nBgn1 = 0, nEnd1 = 0, nBgn2 = 0, nEnd2 = 0; 2014 CFDE_TxtEdtField* pEditableField1 = NULL; 2015 CFDE_TxtEdtField* pEditableField2 = NULL; 2016 FX_BOOL bRet1 = 2017 FindEditableField(nIndex, nBgn1, nEnd1, pEditableField1, FALSE); 2018 FX_BOOL bRet2 = FindEditableField(nIndex, nBgn2, nEnd2, pEditableField2); 2019 if (bRet1 == FALSE) { 2020 FXSYS_assert(bRet2); 2021 return pEditableField2->NormalizeCaretPos( 2022 FDE_FORMAT_EDIT_FIELD_HADERSIZE, FDE_FORMAT_CARET_FORWARD) + 2023 nBgn2; 2024 } else if (bRet2 == FALSE) { 2025 FXSYS_assert(bRet1); 2026 return pEditableField1->NormalizeCaretPos(nEnd1 - nBgn1, 2027 FDE_FORMAT_CARET_BACKWARD) + 2028 nBgn1; 2029 } else { 2030 int32_t nEditablePosBgn = 0, nEditablePosEnd = 0; 2031 if (nIndex - nEnd1 < nBgn2 + nDelta - nIndex) { 2032 pEditableField1->GetEditableRange(nEditablePosBgn, nEditablePosEnd); 2033 return nEditablePosEnd + nBgn1; 2034 } else { 2035 pEditableField2->GetEditableRange(nEditablePosBgn, nEditablePosEnd); 2036 return nEditablePosBgn + nBgn2; 2037 } 2038 } 2039 } break; 2040 case FDE_FORMAT_CARET_BACKWARD: { 2041 if (FindEditableField(nIndex, nBgn, nEnd, pField, FALSE)) { 2042 return pField->NormalizeCaretPos(nEnd - nBgn, 2043 FDE_FORMAT_CARET_BACKWARD) + 2044 nBgn; 2045 } else { 2046 if (nRecord != -1) { 2047 return nRecord; 2048 } 2049 bRet = FindEditableField(nIndex, nBgn, nEnd, pField); 2050 FXSYS_assert(bRet); 2051 return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE, 2052 FDE_FORMAT_CARET_FORWARD) + 2053 nBgn; 2054 } 2055 } break; 2056 default: 2057 FXSYS_assert(0); 2058 return nIndex; 2059 } 2060 } 2061 FX_BOOL CFDE_TxtEdtEngine::GetFieldBoundary(int32_t nIndex, 2062 int32_t& nBgn, 2063 int32_t& nEnd, 2064 CFDE_TxtEdtField*& pField) { 2065 CFDE_TxtEdtBufIter* pIter = 2066 new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE); 2067 pIter->SetAt(nIndex); 2068 FX_BOOL bFind = FALSE; 2069 do { 2070 FX_WCHAR wc = pIter->GetChar(); 2071 if (wc == FDE_TXTEDT_FORMATBLOCK_END) { 2072 nEnd = pIter->GetAt(); 2073 bFind = TRUE; 2074 nIndex--; 2075 break; 2076 } 2077 if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) { 2078 pIter->Release(); 2079 return FALSE; 2080 } 2081 } while (pIter->Next()); 2082 if (!bFind) { 2083 pIter->Release(); 2084 return FALSE; 2085 } 2086 pIter->SetAt(nIndex); 2087 do { 2088 FX_WCHAR wc = pIter->GetChar(); 2089 if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) { 2090 nBgn = pIter->GetAt(); 2091 pIter->Next(); 2092 FX_DWORD dwPre = (FX_DWORD)pIter->GetChar(); 2093 pIter->Next(); 2094 FX_DWORD dwCur = (FX_DWORD)pIter->GetChar(); 2095 pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre); 2096 pIter->Release(); 2097 return TRUE; 2098 } 2099 if (wc == FDE_TXTEDT_FORMATBLOCK_END) { 2100 pIter->Release(); 2101 return FALSE; 2102 } 2103 } while (pIter->Next(TRUE)); 2104 pIter->Release(); 2105 return FALSE; 2106 } 2107 FX_BOOL CFDE_TxtEdtEngine::FindEditableField(int32_t nIndex, 2108 int32_t& nBgn, 2109 int32_t& nEnd, 2110 CFDE_TxtEdtField*& pField, 2111 FX_BOOL bForward) { 2112 FX_WCHAR wcFirst = FDE_TXTEDT_FORMATBLOCK_BGN; 2113 FX_WCHAR wcSecond = FDE_TXTEDT_FORMATBLOCK_END; 2114 if (!bForward) { 2115 wcFirst = FDE_TXTEDT_FORMATBLOCK_END; 2116 wcSecond = FDE_TXTEDT_FORMATBLOCK_BGN; 2117 } 2118 CFDE_TxtEdtBufIter* pIter = 2119 new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE); 2120 pIter->SetAt(nIndex); 2121 int32_t bFind = FALSE; 2122 do { 2123 FX_WCHAR wc = pIter->GetChar(); 2124 if (wc == wcFirst) { 2125 nBgn = pIter->GetAt(); 2126 bFind = TRUE; 2127 break; 2128 } 2129 } while (pIter->Next(!bForward)); 2130 if (!bFind) { 2131 pIter->Release(); 2132 return FALSE; 2133 } 2134 bFind = FALSE; 2135 do { 2136 FX_WCHAR wc = pIter->GetChar(); 2137 if (wc == wcSecond) { 2138 nEnd = pIter->GetAt(); 2139 bFind = TRUE; 2140 break; 2141 } 2142 } while (pIter->Next(!bForward)); 2143 FXSYS_assert(bFind); 2144 if (!bForward) { 2145 int32_t nTemp = nBgn; 2146 nBgn = nEnd; 2147 nEnd = nTemp; 2148 } 2149 pIter->SetAt(nBgn + 1); 2150 FX_DWORD dwPre = (FX_DWORD)pIter->GetChar(); 2151 pIter->Next(); 2152 FX_DWORD dwCur = (FX_DWORD)pIter->GetChar(); 2153 pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre); 2154 pIter->Release(); 2155 if (!pField->IsFix()) { 2156 return TRUE; 2157 } 2158 return FindEditableField((bForward ? nEnd : nBgn), nBgn, nEnd, pField, 2159 bForward); 2160 } 2161 FX_BOOL CFDE_TxtEdtEngine::Move2NextEditableField(int32_t nIndex, 2162 FX_BOOL bForward, 2163 FX_BOOL bSelect) { 2164 if (m_SelRangePtrArr.GetSize() > 0) { 2165 ClearSelection(); 2166 m_Param.pEventSink->On_SelChanged(this); 2167 } 2168 int32_t nBgn = 0, nEnd = 0; 2169 CFDE_TxtEdtField* pField = NULL; 2170 FX_BOOL bRet = FindEditableField(nIndex, nBgn, nEnd, pField, bForward); 2171 if (!bRet) { 2172 return FALSE; 2173 } 2174 int32_t nEditableBgn = 0, nEditableEnd = 0; 2175 pField->GetEditableRange(nEditableBgn, nEditableEnd); 2176 nEditableBgn += nBgn; 2177 nEditableEnd += nBgn; 2178 if (bSelect) { 2179 int32_t nRangeCount = nEditableEnd - nEditableBgn; 2180 if (nRangeCount > 0) { 2181 AddSelRange(nEditableBgn, nEditableEnd - nEditableBgn); 2182 } 2183 } 2184 SetCaretPos(nEditableEnd, TRUE); 2185 return TRUE; 2186 } 2187 int32_t CFDE_TxtEdtEngine::GetRealIndex(int32_t nIndex) const { 2188 CFDE_TxtEdtBufIter* pIter = 2189 new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE); 2190 pIter->SetAt(0); 2191 FX_BOOL bInField = FALSE; 2192 int32_t nFieldBgn = 0; 2193 int32_t nRealIndex = 0; 2194 for (int32_t i = 0; i <= nIndex; i++) { 2195 FX_WCHAR wc = pIter->GetChar(); 2196 if (bInField) { 2197 if (wc == FDE_TXTEDT_FORMATBLOCK_END) { 2198 FX_DWORD dwPre = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 1); 2199 FX_DWORD dwCur = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 2); 2200 CFDE_TxtEdtField* pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre); 2201 nRealIndex += pField->GetFieldTextLength(); 2202 bInField = FALSE; 2203 } 2204 } else { 2205 if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) { 2206 bInField = TRUE; 2207 nFieldBgn = pIter->GetAt(); 2208 } else { 2209 nRealIndex++; 2210 } 2211 } 2212 pIter->Next(); 2213 } 2214 if (!bInField) { 2215 pIter->Release(); 2216 return nRealIndex; 2217 } 2218 pIter->SetAt(nFieldBgn + 1); 2219 FX_DWORD dwPre = (FX_DWORD)pIter->GetChar(); 2220 pIter->Next(); 2221 FX_DWORD dwCur = (FX_DWORD)pIter->GetChar(); 2222 CFDE_TxtEdtField* pField = (CFDE_TxtEdtField*)((dwCur << 16) | dwPre); 2223 pIter->Release(); 2224 if (pField->IsFix()) { 2225 int32_t nDelta = nIndex - nFieldBgn - FDE_FORMAT_EDIT_FIELD_HADERSIZE + 1; 2226 return nRealIndex + (nDelta > 0 ? nDelta : 0); 2227 } else { 2228 return nRealIndex + pField->GetRealIndex(nIndex - nFieldBgn); 2229 } 2230 } 2231 #endif 2232 FX_BOOL CFDE_TxtEdtEngine::IsFitArea(CFX_WideString& wsText) { 2233 IFDE_TextOut* pTextOut = IFDE_TextOut::Create(); 2234 pTextOut->SetLineSpace(m_Param.fLineSpace); 2235 pTextOut->SetFont(m_Param.pFont); 2236 pTextOut->SetFontSize(m_Param.fFontSize); 2237 CFX_RectF rcText; 2238 FXSYS_memset(&rcText, 0, sizeof(rcText)); 2239 FX_DWORD dwStyle = 0; 2240 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) { 2241 dwStyle |= FDE_TTOSTYLE_SingleLine; 2242 } 2243 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { 2244 dwStyle |= FDE_TTOSTYLE_LineWrap; 2245 rcText.width = m_Param.fPlateWidth; 2246 } else { 2247 rcText.width = 65535; 2248 } 2249 pTextOut->SetStyles(dwStyle); 2250 wsText += L"\n"; 2251 pTextOut->CalcLogicSize(wsText, wsText.GetLength(), rcText); 2252 pTextOut->Release(); 2253 wsText.Delete(wsText.GetLength() - 1); 2254 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz) && 2255 (rcText.width > m_Param.fPlateWidth)) { 2256 return FALSE; 2257 } 2258 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) && 2259 (rcText.height > m_Param.fLineSpace * m_Param.nLineCount)) { 2260 return FALSE; 2261 } 2262 return TRUE; 2263 } 2264 void CFDE_TxtEdtEngine::UpdateCaretRect(int32_t nIndex, FX_BOOL bBefore) { 2265 MovePage2Char(nIndex); 2266 GetCaretRect(m_rtCaret, m_nCaretPage, nIndex, bBefore); 2267 m_nCaret = nIndex; 2268 m_bBefore = bBefore; 2269 if (!m_bBefore) { 2270 m_nCaret++; 2271 m_bBefore = TRUE; 2272 } 2273 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) 2274 ? m_rtCaret.top 2275 : m_rtCaret.left; 2276 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0); 2277 } 2278 void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret, 2279 int32_t nPageIndex, 2280 int32_t nCaret, 2281 FX_BOOL bBefore) { 2282 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; 2283 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 2284 FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText; 2285 int32_t nIndexInpage = nCaret - pPage->GetCharStart(); 2286 if (bBefore && bCombText && nIndexInpage > 0) { 2287 nIndexInpage--; 2288 bBefore = FALSE; 2289 } 2290 int32_t nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText); 2291 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { 2292 if ((!FX_IsOdd(nBIDILevel) && !bBefore) || 2293 (FX_IsOdd(nBIDILevel) && bBefore)) { 2294 rtCaret.Offset(0, rtCaret.height - 1.0f); 2295 } 2296 if (rtCaret.height == 0 && rtCaret.top > 1.0f) { 2297 rtCaret.top -= 1.0f; 2298 } 2299 rtCaret.height = 1.0f; 2300 } else { 2301 if ((!FX_IsOdd(nBIDILevel) && !bBefore) || 2302 (FX_IsOdd(nBIDILevel) && bBefore)) { 2303 rtCaret.Offset(rtCaret.width - 1.0f, 0); 2304 } 2305 if (rtCaret.width == 0 && rtCaret.left > 1.0f) { 2306 rtCaret.left -= 1.0f; 2307 } 2308 rtCaret.width = 1.0f; 2309 } 2310 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 2311 } 2312 void CFDE_TxtEdtEngine::UpdateCaretIndex(const CFX_PointF& ptCaret) { 2313 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage]; 2314 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0); 2315 m_nCaret = pPage->GetCharIndex(ptCaret, m_bBefore); 2316 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore); 2317 if (!m_bBefore) { 2318 m_nCaret++; 2319 m_bBefore = TRUE; 2320 } 2321 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage); 2322 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0); 2323 } 2324 FX_BOOL CFDE_TxtEdtEngine::IsSelect() { 2325 return m_SelRangePtrArr.GetSize() > 0; 2326 } 2327 void CFDE_TxtEdtEngine::DeleteSelect() { 2328 int32_t nCountRange = CountSelRanges(); 2329 if (nCountRange > 0) { 2330 #ifdef FDE_USEFORMATBLOCK 2331 int32_t nBlockCount = m_BlockArray.GetSize(); 2332 if (nBlockCount > 0) { 2333 if (nCountRange > 1) { 2334 return; 2335 } 2336 int32_t nSelStart; 2337 int32_t nSelCount; 2338 nSelCount = GetSelRange(0, nSelStart); 2339 int32_t nSelEnd = nSelStart + nSelCount; 2340 int32_t nBgn = 0; 2341 int32_t nEnd = 0; 2342 CFDE_TxtEdtField* pField = NULL; 2343 FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField); 2344 int32_t nCaretInField = nSelStart - nBgn; 2345 FX_BOOL bBefore = FALSE; 2346 if (!bInField || pField->IsFix() || nSelEnd > nEnd) { 2347 return; 2348 } 2349 pField->Backup(); 2350 CFX_WideString wsDel; 2351 int32_t nCaret = 0; 2352 int32_t nRet = 2353 pField->Delete(nCaretInField, nSelCount, wsDel, nCaret, bBefore); 2354 nCaret += nBgn; 2355 switch (nRet) { 2356 case FDE_FORMAT_FIELD_DELETE_RET_S: 2357 break; 2358 case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE: 2359 case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY: 2360 return; 2361 default: 2362 FXSYS_assert(0); 2363 break; 2364 } 2365 CFX_WideString wsField; 2366 pField->GetFieldText(wsField); 2367 if (!m_Param.pEventSink->On_ValidateField( 2368 this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) { 2369 pField->Restore(); 2370 return; 2371 } 2372 CFX_WideString wsDisplay; 2373 pField->GetDisplayText(wsDisplay); 2374 Replace(nBgn, nEnd - nBgn + 1, wsDisplay); 2375 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) { 2376 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_FieldDelete( 2377 this, nSelStart, pField, nCaretInField, nBgn, nEnd - nBgn + 1, 2378 wsDisplay.GetLength(), wsDel, FALSE); 2379 CFX_ByteString bsDoRecord; 2380 pRecord->Serialize(bsDoRecord); 2381 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord); 2382 pRecord->Release(); 2383 } 2384 SetCaretPos(nSelStart, bBefore); 2385 return; 2386 } 2387 #endif 2388 int32_t nSelStart; 2389 int32_t nSelCount; 2390 while (nCountRange > 0) { 2391 nSelCount = GetSelRange(--nCountRange, nSelStart); 2392 FDE_LPTXTEDTSELRANGE lpTemp = m_SelRangePtrArr[nCountRange]; 2393 delete lpTemp; 2394 m_SelRangePtrArr.RemoveAt(nCountRange); 2395 DeleteRange_DoRecord(nSelStart, nSelCount, TRUE); 2396 } 2397 ClearSelection(); 2398 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo); 2399 m_Param.pEventSink->On_SelChanged(this); 2400 SetCaretPos(nSelStart, TRUE); 2401 return; 2402 } 2403 } 2404 IFDE_TxtEdtDoRecord* IFDE_TxtEdtDoRecord::Create( 2405 const CFX_ByteStringC& bsDoRecord) { 2406 const FX_CHAR* lpBuf = bsDoRecord.GetCStr(); 2407 int32_t nType = *((int32_t*)lpBuf); 2408 switch (nType) { 2409 case FDE_TXTEDT_DORECORD_INS: 2410 return new CFDE_TxtEdtDoRecord_Insert(bsDoRecord); 2411 case FDE_TXTEDT_DORECORD_DEL: 2412 return new CFDE_TxtEdtDoRecord_DeleteRange(bsDoRecord); 2413 #ifdef FDE_USEFORMATBLOCK 2414 case FDE_TXTEDT_DORECORD_FORMATINS: 2415 return new CFDE_TxtEdtDoRecord_FieldInsert(bsDoRecord); 2416 case FDE_TXTEDT_DORECORD_FORMATDEL: 2417 return new CFDE_TxtEdtDoRecord_FieldDelete(bsDoRecord); 2418 case FDE_TXTEDT_DORECORD_FORMATREP: 2419 return new CFDE_TxtEdtDoRecord_FieldReplace(bsDoRecord); 2420 #endif 2421 default: 2422 break; 2423 } 2424 return NULL; 2425 } 2426 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert( 2427 const CFX_ByteStringC& bsDoRecord) { 2428 Deserialize(bsDoRecord); 2429 } 2430 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert( 2431 CFDE_TxtEdtEngine* pEngine, 2432 int32_t nCaret, 2433 const FX_WCHAR* lpText, 2434 int32_t nLength) 2435 : m_pEngine(pEngine), m_nCaret(nCaret) { 2436 FXSYS_assert(pEngine); 2437 FX_WCHAR* lpBuffer = m_wsInsert.GetBuffer(nLength); 2438 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR)); 2439 m_wsInsert.ReleaseBuffer(); 2440 } 2441 CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert() {} 2442 void CFDE_TxtEdtDoRecord_Insert::Release() { 2443 delete this; 2444 } 2445 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Undo() { 2446 if (m_pEngine->IsSelect()) { 2447 m_pEngine->ClearSelection(); 2448 } 2449 m_pEngine->Inner_DeleteRange(m_nCaret, m_wsInsert.GetLength()); 2450 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; 2451 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete; 2452 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert; 2453 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); 2454 m_pEngine->SetCaretPos(m_nCaret, TRUE); 2455 return TRUE; 2456 } 2457 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Redo() { 2458 m_pEngine->Inner_Insert(m_nCaret, m_wsInsert.c_str(), m_wsInsert.GetLength()); 2459 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; 2460 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; 2461 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert; 2462 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); 2463 m_pEngine->SetCaretPos(m_nCaret, FALSE); 2464 return TRUE; 2465 } 2466 void CFDE_TxtEdtDoRecord_Insert::Serialize(CFX_ByteString& bsDoRecord) const { 2467 CFX_ArchiveSaver ArchiveSaver; 2468 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_INS); 2469 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine; 2470 ArchiveSaver << m_nCaret; 2471 ArchiveSaver << m_wsInsert; 2472 int32_t nLength = ArchiveSaver.GetLength(); 2473 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); 2474 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); 2475 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); 2476 bsDoRecord.ReleaseBuffer(nLength); 2477 } 2478 void CFDE_TxtEdtDoRecord_Insert::Deserialize( 2479 const CFX_ByteStringC& bsDoRecord) { 2480 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), 2481 bsDoRecord.GetLength()); 2482 int32_t nType = 0; 2483 ArchiveLoader >> nType; 2484 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_INS); 2485 int32_t nEngine = 0; 2486 ArchiveLoader >> nEngine; 2487 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; 2488 ArchiveLoader >> m_nCaret; 2489 ArchiveLoader >> m_wsInsert; 2490 } 2491 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange( 2492 const CFX_ByteStringC& bsDoRecord) { 2493 Deserialize(bsDoRecord); 2494 } 2495 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange( 2496 CFDE_TxtEdtEngine* pEngine, 2497 int32_t nIndex, 2498 int32_t nCaret, 2499 const CFX_WideString& wsRange, 2500 FX_BOOL bSel) 2501 : m_pEngine(pEngine), 2502 m_bSel(bSel), 2503 m_nIndex(nIndex), 2504 m_nCaret(nCaret), 2505 m_wsRange(wsRange) { 2506 FXSYS_assert(pEngine); 2507 } 2508 CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange() {} 2509 void CFDE_TxtEdtDoRecord_DeleteRange::Release() { 2510 delete this; 2511 } 2512 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Undo() { 2513 if (m_pEngine->IsSelect()) { 2514 m_pEngine->ClearSelection(); 2515 } 2516 m_pEngine->Inner_Insert(m_nIndex, m_wsRange.c_str(), m_wsRange.GetLength()); 2517 if (m_bSel) { 2518 m_pEngine->AddSelRange(m_nIndex, m_wsRange.GetLength()); 2519 } 2520 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; 2521 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; 2522 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange; 2523 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); 2524 m_pEngine->SetCaretPos(m_nCaret, TRUE); 2525 return TRUE; 2526 } 2527 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Redo() { 2528 m_pEngine->Inner_DeleteRange(m_nIndex, m_wsRange.GetLength()); 2529 if (m_bSel) { 2530 m_pEngine->RemoveSelRange(m_nIndex, m_wsRange.GetLength()); 2531 } 2532 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param; 2533 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert; 2534 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange; 2535 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo); 2536 m_pEngine->SetCaretPos(m_nIndex, TRUE); 2537 return TRUE; 2538 } 2539 void CFDE_TxtEdtDoRecord_DeleteRange::Serialize( 2540 CFX_ByteString& bsDoRecord) const { 2541 CFX_ArchiveSaver ArchiveSaver; 2542 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_DEL); 2543 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine; 2544 ArchiveSaver << (int32_t)m_bSel; 2545 ArchiveSaver << m_nIndex; 2546 ArchiveSaver << m_nCaret; 2547 ArchiveSaver << m_wsRange; 2548 int32_t nLength = ArchiveSaver.GetLength(); 2549 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); 2550 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); 2551 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); 2552 bsDoRecord.ReleaseBuffer(nLength); 2553 } 2554 void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize( 2555 const CFX_ByteStringC& bsDoRecord) { 2556 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), 2557 bsDoRecord.GetLength()); 2558 int32_t nType = 0; 2559 ArchiveLoader >> nType; 2560 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_DEL); 2561 int32_t nEngine = 0; 2562 ArchiveLoader >> nEngine; 2563 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; 2564 int32_t iSel = 0; 2565 ArchiveLoader >> iSel; 2566 m_bSel = !!iSel; 2567 ArchiveLoader >> m_nIndex; 2568 ArchiveLoader >> m_nCaret; 2569 ArchiveLoader >> m_wsRange; 2570 } 2571 #ifdef FDE_USEFORMATBLOCK 2572 CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert( 2573 const CFX_ByteStringC& bsDoRecord) { 2574 Deserialize(bsDoRecord); 2575 } 2576 CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert( 2577 CFDE_TxtEdtEngine* pEngine, 2578 int32_t nCaret, 2579 CFDE_TxtEdtField* pField, 2580 int32_t nIndexInField, 2581 int32_t nFieldBgn, 2582 int32_t nOldFieldLength, 2583 int32_t nNewFieldLength, 2584 const CFX_WideString& wsIns, 2585 FX_BOOL bSel) 2586 : m_pEngine(pEngine), 2587 m_nCaret(nCaret), 2588 m_pField(pField), 2589 m_nIndexInField(nIndexInField), 2590 m_nFieldBgn(nFieldBgn), 2591 m_nOldFieldLength(nOldFieldLength), 2592 m_nNewFieldLength(nNewFieldLength), 2593 m_wsIns(wsIns), 2594 m_bSel(bSel) { 2595 FXSYS_assert(pEngine); 2596 FXSYS_assert(pField); 2597 } 2598 CFDE_TxtEdtDoRecord_FieldInsert::~CFDE_TxtEdtDoRecord_FieldInsert() {} 2599 void CFDE_TxtEdtDoRecord_FieldInsert::Release() { 2600 delete this; 2601 } 2602 FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Undo() { 2603 CFX_WideString wsDel; 2604 int32_t nCaret = 0; 2605 FX_BOOL bBefore = FALSE; 2606 int32_t nRet = m_pField->Delete(m_nIndexInField, m_wsIns.GetLength(), wsDel, 2607 nCaret, bBefore); 2608 FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && 2609 nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY); 2610 CFX_WideString wsDisplay; 2611 m_pField->GetDisplayText(wsDisplay); 2612 m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay); 2613 m_pEngine->SetCaretPos(m_nCaret, TRUE); 2614 return TRUE; 2615 } 2616 FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Redo() { 2617 int32_t nCaret = 0; 2618 FX_BOOL bBefore = FALSE; 2619 int32_t nRet = m_pField->Insert(m_nIndexInField, m_wsIns, nCaret, bBefore); 2620 FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL && 2621 nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE); 2622 CFX_WideString wsDisplay; 2623 m_pField->GetDisplayText(wsDisplay); 2624 m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay); 2625 m_pEngine->SetCaretPos(m_nCaret + m_wsIns.GetLength(), TRUE); 2626 return TRUE; 2627 } 2628 void CFDE_TxtEdtDoRecord_FieldInsert::Serialize( 2629 CFX_ByteString& bsDoRecord) const { 2630 CFX_ArchiveSaver ArchiveSaver; 2631 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATINS); 2632 ArchiveSaver << int32_t(m_pEngine); 2633 ArchiveSaver << m_nCaret; 2634 ArchiveSaver << int32_t(m_pField); 2635 ArchiveSaver << m_nIndexInField; 2636 ArchiveSaver << m_nFieldBgn; 2637 ArchiveSaver << m_nOldFieldLength; 2638 ArchiveSaver << m_nNewFieldLength; 2639 ArchiveSaver << m_wsIns; 2640 ArchiveSaver << m_bSel; 2641 int32_t nLength = ArchiveSaver.GetLength(); 2642 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); 2643 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); 2644 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); 2645 bsDoRecord.ReleaseBuffer(nLength); 2646 } 2647 void CFDE_TxtEdtDoRecord_FieldInsert::Deserialize( 2648 const CFX_ByteStringC& bsDoRecord) { 2649 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), 2650 bsDoRecord.GetLength()); 2651 int32_t nType = 0; 2652 ArchiveLoader >> nType; 2653 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATINS); 2654 int32_t nEngine = 0; 2655 ArchiveLoader >> nEngine; 2656 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; 2657 ArchiveLoader >> m_nCaret; 2658 int32_t nField = 0; 2659 ArchiveLoader >> nField; 2660 m_pField = (CFDE_TxtEdtField*)nField; 2661 ArchiveLoader >> m_nIndexInField; 2662 ArchiveLoader >> m_nFieldBgn; 2663 ArchiveLoader >> m_nOldFieldLength; 2664 ArchiveLoader >> m_nNewFieldLength; 2665 ArchiveLoader >> m_wsIns; 2666 ArchiveLoader >> m_bSel; 2667 } 2668 CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete( 2669 const CFX_ByteStringC& bsDoRecord) { 2670 Deserialize(bsDoRecord); 2671 } 2672 CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete( 2673 CFDE_TxtEdtEngine* pEngine, 2674 int32_t nCaret, 2675 CFDE_TxtEdtField* pField, 2676 int32_t nIndexInField, 2677 int32_t nFieldBgn, 2678 int32_t nOldLength, 2679 int32_t nNewLength, 2680 const CFX_WideString& wsDel, 2681 FX_BOOL bSel) 2682 : m_pEngine(pEngine), 2683 m_nCaret(nCaret), 2684 m_pField(pField), 2685 m_nIndexInField(nIndexInField), 2686 m_nFieldBgn(nFieldBgn), 2687 m_nOldFieldLength(nOldLength), 2688 m_nNewFieldLength(nNewLength), 2689 m_wsDel(wsDel), 2690 m_bSel(bSel) { 2691 FXSYS_assert(m_pEngine); 2692 FXSYS_assert(m_pField); 2693 } 2694 CFDE_TxtEdtDoRecord_FieldDelete::~CFDE_TxtEdtDoRecord_FieldDelete() {} 2695 void CFDE_TxtEdtDoRecord_FieldDelete::Release() { 2696 delete this; 2697 } 2698 FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Undo() { 2699 int32_t nCaret = 0; 2700 FX_BOOL bBefore = FALSE; 2701 int32_t nRet = m_pField->Insert(m_nIndexInField, m_wsDel, nCaret, bBefore); 2702 FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL && 2703 nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE); 2704 CFX_WideString wsDisplay; 2705 m_pField->GetDisplayText(wsDisplay); 2706 m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay); 2707 m_pEngine->SetCaretPos(m_nCaret, TRUE); 2708 return TRUE; 2709 } 2710 FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Redo() { 2711 int32_t nCaret = 0; 2712 FX_BOOL bBefore = 0; 2713 CFX_WideString wsDel; 2714 int32_t nRet = m_pField->Delete(m_nIndexInField, m_wsDel.GetLength(), wsDel, 2715 nCaret, bBefore); 2716 FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && 2717 nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY); 2718 CFX_WideString wsDisplay; 2719 m_pField->GetDisplayText(wsDisplay); 2720 m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay); 2721 m_pEngine->SetCaretPos(m_nCaret - m_wsDel.GetLength(), TRUE); 2722 return TRUE; 2723 } 2724 void CFDE_TxtEdtDoRecord_FieldDelete::Serialize( 2725 CFX_ByteString& bsDoRecord) const { 2726 CFX_ArchiveSaver ArchiveSaver; 2727 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATDEL); 2728 ArchiveSaver << int32_t(m_pEngine); 2729 ArchiveSaver << m_nCaret; 2730 ArchiveSaver << int32_t(m_pField); 2731 ArchiveSaver << m_nIndexInField; 2732 ArchiveSaver << m_nFieldBgn; 2733 ArchiveSaver << m_nOldFieldLength; 2734 ArchiveSaver << m_nNewFieldLength; 2735 ArchiveSaver << m_wsDel; 2736 ArchiveSaver << m_bSel; 2737 int32_t nLength = ArchiveSaver.GetLength(); 2738 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); 2739 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); 2740 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); 2741 bsDoRecord.ReleaseBuffer(nLength); 2742 } 2743 void CFDE_TxtEdtDoRecord_FieldDelete::Deserialize( 2744 const CFX_ByteStringC& bsDoRecord) { 2745 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), 2746 bsDoRecord.GetLength()); 2747 int32_t nType = 0; 2748 ArchiveLoader >> nType; 2749 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATDEL); 2750 int32_t nEngine = 0; 2751 ArchiveLoader >> nEngine; 2752 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; 2753 ArchiveLoader >> m_nCaret; 2754 int32_t nField = 0; 2755 ArchiveLoader >> nField; 2756 m_pField = (CFDE_TxtEdtField*)nField; 2757 ArchiveLoader >> m_nIndexInField; 2758 ArchiveLoader >> m_nFieldBgn; 2759 ArchiveLoader >> m_nOldFieldLength; 2760 ArchiveLoader >> m_nNewFieldLength; 2761 ArchiveLoader >> m_wsDel; 2762 ArchiveLoader >> m_bSel; 2763 } 2764 CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace( 2765 const CFX_ByteStringC& bsDoRecord) { 2766 Deserialize(bsDoRecord); 2767 } 2768 CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace( 2769 CFDE_TxtEdtEngine* pEngine, 2770 int32_t nCaret, 2771 int32_t nNewCaret, 2772 CFDE_TxtEdtField* pField, 2773 int32_t nIndexInField, 2774 int32_t nFieldBgn, 2775 int32_t nFieldNewLength, 2776 const CFX_WideString& wsDel, 2777 const CFX_WideString& wsIns, 2778 FX_BOOL bSel) 2779 : m_pEngine(pEngine), 2780 m_nCaret(nCaret), 2781 m_nNewCaret(nNewCaret), 2782 m_pField(pField), 2783 m_nIndexInField(nIndexInField), 2784 m_nFieldBgn(nFieldBgn), 2785 m_nFieldNewLength(nFieldNewLength), 2786 m_wsDel(wsDel), 2787 m_wsIns(wsIns), 2788 m_bSel(bSel) { 2789 FXSYS_assert(m_pEngine); 2790 FXSYS_assert(m_pField); 2791 } 2792 CFDE_TxtEdtDoRecord_FieldReplace::~CFDE_TxtEdtDoRecord_FieldReplace() {} 2793 void CFDE_TxtEdtDoRecord_FieldReplace::Release() { 2794 delete this; 2795 } 2796 FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Undo() { 2797 CFX_WideString wsDel; 2798 int32_t nCaret = 0; 2799 FX_BOOL bBefore = FALSE; 2800 int32_t nRet = m_pField->Replace(m_nIndexInField, m_wsIns.GetLength(), 2801 m_wsDel, wsDel, nCaret, bBefore); 2802 FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && 2803 nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY); 2804 CFX_WideString wsDisplay; 2805 m_pField->GetDisplayText(wsDisplay); 2806 m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay); 2807 m_pEngine->SetCaretPos(m_nCaret, TRUE); 2808 return TRUE; 2809 } 2810 FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Redo() { 2811 CFX_WideString wsDel; 2812 int32_t nCaret = 0; 2813 FX_BOOL bBefore = FALSE; 2814 int32_t nRet = m_pField->Replace(m_nIndexInField, m_wsDel.GetLength(), 2815 m_wsIns, wsDel, nCaret, bBefore); 2816 FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && 2817 nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY); 2818 CFX_WideString wsDisplay; 2819 m_pField->GetDisplayText(wsDisplay); 2820 m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay); 2821 m_pEngine->SetCaretPos(m_nNewCaret, TRUE); 2822 return TRUE; 2823 } 2824 void CFDE_TxtEdtDoRecord_FieldReplace::Serialize( 2825 CFX_ByteString& bsDoRecord) const { 2826 CFX_ArchiveSaver ArchiveSaver; 2827 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_FORMATREP); 2828 ArchiveSaver << int32_t(m_pEngine); 2829 ArchiveSaver << m_nCaret; 2830 ArchiveSaver << m_nNewCaret; 2831 ArchiveSaver << int32_t(m_pField); 2832 ArchiveSaver << m_nIndexInField; 2833 ArchiveSaver << m_nFieldBgn; 2834 ArchiveSaver << m_nFieldNewLength; 2835 ArchiveSaver << m_wsDel; 2836 ArchiveSaver << m_wsIns; 2837 ArchiveSaver << m_bSel; 2838 int32_t nLength = ArchiveSaver.GetLength(); 2839 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer(); 2840 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength); 2841 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength); 2842 bsDoRecord.ReleaseBuffer(nLength); 2843 } 2844 void CFDE_TxtEdtDoRecord_FieldReplace::Deserialize( 2845 const CFX_ByteStringC& bsDoRecord) { 2846 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(), 2847 bsDoRecord.GetLength()); 2848 int32_t nType = 0; 2849 ArchiveLoader >> nType; 2850 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATREP); 2851 int32_t nEngine = 0; 2852 ArchiveLoader >> nEngine; 2853 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine; 2854 ArchiveLoader >> m_nCaret; 2855 ArchiveLoader >> m_nNewCaret; 2856 int32_t nField = 0; 2857 ArchiveLoader >> nField; 2858 m_pField = (CFDE_TxtEdtField*)nField; 2859 ArchiveLoader >> m_nIndexInField; 2860 ArchiveLoader >> m_nFieldBgn; 2861 ArchiveLoader >> m_nFieldNewLength; 2862 ArchiveLoader >> m_wsDel; 2863 ArchiveLoader >> m_wsIns; 2864 ArchiveLoader >> m_bSel; 2865 } 2866 #endif 2867