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
Create()31 IFDE_TxtEdtEngine* IFDE_TxtEdtEngine::Create() {
32   return new CFDE_TxtEdtEngine();
33 }
CFDE_TxtEdtEngine()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 }
~CFDE_TxtEdtEngine()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 }
Release()83 void CFDE_TxtEdtEngine::Release() {
84   delete this;
85 }
SetEditParams(const FDE_TXTEDTPARAMS & params)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, &params, sizeof(FDE_TXTEDTPARAMS));
91   m_wLineEnd = params.wLineBreakChar;
92   m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
93   UpdateTxtBreak();
94 }
GetEditParams() const95 const FDE_TXTEDTPARAMS* CFDE_TxtEdtEngine::GetEditParams() const {
96   return &m_Param;
97 }
CountPages() const98 int32_t CFDE_TxtEdtEngine::CountPages() const {
99   if (m_nLineCount == 0) {
100     return 0;
101   }
102   return ((m_nLineCount - 1) / m_nPageLineCount) + 1;
103 }
GetPage(int32_t nIndex)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 }
SetBufChunkSize(int32_t nChunkSize)110 FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(int32_t nChunkSize) {
111   return m_pTxtBuf->SetChunkSize(nChunkSize);
112 }
SetTextByStream(IFX_Stream * pStream)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 }
SetText(const CFX_WideString & wsText)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 }
GetTextLength() const160 int32_t CFDE_TxtEdtEngine::GetTextLength() const {
161   return GetTextBufLength();
162 }
GetText(CFX_WideString & wsText,int32_t nStart,int32_t nCount)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 }
ClearText()216 void CFDE_TxtEdtEngine::ClearText() {
217   DeleteRange(0, -1);
218 }
GetCaretRect(CFX_RectF & rtCaret) const219 int32_t CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret) const {
220   rtCaret = m_rtCaret;
221   return m_nCaret;
222 }
GetCaretPos() const223 int32_t CFDE_TxtEdtEngine::GetCaretPos() const {
224   if (IsLocked()) {
225     return 0;
226   }
227   return m_nCaret + (m_bBefore ? 0 : 1);
228 }
SetCaretPos(int32_t nIndex,FX_BOOL bBefore)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 }
MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret,FX_BOOL bShift,FX_BOOL bCtrl)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 }
Lock()403 void CFDE_TxtEdtEngine::Lock() {
404   m_bLock = TRUE;
405 }
Unlock()406 void CFDE_TxtEdtEngine::Unlock() {
407   m_bLock = FALSE;
408 }
IsLocked() const409 FX_BOOL CFDE_TxtEdtEngine::IsLocked() const {
410   return m_bLock;
411 }
Insert(int32_t nStart,const FX_WCHAR * lpText,int32_t nLength)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 }
Delete(int32_t nStart,FX_BOOL bBackspace)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 }
DeleteRange(int32_t nStart,int32_t nCount)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 }
Replace(int32_t nStart,int32_t nLength,const CFX_WideString & wsReplace)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 }
SetLimit(int32_t nLimit)832 void CFDE_TxtEdtEngine::SetLimit(int32_t nLimit) {
833   m_nLimit = nLimit;
834 }
SetAliasChar(FX_WCHAR wcAlias)835 void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias) {
836   m_wcAliasChar = wcAlias;
837 }
SetFormatBlock(int32_t nIndex,const CFX_WideString & wsBlockFormat)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 }
CountEditBlocks() const887 int32_t CFDE_TxtEdtEngine::CountEditBlocks() const {
888 #ifdef FDE_USEFORMATBLOCK
889   return m_BlockArray.GetSize();
890 #else
891   return 0;
892 #endif
893 }
GetEditBlockText(int32_t nIndex,CFX_WideString & wsBlockText) const894 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 }
CountEditFields(int32_t nBlockIndex) const901 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 }
GetEditFieldText(int32_t nBlockIndex,int32_t nFieldIndex,CFX_WideString & wsFieldText) const909 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 }
StartEdit()917 void CFDE_TxtEdtEngine::StartEdit() {
918 #ifdef FDE_USEFORMATBLOCK
919 #endif
920 }
EndEdit()921 void CFDE_TxtEdtEngine::EndEdit() {
922 #ifdef FDE_USEFORMATBLOCK
923 #endif
924 }
RemoveSelRange(int32_t nStart,int32_t nCount)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 }
AddSelRange(int32_t nStart,int32_t nCount)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 }
CountSelRanges()1008 int32_t CFDE_TxtEdtEngine::CountSelRanges() {
1009   return m_SelRangePtrArr.GetSize();
1010 }
GetSelRange(int32_t nIndex,int32_t & nStart)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 }
ClearSelection()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 }
Redo(const CFX_ByteStringC & bsRedo)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 }
Undo(const CFX_ByteStringC & bsUndo)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 }
StartLayout()1063 int32_t CFDE_TxtEdtEngine::StartLayout() {
1064   Lock();
1065   RemoveAllPages();
1066   m_nLayoutPos = 0;
1067   m_nLineCount = 0;
1068   return 0;
1069 }
DoLayout(IFX_Pause * pPause)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 }
EndLayout()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 }
Optimize(IFX_Pause * pPause)1100 FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause* pPause) {
1101   return m_pTxtBuf->Optimize(pPause);
1102 }
GetTextBuf() const1103 IFDE_TxtEdtBuf* CFDE_TxtEdtEngine::GetTextBuf() const {
1104   return (IFDE_TxtEdtBuf*)m_pTxtBuf;
1105 }
GetTextBufLength() const1106 int32_t CFDE_TxtEdtEngine::GetTextBufLength() const {
1107   return m_pTxtBuf->GetTextLength() - 1;
1108 }
GetTextBreak() const1109 IFX_TxtBreak* CFDE_TxtEdtEngine::GetTextBreak() const {
1110   return m_pTextBreak;
1111 }
GetLineCount() const1112 int32_t CFDE_TxtEdtEngine::GetLineCount() const {
1113   return m_nLineCount;
1114 }
GetPageLineCount() const1115 int32_t CFDE_TxtEdtEngine::GetPageLineCount() const {
1116   return m_nPageLineCount;
1117 }
CountParags() const1118 int32_t CFDE_TxtEdtEngine::CountParags() const {
1119   return m_ParagPtrArray.GetSize();
1120 }
GetParag(int32_t nParagIndex) const1121 IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const {
1122   return m_ParagPtrArray[nParagIndex];
1123 }
CreateCharIter()1124 IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() {
1125   if (!m_pTxtBuf) {
1126     return NULL;
1127   }
1128   return new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
1129 }
Line2Parag(int32_t nStartParag,int32_t nStartLineofParag,int32_t nLineIndex,int32_t & nStartLine) const1130 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 }
GetPreDeleteText(CFX_WideString & wsText,int32_t nIndex,int32_t nLength)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 }
GetPreInsertText(CFX_WideString & wsText,int32_t nIndex,const FX_WCHAR * lpText,int32_t nLength)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 }
GetPreReplaceText(CFX_WideString & wsText,int32_t nIndex,int32_t nOriginLength,const FX_WCHAR * lpText,int32_t nLength)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 }
Inner_Insert(int32_t nStart,const FX_WCHAR * lpText,int32_t nLength)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
RawInsert(int32_t nStart,const FX_WCHAR * lpText,int32_t nLength)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
Inner_DeleteRange(int32_t nStart,int32_t nCount)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 }
DeleteRange_DoRecord(int32_t nStart,int32_t nCount,FX_BOOL bSel)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 }
ResetEngine()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 }
RebuildParagraphs()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 }
RemoveAllParags()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 }
RemoveAllPages()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 }
UpdateParags()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 }
UpdatePages()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 }
UpdateTxtBreak()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 }
ReplaceParagEnd(FX_WCHAR * & lpText,int32_t & nLength,FX_BOOL bPreIsCR)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 }
RecoverParagEnd(CFX_WideString & wsText)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 }
MovePage2Char(int32_t nIndex)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 }
TextPos2ParagPos(int32_t nIndex,FDE_TXTEDTPARAGPOS & ParagPos) const1722 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 }
MoveForward(FX_BOOL & bBefore)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 }
MoveBackward(FX_BOOL & bBefore)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 }
MoveUp(CFX_PointF & ptCaret)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 }
MoveDown(CFX_PointF & ptCaret)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 }
MoveLineStart()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 }
MoveLineEnd()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 }
MoveParagStart()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 }
MoveParagEnd()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 }
MoveHome()1945 FX_BOOL CFDE_TxtEdtEngine::MoveHome() {
1946   UpdateCaretRect(0, TRUE);
1947   return TRUE;
1948 }
MoveEnd()1949 FX_BOOL CFDE_TxtEdtEngine::MoveEnd() {
1950   UpdateCaretRect(GetTextBufLength(), TRUE);
1951   return TRUE;
1952 }
1953 #ifdef FDE_USEFORMATBLOCK
NormalizeCaretPos(int32_t nIndex,int32_t nFlags,FX_BOOL & bBefore)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 }
GetFieldBoundary(int32_t nIndex,int32_t & nBgn,int32_t & nEnd,CFDE_TxtEdtField * & pField)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 }
FindEditableField(int32_t nIndex,int32_t & nBgn,int32_t & nEnd,CFDE_TxtEdtField * & pField,FX_BOOL bForward)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 }
Move2NextEditableField(int32_t nIndex,FX_BOOL bForward,FX_BOOL bSelect)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 }
GetRealIndex(int32_t nIndex) const2187 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
IsFitArea(CFX_WideString & wsText)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 }
UpdateCaretRect(int32_t nIndex,FX_BOOL bBefore)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 }
GetCaretRect(CFX_RectF & rtCaret,int32_t nPageIndex,int32_t nCaret,FX_BOOL bBefore)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 }
UpdateCaretIndex(const CFX_PointF & ptCaret)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 }
IsSelect()2324 FX_BOOL CFDE_TxtEdtEngine::IsSelect() {
2325   return m_SelRangePtrArr.GetSize() > 0;
2326 }
DeleteSelect()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 }
Create(const CFX_ByteStringC & bsDoRecord)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 }
CFDE_TxtEdtDoRecord_Insert(const CFX_ByteStringC & bsDoRecord)2426 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(
2427     const CFX_ByteStringC& bsDoRecord) {
2428   Deserialize(bsDoRecord);
2429 }
CFDE_TxtEdtDoRecord_Insert(CFDE_TxtEdtEngine * pEngine,int32_t nCaret,const FX_WCHAR * lpText,int32_t nLength)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 }
~CFDE_TxtEdtDoRecord_Insert()2441 CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert() {}
Release()2442 void CFDE_TxtEdtDoRecord_Insert::Release() {
2443   delete this;
2444 }
Undo()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 }
Redo()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 }
Serialize(CFX_ByteString & bsDoRecord) const2466 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 }
Deserialize(const CFX_ByteStringC & bsDoRecord)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 }
CFDE_TxtEdtDoRecord_DeleteRange(const CFX_ByteStringC & bsDoRecord)2491 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(
2492     const CFX_ByteStringC& bsDoRecord) {
2493   Deserialize(bsDoRecord);
2494 }
CFDE_TxtEdtDoRecord_DeleteRange(CFDE_TxtEdtEngine * pEngine,int32_t nIndex,int32_t nCaret,const CFX_WideString & wsRange,FX_BOOL bSel)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 }
~CFDE_TxtEdtDoRecord_DeleteRange()2508 CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange() {}
Release()2509 void CFDE_TxtEdtDoRecord_DeleteRange::Release() {
2510   delete this;
2511 }
Undo()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 }
Redo()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 }
Serialize(CFX_ByteString & bsDoRecord) const2539 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 }
Deserialize(const CFX_ByteStringC & bsDoRecord)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
CFDE_TxtEdtDoRecord_FieldInsert(const CFX_ByteStringC & bsDoRecord)2572 CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert(
2573     const CFX_ByteStringC& bsDoRecord) {
2574   Deserialize(bsDoRecord);
2575 }
CFDE_TxtEdtDoRecord_FieldInsert(CFDE_TxtEdtEngine * pEngine,int32_t nCaret,CFDE_TxtEdtField * pField,int32_t nIndexInField,int32_t nFieldBgn,int32_t nOldFieldLength,int32_t nNewFieldLength,const CFX_WideString & wsIns,FX_BOOL bSel)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 }
~CFDE_TxtEdtDoRecord_FieldInsert()2598 CFDE_TxtEdtDoRecord_FieldInsert::~CFDE_TxtEdtDoRecord_FieldInsert() {}
Release()2599 void CFDE_TxtEdtDoRecord_FieldInsert::Release() {
2600   delete this;
2601 }
Undo()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 }
Redo()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 }
Serialize(CFX_ByteString & bsDoRecord) const2628 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 }
Deserialize(const CFX_ByteStringC & bsDoRecord)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 }
CFDE_TxtEdtDoRecord_FieldDelete(const CFX_ByteStringC & bsDoRecord)2668 CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete(
2669     const CFX_ByteStringC& bsDoRecord) {
2670   Deserialize(bsDoRecord);
2671 }
CFDE_TxtEdtDoRecord_FieldDelete(CFDE_TxtEdtEngine * pEngine,int32_t nCaret,CFDE_TxtEdtField * pField,int32_t nIndexInField,int32_t nFieldBgn,int32_t nOldLength,int32_t nNewLength,const CFX_WideString & wsDel,FX_BOOL bSel)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 }
~CFDE_TxtEdtDoRecord_FieldDelete()2694 CFDE_TxtEdtDoRecord_FieldDelete::~CFDE_TxtEdtDoRecord_FieldDelete() {}
Release()2695 void CFDE_TxtEdtDoRecord_FieldDelete::Release() {
2696   delete this;
2697 }
Undo()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 }
Redo()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 }
Serialize(CFX_ByteString & bsDoRecord) const2724 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 }
Deserialize(const CFX_ByteStringC & bsDoRecord)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 }
CFDE_TxtEdtDoRecord_FieldReplace(const CFX_ByteStringC & bsDoRecord)2764 CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace(
2765     const CFX_ByteStringC& bsDoRecord) {
2766   Deserialize(bsDoRecord);
2767 }
CFDE_TxtEdtDoRecord_FieldReplace(CFDE_TxtEdtEngine * pEngine,int32_t nCaret,int32_t nNewCaret,CFDE_TxtEdtField * pField,int32_t nIndexInField,int32_t nFieldBgn,int32_t nFieldNewLength,const CFX_WideString & wsDel,const CFX_WideString & wsIns,FX_BOOL bSel)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 }
~CFDE_TxtEdtDoRecord_FieldReplace()2792 CFDE_TxtEdtDoRecord_FieldReplace::~CFDE_TxtEdtDoRecord_FieldReplace() {}
Release()2793 void CFDE_TxtEdtDoRecord_FieldReplace::Release() {
2794   delete this;
2795 }
Undo()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 }
Redo()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 }
Serialize(CFX_ByteString & bsDoRecord) const2824 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 }
Deserialize(const CFX_ByteStringC & bsDoRecord)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