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/fwl/src/core/include/fwl_threadimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
16 #include "xfa/src/fwl/src/basewidget/include/fwl_caretimp.h"
17 #include "xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h"
18 #include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h"
19 #include "xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h"
20 
21 // static
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)22 IFWL_Edit* IFWL_Edit::Create(const CFWL_WidgetImpProperties& properties,
23                              IFWL_Widget* pOuter) {
24   IFWL_Edit* pEdit = new IFWL_Edit;
25   CFWL_EditImp* pEditImpl = new CFWL_EditImp(properties, pOuter);
26   pEdit->SetImpl(pEditImpl);
27   pEditImpl->SetInterface(pEdit);
28   return pEdit;
29 }
30 // static
CreateComboEdit(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)31 IFWL_Edit* IFWL_Edit::CreateComboEdit(
32     const CFWL_WidgetImpProperties& properties,
33     IFWL_Widget* pOuter) {
34   IFWL_Edit* pEdit = new IFWL_Edit;
35   CFWL_EditImp* pComboEditImpl = new CFWL_ComboEditImp(properties, pOuter);
36   pEdit->SetImpl(pComboEditImpl);
37   pComboEditImpl->SetInterface(pEdit);
38   return pEdit;
39 }
IFWL_Edit()40 IFWL_Edit::IFWL_Edit() {}
SetText(const CFX_WideString & wsText)41 FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) {
42   return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText);
43 }
GetTextLength() const44 int32_t IFWL_Edit::GetTextLength() const {
45   return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength();
46 }
GetText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const47 FWL_ERR IFWL_Edit::GetText(CFX_WideString& wsText,
48                            int32_t nStart,
49                            int32_t nCount) const {
50   return static_cast<CFWL_EditImp*>(GetImpl())->GetText(wsText, nStart, nCount);
51 }
ClearText()52 FWL_ERR IFWL_Edit::ClearText() {
53   return static_cast<CFWL_EditImp*>(GetImpl())->ClearText();
54 }
GetCaretPos() const55 int32_t IFWL_Edit::GetCaretPos() const {
56   return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos();
57 }
SetCaretPos(int32_t nIndex,FX_BOOL bBefore)58 int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
59   return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore);
60 }
AddSelRange(int32_t nStart,int32_t nCount)61 FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) {
62   return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount);
63 }
CountSelRanges()64 int32_t IFWL_Edit::CountSelRanges() {
65   return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges();
66 }
GetSelRange(int32_t nIndex,int32_t & nStart)67 int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) {
68   return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart);
69 }
ClearSelections()70 FWL_ERR IFWL_Edit::ClearSelections() {
71   return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections();
72 }
GetLimit()73 int32_t IFWL_Edit::GetLimit() {
74   return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit();
75 }
SetLimit(int32_t nLimit)76 FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) {
77   return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit);
78 }
SetAliasChar(FX_WCHAR wAlias)79 FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) {
80   return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias);
81 }
SetFormatString(const CFX_WideString & wsFormat)82 FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString& wsFormat) {
83   return static_cast<CFWL_EditImp*>(GetImpl())->SetFormatString(wsFormat);
84 }
Insert(int32_t nStart,const FX_WCHAR * lpText,int32_t nLen)85 FWL_ERR IFWL_Edit::Insert(int32_t nStart,
86                           const FX_WCHAR* lpText,
87                           int32_t nLen) {
88   return static_cast<CFWL_EditImp*>(GetImpl())->Insert(nStart, lpText, nLen);
89 }
DeleteSelections()90 FWL_ERR IFWL_Edit::DeleteSelections() {
91   return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections();
92 }
DeleteRange(int32_t nStart,int32_t nCount)93 FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) {
94   return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount);
95 }
ReplaceSelections(const CFX_WideStringC & wsReplace)96 FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) {
97   return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace);
98 }
Replace(int32_t nStart,int32_t nLen,const CFX_WideStringC & wsReplace)99 FWL_ERR IFWL_Edit::Replace(int32_t nStart,
100                            int32_t nLen,
101                            const CFX_WideStringC& wsReplace) {
102   return static_cast<CFWL_EditImp*>(GetImpl())
103       ->Replace(nStart, nLen, wsReplace);
104 }
DoClipboard(int32_t iCmd)105 FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) {
106   return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd);
107 }
Copy(CFX_WideString & wsCopy)108 FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) {
109   return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy);
110 }
Cut(CFX_WideString & wsCut)111 FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) {
112   return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut);
113 }
Paste(const CFX_WideString & wsPaste)114 FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) {
115   return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste);
116 }
Delete()117 FX_BOOL IFWL_Edit::Delete() {
118   return static_cast<CFWL_EditImp*>(GetImpl())->Delete();
119 }
Redo(const CFX_ByteStringC & bsRecord)120 FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) {
121   return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord);
122 }
Undo(const CFX_ByteStringC & bsRecord)123 FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) {
124   return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord);
125 }
Undo()126 FX_BOOL IFWL_Edit::Undo() {
127   return static_cast<CFWL_EditImp*>(GetImpl())->Undo();
128 }
Redo()129 FX_BOOL IFWL_Edit::Redo() {
130   return static_cast<CFWL_EditImp*>(GetImpl())->Redo();
131 }
CanUndo()132 FX_BOOL IFWL_Edit::CanUndo() {
133   return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo();
134 }
CanRedo()135 FX_BOOL IFWL_Edit::CanRedo() {
136   return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo();
137 }
SetTabWidth(FX_FLOAT fTabWidth,FX_BOOL bEquidistant)138 FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
139   return static_cast<CFWL_EditImp*>(GetImpl())
140       ->SetTabWidth(fTabWidth, bEquidistant);
141 }
SetOuter(IFWL_Widget * pOuter)142 FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) {
143   return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter);
144 }
SetNumberRange(int32_t iMin,int32_t iMax)145 FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) {
146   return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax);
147 }
SetBackColor(FX_DWORD dwColor)148 FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) {
149   return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor);
150 }
SetFont(const CFX_WideString & wsFont,FX_FLOAT fSize)151 FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
152   return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize);
153 }
SetScrollOffset(FX_FLOAT fScrollOffset)154 void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) {
155   return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset);
156 }
GetSuggestWords(CFX_PointF pointf,CFX_ByteStringArray & sSuggest)157 FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf,
158                                    CFX_ByteStringArray& sSuggest) {
159   return static_cast<CFWL_EditImp*>(GetImpl())
160       ->GetSuggestWords(pointf, sSuggest);
161 }
ReplaceSpellCheckWord(CFX_PointF pointf,const CFX_ByteStringC & bsReplace)162 FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf,
163                                          const CFX_ByteStringC& bsReplace) {
164   return static_cast<CFWL_EditImp*>(GetImpl())
165       ->ReplaceSpellCheckWord(pointf, bsReplace);
166 }
167 #define FWL_EDIT_Margin 3
CFWL_EditImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)168 CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties& properties,
169                            IFWL_Widget* pOuter)
170     : CFWL_WidgetImp(properties, pOuter),
171       m_fVAlignOffset(0.0f),
172       m_fScrollOffsetX(0.0f),
173       m_fScrollOffsetY(0.0f),
174       m_pEdtEngine(NULL),
175       m_bLButtonDown(FALSE),
176       m_nSelStart(0),
177       m_nLimit(-1),
178       m_fSpaceAbove(0),
179       m_fSpaceBelow(0),
180       m_fFontSize(0),
181       m_bSetRange(FALSE),
182       m_iMin(-1),
183       m_iMax(0xFFFFFFF),
184       m_backColor(0),
185       m_updateBackColor(FALSE),
186       m_iCurRecord(-1),
187       m_iMaxRecord(128) {
188   m_rtClient.Reset();
189   m_rtEngine.Reset();
190   m_rtStatic.Reset();
191 }
~CFWL_EditImp()192 CFWL_EditImp::~CFWL_EditImp() {
193   if (m_pEdtEngine) {
194     m_pEdtEngine->Release();
195     m_pEdtEngine = NULL;
196   }
197   ClearRecord();
198 }
GetClassName(CFX_WideString & wsClass) const199 FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const {
200   wsClass = FWL_CLASS_Edit;
201   return FWL_ERR_Succeeded;
202 }
GetClassID() const203 FX_DWORD CFWL_EditImp::GetClassID() const {
204   return FWL_CLASSHASH_Edit;
205 }
Initialize()206 FWL_ERR CFWL_EditImp::Initialize() {
207   if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
208     return FWL_ERR_Indefinite;
209   if (!m_pDelegate) {
210     m_pDelegate = new CFWL_EditImpDelegate(this);
211   }
212   InitCaret();
213   if (!m_pEdtEngine) {
214     InitEngine();
215   }
216   return FWL_ERR_Succeeded;
217 }
Finalize()218 FWL_ERR CFWL_EditImp::Finalize() {
219   if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
220     ShowCaret(FALSE);
221   }
222   if (m_pHorzScrollBar) {
223     m_pHorzScrollBar->Finalize();
224   }
225   if (m_pVertScrollBar) {
226     m_pVertScrollBar->Finalize();
227   }
228   delete m_pDelegate;
229   m_pDelegate = nullptr;
230   return CFWL_WidgetImp::Finalize();
231 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)232 FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
233   if (bAutoSize) {
234     rect.Set(0, 0, 0, 0);
235     if (m_pEdtEngine) {
236       int32_t iTextLen = m_pEdtEngine->GetTextLength();
237       if (iTextLen > 0) {
238         CFX_WideString wsText;
239         m_pEdtEngine->GetText(wsText, 0);
240         CFX_SizeF sz = CalcTextSize(
241             wsText, m_pProperties->m_pThemeProvider,
242             m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
243         rect.Set(0, 0, sz.x, sz.y);
244       }
245     }
246     CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
247   } else {
248     rect = m_pProperties->m_rtWidget;
249     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
250       if (IsShowScrollBar(TRUE)) {
251         FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
252             GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
253         rect.width += *pfWidth;
254         rect.width += FWL_EDIT_Margin;
255       }
256       if (IsShowScrollBar(FALSE)) {
257         FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
258             GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
259         rect.height += *pfWidth;
260         rect.height += FWL_EDIT_Margin;
261       }
262     }
263   }
264   return FWL_ERR_Succeeded;
265 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)266 FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
267   if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) ||
268       (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
269     ShowCaret(FALSE);
270   }
271   return CFWL_WidgetImp::SetStates(dwStates, bSet);
272 }
SetWidgetRect(const CFX_RectF & rect)273 FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) {
274   return CFWL_WidgetImp::SetWidgetRect(rect);
275 }
Update()276 FWL_ERR CFWL_EditImp::Update() {
277   if (IsLocked()) {
278     return FWL_ERR_Indefinite;
279   }
280   if (!m_pProperties->m_pThemeProvider) {
281     m_pProperties->m_pThemeProvider = GetAvailableTheme();
282   }
283   Layout();
284   if (m_rtClient.IsEmpty()) {
285     return FWL_ERR_Indefinite;
286   }
287   UpdateEditEngine();
288   UpdateVAlignment();
289   UpdateScroll();
290   InitCaret();
291   return FWL_ERR_Succeeded;
292 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)293 FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
294   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
295     if (IsShowScrollBar(TRUE)) {
296       CFX_RectF rect;
297       m_pVertScrollBar->GetWidgetRect(rect);
298       if (rect.Contains(fx, fy)) {
299         return FWL_WGTHITTEST_VScrollBar;
300       }
301     }
302     if (IsShowScrollBar(FALSE)) {
303       CFX_RectF rect;
304       m_pHorzScrollBar->GetWidgetRect(rect);
305       if (rect.Contains(fx, fy)) {
306         return FWL_WGTHITTEST_HScrollBar;
307       }
308     }
309   }
310   if (m_rtClient.Contains(fx, fy)) {
311     return FWL_WGTHITTEST_Edit;
312   }
313   return FWL_WGTHITTEST_Unknown;
314 }
315 #define FX_EDIT_ISLATINWORD(u)                                     \
316   (u == 0x2D || (u <= 0x005A && u >= 0x0041) ||                    \
317    (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || \
318    u == 0x0027)
AddSquigglyPath(CFX_Path & PathData,FX_FLOAT fStartX,FX_FLOAT fEndX,FX_FLOAT fY,FX_FLOAT fStep)319 static void AddSquigglyPath(CFX_Path& PathData,
320                             FX_FLOAT fStartX,
321                             FX_FLOAT fEndX,
322                             FX_FLOAT fY,
323                             FX_FLOAT fStep) {
324   PathData.MoveTo(fStartX, fY);
325   FX_FLOAT fx;
326   int32_t i;
327   for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
328     PathData.LineTo(fx, fY + (i & 1) * fStep);
329   }
330 }
AddSpellCheckObj(CFX_Path & PathData,int32_t nStart,int32_t nCount,FX_FLOAT fOffSetX,FX_FLOAT fOffSetY)331 void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData,
332                                     int32_t nStart,
333                                     int32_t nCount,
334                                     FX_FLOAT fOffSetX,
335                                     FX_FLOAT fOffSetY) {
336   FX_FLOAT fStartX = 0.0f;
337   FX_FLOAT fEndX = 0.0f;
338   FX_FLOAT fY = 0.0f;
339   FX_FLOAT fStep = 0.0f;
340   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
341   CFX_RectFArray rectArray;
342   CFX_RectF rectText;
343   const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();
344   FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() *
345                     txtEdtParams->fFontSize / 1000;
346   pPage->CalcRangeRectArray(nStart, nCount, rectArray);
347   for (int i = 0; i < rectArray.GetSize(); i++) {
348     rectText = rectArray.GetAt(i);
349     fY = rectText.top + fAsent + fOffSetY;
350     fStep = txtEdtParams->fFontSize / 16.0f;
351     fStartX = rectText.left + fOffSetX;
352     fEndX = fStartX + rectText.Width();
353     AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
354   }
355 }
GetWordAtPoint(CFX_PointF pointf,int32_t & nCount)356 int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) {
357   return 0;
358 }
GetSuggestWords(CFX_PointF pointf,CFX_ByteStringArray & sSuggest)359 FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf,
360                                       CFX_ByteStringArray& sSuggest) {
361   int32_t nWordCount = 0;
362   int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
363   if (nWordCount < 1) {
364     return FALSE;
365   }
366   CFX_WideString wsSpell;
367   GetText(wsSpell, nWordStart, nWordCount);
368   CFX_ByteString sLatinWord;
369   for (int i = 0; i < nWordCount; i++) {
370     if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
371       break;
372     }
373     sLatinWord += (FX_CHAR)wsSpell[i];
374   }
375   if (sLatinWord.IsEmpty()) {
376     return FALSE;
377   }
378   CFWL_EvtEdtCheckWord checkWordEvent;
379   checkWordEvent.m_pSrcTarget = m_pInterface;
380   checkWordEvent.bsWord = sLatinWord;
381   checkWordEvent.bCheckWord = TRUE;
382   DispatchEvent(&checkWordEvent);
383   if (checkWordEvent.bCheckWord) {
384     return FALSE;
385   }
386   CFWL_EvtEdtGetSuggestWords suggestWordsEvent;
387   suggestWordsEvent.m_pSrcTarget = m_pInterface;
388   suggestWordsEvent.bsWord = sLatinWord;
389   suggestWordsEvent.bsArraySuggestWords = sSuggest;
390   suggestWordsEvent.bSuggestWords = FALSE;
391   DispatchEvent(&checkWordEvent);
392   return suggestWordsEvent.bSuggestWords;
393 }
ReplaceSpellCheckWord(CFX_PointF pointf,const CFX_ByteStringC & bsReplace)394 FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf,
395                                             const CFX_ByteStringC& bsReplace) {
396   int32_t nWordCount = 0;
397   int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
398   if (nWordCount < 1) {
399     return FALSE;
400   }
401   CFX_WideString wsSpell;
402   GetText(wsSpell, nWordStart, nWordCount);
403   for (int i = 0; i < nWordCount; i++) {
404     if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
405       nWordCount = i;
406       break;
407     }
408   }
409   int32_t nDestLen = bsReplace.GetLength();
410   CFX_WideString wsDest;
411   FX_WCHAR* pBuffer = wsDest.GetBuffer(nDestLen);
412   for (int32_t i = 0; i < nDestLen; i++) {
413     pBuffer[i] = bsReplace[i];
414   }
415   wsDest.ReleaseBuffer(nDestLen);
416   Replace(nWordStart, nWordCount, wsDest);
417   return TRUE;
418 }
DrawSpellCheck(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)419 void CFWL_EditImp::DrawSpellCheck(CFX_Graphics* pGraphics,
420                                   const CFX_Matrix* pMatrix) {
421   pGraphics->SaveGraphState();
422   if (pMatrix) {
423     pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix));
424   }
425   FX_ARGB cr = 0xFFFF0000;
426   CFX_Color crLine(cr);
427   CFWL_EvtEdtCheckWord checkWordEvent;
428   checkWordEvent.m_pSrcTarget = m_pInterface;
429   CFX_ByteString sLatinWord;
430   CFX_Path pathSpell;
431   pathSpell.Create();
432   int32_t nStart = 0;
433   FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
434   FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
435   CFX_WideString wsSpell;
436   this->GetText(wsSpell);
437   int32_t nContentLen = wsSpell.GetLength();
438   for (int i = 0; i < nContentLen; i++) {
439     if (FX_EDIT_ISLATINWORD(wsSpell[i])) {
440       if (sLatinWord.IsEmpty()) {
441         nStart = i;
442       }
443       sLatinWord += (FX_CHAR)wsSpell[i];
444     } else {
445       checkWordEvent.bsWord = sLatinWord;
446       checkWordEvent.bCheckWord = TRUE;
447       DispatchEvent(&checkWordEvent);
448       if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
449         AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
450                          fOffSetY);
451       }
452       sLatinWord.Empty();
453     }
454   }
455   checkWordEvent.bsWord = sLatinWord;
456   checkWordEvent.bCheckWord = TRUE;
457   DispatchEvent(&checkWordEvent);
458   if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
459     AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
460                      fOffSetY);
461   }
462   if (!pathSpell.IsEmpty()) {
463     CFX_RectF rtClip = m_rtEngine;
464     CFX_Matrix mt;
465     mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
466     if (pMatrix) {
467       pMatrix->TransformRect(rtClip);
468       mt.Concat(*pMatrix);
469     }
470     pGraphics->SetClipRect(rtClip);
471     pGraphics->SetStrokeColor(&crLine);
472     pGraphics->SetLineWidth(0);
473     pGraphics->StrokePath(&pathSpell, NULL);
474   }
475   pGraphics->RestoreGraphState();
476 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)477 FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics* pGraphics,
478                                  const CFX_Matrix* pMatrix) {
479   if (!pGraphics)
480     return FWL_ERR_Indefinite;
481   if (!m_pProperties->m_pThemeProvider)
482     return FWL_ERR_Indefinite;
483   if (m_rtClient.IsEmpty()) {
484     return FWL_ERR_Indefinite;
485   }
486   IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
487   if (!m_pWidgetMgr->IsFormDisabled()) {
488     DrawTextBk(pGraphics, pTheme, pMatrix);
489   }
490   if (m_pEdtEngine) {
491     DrawContent(pGraphics, pTheme, pMatrix);
492   }
493   if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) &&
494       !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) {
495     DrawSpellCheck(pGraphics, pMatrix);
496   }
497   if (HasBorder()) {
498     DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix);
499   }
500   if (HasEdge()) {
501     DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix);
502   }
503   return FWL_ERR_Succeeded;
504 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)505 FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
506   if (!pThemeProvider)
507     return FWL_ERR_Indefinite;
508   if (m_pHorzScrollBar) {
509     m_pHorzScrollBar->SetThemeProvider(pThemeProvider);
510   }
511   if (m_pVertScrollBar) {
512     m_pVertScrollBar->SetThemeProvider(pThemeProvider);
513   }
514   if (m_pCaret) {
515     m_pCaret->SetThemeProvider(pThemeProvider);
516   }
517   m_pProperties->m_pThemeProvider = pThemeProvider;
518   return FWL_ERR_Succeeded;
519 }
SetText(const CFX_WideString & wsText)520 FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) {
521   m_pEdtEngine->SetText(wsText);
522   return FWL_ERR_Succeeded;
523 }
GetTextLength() const524 int32_t CFWL_EditImp::GetTextLength() const {
525   if (!m_pEdtEngine)
526     return -1;
527   return m_pEdtEngine->GetTextLength();
528 }
GetText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const529 FWL_ERR CFWL_EditImp::GetText(CFX_WideString& wsText,
530                               int32_t nStart,
531                               int32_t nCount) const {
532   if (!m_pEdtEngine)
533     return FWL_ERR_Succeeded;
534   m_pEdtEngine->GetText(wsText, nStart, nCount);
535   return FWL_ERR_Succeeded;
536 }
ClearText()537 FWL_ERR CFWL_EditImp::ClearText() {
538   if (!m_pEdtEngine)
539     return FWL_ERR_Succeeded;
540   m_pEdtEngine->ClearText();
541   return FWL_ERR_Succeeded;
542 }
GetCaretPos() const543 int32_t CFWL_EditImp::GetCaretPos() const {
544   if (!m_pEdtEngine)
545     return -1;
546   return m_pEdtEngine->GetCaretPos();
547 }
SetCaretPos(int32_t nIndex,FX_BOOL bBefore)548 int32_t CFWL_EditImp::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
549   if (!m_pEdtEngine)
550     return -1;
551   return m_pEdtEngine->SetCaretPos(nIndex, bBefore);
552 }
AddSelRange(int32_t nStart,int32_t nCount)553 FWL_ERR CFWL_EditImp::AddSelRange(int32_t nStart, int32_t nCount) {
554   if (!m_pEdtEngine)
555     return FWL_ERR_Succeeded;
556   m_pEdtEngine->AddSelRange(nStart, nCount);
557   return FWL_ERR_Succeeded;
558 }
CountSelRanges()559 int32_t CFWL_EditImp::CountSelRanges() {
560   if (!m_pEdtEngine)
561     return 0;
562   return m_pEdtEngine->CountSelRanges();
563   return FWL_ERR_Succeeded;
564 }
GetSelRange(int32_t nIndex,int32_t & nStart)565 int32_t CFWL_EditImp::GetSelRange(int32_t nIndex, int32_t& nStart) {
566   if (!m_pEdtEngine)
567     return -1;
568   return m_pEdtEngine->GetSelRange(nIndex, nStart);
569 }
ClearSelections()570 FWL_ERR CFWL_EditImp::ClearSelections() {
571   if (!m_pEdtEngine)
572     return FWL_ERR_Succeeded;
573   m_pEdtEngine->ClearSelection();
574   return FWL_ERR_Succeeded;
575 }
GetLimit()576 int32_t CFWL_EditImp::GetLimit() {
577   return m_nLimit;
578 }
SetLimit(int32_t nLimit)579 FWL_ERR CFWL_EditImp::SetLimit(int32_t nLimit) {
580   m_nLimit = nLimit;
581   if (!m_pEdtEngine)
582     return FWL_ERR_Succeeded;
583   m_pEdtEngine->SetLimit(nLimit);
584   return FWL_ERR_Succeeded;
585 }
SetAliasChar(FX_WCHAR wAlias)586 FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias) {
587   if (!m_pEdtEngine)
588     return FWL_ERR_Indefinite;
589   m_pEdtEngine->SetAliasChar(wAlias);
590   return FWL_ERR_Succeeded;
591 }
SetFormatString(const CFX_WideString & wsFormat)592 FWL_ERR CFWL_EditImp::SetFormatString(const CFX_WideString& wsFormat) {
593   if (!m_pEdtEngine)
594     return FWL_ERR_Succeeded;
595   m_pEdtEngine->SetFormatBlock(0, wsFormat);
596   return FWL_ERR_Succeeded;
597 }
Insert(int32_t nStart,const FX_WCHAR * lpText,int32_t nLen)598 FWL_ERR CFWL_EditImp::Insert(int32_t nStart,
599                              const FX_WCHAR* lpText,
600                              int32_t nLen) {
601   if (!m_pEdtEngine)
602     return FWL_ERR_Succeeded;
603   if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
604       (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
605     return FWL_ERR_Indefinite;
606   }
607   m_pEdtEngine->Insert(nStart, lpText, nLen);
608   return FWL_ERR_Succeeded;
609 }
DeleteSelections()610 FWL_ERR CFWL_EditImp::DeleteSelections() {
611   if (!m_pEdtEngine)
612     return FWL_ERR_Succeeded;
613   int32_t iCount = m_pEdtEngine->CountSelRanges();
614   if (iCount > 0) {
615     m_pEdtEngine->Delete(-1);
616   }
617   return FWL_ERR_Succeeded;
618 }
DeleteRange(int32_t nStart,int32_t nCount)619 FWL_ERR CFWL_EditImp::DeleteRange(int32_t nStart, int32_t nCount) {
620   if (!m_pEdtEngine)
621     return FWL_ERR_Succeeded;
622   m_pEdtEngine->DeleteRange(nStart, nCount);
623   return FWL_ERR_Succeeded;
624 }
ReplaceSelections(const CFX_WideStringC & wsReplace)625 FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC& wsReplace) {
626   if (!m_pEdtEngine)
627     return FWL_ERR_Succeeded;
628   int32_t iCount = m_pEdtEngine->CountSelRanges();
629   for (int i = 0; i < iCount; i++) {
630     int32_t nStart;
631     int32_t nCount = m_pEdtEngine->GetSelRange(i, nStart);
632     m_pEdtEngine->Replace(nStart, nCount, wsReplace);
633   }
634   return FWL_ERR_Succeeded;
635 }
Replace(int32_t nStart,int32_t nLen,const CFX_WideStringC & wsReplace)636 FWL_ERR CFWL_EditImp::Replace(int32_t nStart,
637                               int32_t nLen,
638                               const CFX_WideStringC& wsReplace) {
639   if (!m_pEdtEngine)
640     return FWL_ERR_Succeeded;
641   m_pEdtEngine->Replace(nStart, nLen, wsReplace);
642   return FWL_ERR_Succeeded;
643 }
DoClipboard(int32_t iCmd)644 FWL_ERR CFWL_EditImp::DoClipboard(int32_t iCmd) {
645   if (!m_pEdtEngine)
646     return FWL_ERR_Succeeded;
647   if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
648       (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
649     return FWL_ERR_Succeeded;
650   }
651   IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
652   if (!pNative)
653     return FWL_ERR_Indefinite;
654   IFWL_AdapterClipboardMgr* pClipBorder = pNative->GetClipboardMgr();
655   if (!pClipBorder)
656     return FWL_ERR_Indefinite;
657   CFX_WideString wsText;
658   switch (iCmd) {
659     case 1: {
660       int32_t nStart;
661       int32_t nCount = m_pEdtEngine->GetSelRange(0, nStart);
662       if (nCount < 1) {
663         break;
664       }
665       m_pEdtEngine->GetText(wsText, nStart, nCount);
666       pClipBorder->SetStringData(wsText);
667       break;
668     }
669     case 2: {
670       int32_t nStart;
671       int32_t nCount = m_pEdtEngine->GetSelRange(0, nStart);
672       if (nCount < 1) {
673         break;
674       }
675       m_pEdtEngine->GetText(wsText, nStart, nCount);
676       m_pEdtEngine->DeleteRange(nStart, nCount);
677       m_pEdtEngine->ClearSelection();
678       pClipBorder->SetStringData(wsText);
679       break;
680     }
681     case 3: {
682       pClipBorder->GetStringData(wsText);
683       int32_t iLen = wsText.GetLength();
684       if (iLen < 0) {
685         break;
686       }
687       if (wsText[iLen] == L'\0') {
688         if (iLen == 1) {
689           break;
690         }
691         iLen--;
692         wsText = wsText.Left(iLen);
693       }
694       int32_t nPos = m_pEdtEngine->GetCaretPos();
695       m_pEdtEngine->Insert(nPos, wsText, iLen);
696       break;
697     }
698     default: {}
699   }
700   return FWL_ERR_Succeeded;
701 }
Copy(CFX_WideString & wsCopy)702 FX_BOOL CFWL_EditImp::Copy(CFX_WideString& wsCopy) {
703   if (!m_pEdtEngine)
704     return FALSE;
705   int32_t nCount = m_pEdtEngine->CountSelRanges();
706   if (nCount == 0) {
707     return FALSE;
708   }
709   wsCopy.Empty();
710   CFX_WideString wsTemp;
711   int32_t nStart, nLength;
712   for (int32_t i = 0; i < nCount; i++) {
713     nLength = m_pEdtEngine->GetSelRange(i, nStart);
714     m_pEdtEngine->GetText(wsTemp, nStart, nLength);
715     wsCopy += wsTemp;
716     wsTemp.Empty();
717   }
718   return TRUE;
719 }
Cut(CFX_WideString & wsCut)720 FX_BOOL CFWL_EditImp::Cut(CFX_WideString& wsCut) {
721   if (!m_pEdtEngine)
722     return FALSE;
723   int32_t nCount = m_pEdtEngine->CountSelRanges();
724   if (nCount == 0) {
725     return FALSE;
726   }
727   wsCut.Empty();
728   CFX_WideString wsTemp;
729   int32_t nStart, nLength;
730   for (int32_t i = 0; i < nCount; i++) {
731     nLength = m_pEdtEngine->GetSelRange(i, nStart);
732     m_pEdtEngine->GetText(wsTemp, nStart, nLength);
733     wsCut += wsTemp;
734     wsTemp.Empty();
735   }
736   m_pEdtEngine->Delete(0);
737   return TRUE;
738 }
Paste(const CFX_WideString & wsPaste)739 FX_BOOL CFWL_EditImp::Paste(const CFX_WideString& wsPaste) {
740   if (!m_pEdtEngine)
741     return FALSE;
742   int32_t nCaret = m_pEdtEngine->GetCaretPos();
743   int32_t iError =
744       m_pEdtEngine->Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength());
745   if (iError < 0) {
746     ProcessInsertError(iError);
747     return FALSE;
748   }
749   return TRUE;
750 }
Delete()751 FX_BOOL CFWL_EditImp::Delete() {
752   if (!m_pEdtEngine)
753     return FALSE;
754   int32_t nCount = m_pEdtEngine->CountSelRanges();
755   if (nCount < 1) {
756     return FALSE;
757   }
758   m_pEdtEngine->Delete(0);
759   return TRUE;
760 }
Redo(const CFX_ByteStringC & bsRecord)761 FX_BOOL CFWL_EditImp::Redo(const CFX_ByteStringC& bsRecord) {
762   if (!m_pEdtEngine)
763     return FALSE;
764   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
765     return TRUE;
766   }
767   return m_pEdtEngine->Redo(bsRecord);
768 }
Undo(const CFX_ByteStringC & bsRecord)769 FX_BOOL CFWL_EditImp::Undo(const CFX_ByteStringC& bsRecord) {
770   if (!m_pEdtEngine)
771     return FALSE;
772   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
773     return TRUE;
774   }
775   return m_pEdtEngine->Undo(bsRecord);
776 }
Undo()777 FX_BOOL CFWL_EditImp::Undo() {
778   if (!CanUndo()) {
779     return FALSE;
780   }
781   CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];
782   return Undo(bsRecord);
783 }
Redo()784 FX_BOOL CFWL_EditImp::Redo() {
785   if (!CanRedo()) {
786     return FALSE;
787   }
788   CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];
789   return Redo(bsRecord);
790 }
CanUndo()791 FX_BOOL CFWL_EditImp::CanUndo() {
792   return m_iCurRecord >= 0;
793 }
CanRedo()794 FX_BOOL CFWL_EditImp::CanRedo() {
795   return m_iCurRecord < m_RecordArr.GetSize() - 1;
796 }
SetTabWidth(FX_FLOAT fTabWidth,FX_BOOL bEquidistant)797 FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
798   if (!m_pEdtEngine)
799     return FWL_ERR_Succeeded;
800   FDE_LPTXTEDTPARAMS pParams =
801       (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams();
802   pParams->fTabWidth = fTabWidth;
803   pParams->bTabEquidistant = bEquidistant;
804   return FWL_ERR_Succeeded;
805 }
SetOuter(IFWL_Widget * pOuter)806 FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) {
807   m_pOuter = pOuter;
808   return FWL_ERR_Succeeded;
809 }
SetNumberRange(int32_t iMin,int32_t iMax)810 FWL_ERR CFWL_EditImp::SetNumberRange(int32_t iMin, int32_t iMax) {
811   m_iMin = iMin;
812   m_iMax = iMax;
813   m_bSetRange = TRUE;
814   return FWL_ERR_Succeeded;
815 }
On_CaretChanged(IFDE_TxtEdtEngine * pEdit,int32_t nPage,FX_BOOL bVisible)816 void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine* pEdit,
817                                    int32_t nPage,
818                                    FX_BOOL bVisible) {
819   if (m_rtEngine.IsEmpty()) {
820     return;
821   }
822   if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
823     return;
824   }
825   FX_BOOL bRepaintContent = UpdateOffset();
826   UpdateCaret();
827   CFX_RectF rtInvalid;
828   rtInvalid.Set(0, 0, 0, 0);
829   FX_BOOL bRepaintScroll = FALSE;
830   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
831     IFWL_ScrollBar* pScroll = UpdateScroll();
832     if (pScroll) {
833       pScroll->GetWidgetRect(rtInvalid);
834       bRepaintScroll = TRUE;
835     }
836   }
837   if (bRepaintContent || bRepaintScroll) {
838     if (bRepaintContent) {
839       rtInvalid.Union(m_rtEngine);
840     }
841     Repaint(&rtInvalid);
842   }
843 }
On_TextChanged(IFDE_TxtEdtEngine * pEdit,FDE_TXTEDT_TEXTCHANGE_INFO & ChangeInfo)844 void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine* pEdit,
845                                   FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) {
846   FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes;
847   if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) {
848     UpdateVAlignment();
849   }
850   IFDE_TxtEdtPage* page = m_pEdtEngine->GetPage(0);
851   FX_FLOAT fContentWidth = page->GetContentsBox().width;
852   FX_FLOAT fContentHeight = page->GetContentsBox().height;
853   CFX_RectF rtTemp;
854   GetClientRect(rtTemp);
855   FX_BOOL bHSelfAdaption =
856       m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;
857   FX_BOOL bVSelfAdaption =
858       m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;
859   FX_BOOL bNeedUpdate = FALSE;
860   if (bHSelfAdaption || bVSelfAdaption) {
861     CFWL_EvtEdtPreSelfAdaption evt;
862     evt.m_pSrcTarget = m_pInterface;
863     evt.bHSelfAdaption = TRUE;
864     evt.bVSelfAdaption = TRUE;
865     FX_FLOAT fWidth;
866     FX_FLOAT fHight;
867     fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;
868     fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;
869     evt.rtAfterChange.Set(0, 0, fWidth, fHight);
870     DispatchEvent(&evt);
871     if (!evt.bHSelfAdaption) {
872       ModifyStylesEx(
873           0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);
874     }
875     if (!evt.bVSelfAdaption) {
876       ModifyStylesEx(
877           0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);
878     }
879     bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) ||
880                   (bVSelfAdaption && !evt.bVSelfAdaption);
881   }
882   FX_FLOAT fContentWidth1 = fContentWidth;
883   FX_FLOAT fContentHeight1 = fContentHeight;
884   if (bNeedUpdate) {
885     UpdateEditParams();
886     UpdateEditLayout();
887     IFDE_TxtEdtPage* page1 = m_pEdtEngine->GetPage(0);
888     fContentWidth1 = page1->GetContentsBox().width;
889     fContentHeight1 = page1->GetContentsBox().height;
890   }
891   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {
892     rtTemp.width = std::max(m_pProperties->m_rtWidget.width, fContentWidth1);
893     m_pProperties->m_rtWidget.width = fContentWidth1;
894   }
895   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {
896     rtTemp.height = std::max(m_pProperties->m_rtWidget.height, fContentHeight1);
897     m_pProperties->m_rtWidget.height = fContentHeight1;
898   }
899   CFWL_EvtEdtTextChanged event;
900   event.m_pSrcTarget = m_pInterface;
901   event.nChangeType = ChangeInfo.nChangeType;
902   event.wsInsert = ChangeInfo.wsInsert;
903   event.wsDelete = ChangeInfo.wsDelete;
904   event.wsPrevText = ChangeInfo.wsPrevText;
905   DispatchEvent(&event);
906   LayoutScrollBar();
907   Repaint(&rtTemp);
908 }
On_SelChanged(IFDE_TxtEdtEngine * pEdit)909 void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) {
910   CFX_RectF rtTemp;
911   GetClientRect(rtTemp);
912   Repaint(&rtTemp);
913 }
On_PageLoad(IFDE_TxtEdtEngine * pEdit,int32_t nPageIndex,int32_t nPurpose)914 FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine* pEdit,
915                                   int32_t nPageIndex,
916                                   int32_t nPurpose) {
917   IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
918   IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
919   if (!pPage)
920     return FALSE;
921   pPage->LoadPage();
922   return TRUE;
923 }
On_PageUnload(IFDE_TxtEdtEngine * pEdit,int32_t nPageIndex,int32_t nPurpose)924 FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine* pEdit,
925                                     int32_t nPageIndex,
926                                     int32_t nPurpose) {
927   IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
928   IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
929   if (!pPage)
930     return FALSE;
931   pPage->UnloadPage();
932   return TRUE;
933 }
On_AddDoRecord(IFDE_TxtEdtEngine * pEdit,const CFX_ByteStringC & bsDoRecord)934 void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine* pEdit,
935                                   const CFX_ByteStringC& bsDoRecord) {
936   AddDoRecord(bsDoRecord);
937   CFWL_WidgetImp* pSrcTarget = GetRootOuter();
938   if (!pSrcTarget) {
939     pSrcTarget = this;
940   }
941   CFWL_EvtEdtAddDoRecord evt;
942   evt.m_pSrcTarget = m_pInterface;
943   evt.m_wsDoRecord = bsDoRecord;
944   m_pDelegate->OnProcessEvent(&evt);
945 }
On_ValidateField(IFDE_TxtEdtEngine * pEdit,int32_t nBlockIndex,int32_t nFieldIndex,const CFX_WideString & wsFieldText,int32_t nCharIndex)946 FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine* pEdit,
947                                        int32_t nBlockIndex,
948                                        int32_t nFieldIndex,
949                                        const CFX_WideString& wsFieldText,
950                                        int32_t nCharIndex) {
951   return TRUE;
952 }
On_ValidateBlock(IFDE_TxtEdtEngine * pEdit,int32_t nBlockIndex)953 FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit,
954                                        int32_t nBlockIndex) {
955   return TRUE;
956 }
On_GetBlockFormatText(IFDE_TxtEdtEngine * pEdit,int32_t nBlockIndex,CFX_WideString & wsBlockText)957 FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit,
958                                             int32_t nBlockIndex,
959                                             CFX_WideString& wsBlockText) {
960   return FALSE;
961 }
On_Validate(IFDE_TxtEdtEngine * pEdit,CFX_WideString & wsText)962 FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine* pEdit,
963                                   CFX_WideString& wsText) {
964   IFWL_Widget* pDst = GetOuter();
965   if (!pDst) {
966     pDst = m_pInterface;
967   }
968   CFWL_EvtEdtValidate event;
969   event.pDstWidget = pDst;
970   event.m_pSrcTarget = m_pInterface;
971   event.wsInsert = wsText;
972   event.bValidate = TRUE;
973   DispatchEvent(&event);
974   return event.bValidate;
975 }
SetBackgroundColor(FX_DWORD color)976 FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) {
977   m_backColor = color;
978   m_updateBackColor = TRUE;
979   return FWL_ERR_Succeeded;
980 }
SetFont(const CFX_WideString & wsFont,FX_FLOAT fSize)981 FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
982   m_wsFont = wsFont;
983   m_fFontSize = fSize;
984   return FWL_ERR_Succeeded;
985 }
SetScrollOffset(FX_FLOAT fScrollOffset)986 void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) {
987   m_fScrollOffsetY = fScrollOffset;
988 }
DrawTextBk(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)989 void CFWL_EditImp::DrawTextBk(CFX_Graphics* pGraphics,
990                               IFWL_ThemeProvider* pTheme,
991                               const CFX_Matrix* pMatrix) {
992   CFWL_ThemeBackground param;
993   param.m_pWidget = m_pInterface;
994   param.m_iPart = FWL_PART_EDT_Background;
995   param.m_dwData = FWL_PARTDATA_EDT_Background;
996   param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly
997                          ? FWL_PARTSTATE_EDT_ReadOnly
998                          : FWL_PARTSTATE_EDT_Normal;
999   FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled);
1000   if (dwStates) {
1001     param.m_dwStates = FWL_PARTSTATE_EDT_Disable;
1002   }
1003   param.m_pGraphics = pGraphics;
1004   param.m_matrix = *pMatrix;
1005   param.m_rtPart = m_rtClient;
1006   pTheme->DrawBackground(&param);
1007   if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) {
1008     return;
1009   }
1010   CFX_RectF rtScorll;
1011   m_pHorzScrollBar->GetWidgetRect(rtScorll);
1012   CFX_RectF rtStatic;
1013   rtStatic.Set(m_rtClient.right() - rtScorll.height,
1014                m_rtClient.bottom() - rtScorll.height, rtScorll.height,
1015                rtScorll.height);
1016   param.m_dwData = FWL_PARTDATA_EDT_StaticBackground;
1017   param.m_rtPart = rtStatic;
1018   pTheme->DrawBackground(&param);
1019 }
DrawContent(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)1020 void CFWL_EditImp::DrawContent(CFX_Graphics* pGraphics,
1021                                IFWL_ThemeProvider* pTheme,
1022                                const CFX_Matrix* pMatrix) {
1023   if (!m_pEdtEngine)
1024     return;
1025   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1026   if (!pPage)
1027     return;
1028   pGraphics->SaveGraphState();
1029   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
1030     pGraphics->SaveGraphState();
1031   }
1032   CFX_RectF rtClip = m_rtEngine;
1033   FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
1034   FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
1035   CFX_Matrix mt;
1036   mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
1037   if (pMatrix) {
1038     pMatrix->TransformRect(rtClip);
1039     mt.Concat(*pMatrix);
1040   }
1041   FX_BOOL bShowSel =
1042       (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) ||
1043       (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
1044   if (bShowSel) {
1045     IFWL_Widget* pForm =
1046         m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
1047     if (pForm) {
1048       bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) !=
1049                  FWL_WGTSTATE_Deactivated;
1050     }
1051   }
1052   int32_t nSelCount = m_pEdtEngine->CountSelRanges();
1053   if (bShowSel && nSelCount > 0) {
1054     int32_t nPageCharStart = pPage->GetCharStart();
1055     int32_t nPageCharCount = pPage->GetCharCount();
1056     int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1;
1057     int32_t nCharCount;
1058     int32_t nCharStart;
1059     CFX_RectFArray rectArr;
1060     int32_t i = 0;
1061     for (i = 0; i < nSelCount; i++) {
1062       nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart);
1063       int32_t nCharEnd = nCharStart + nCharCount - 1;
1064       if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) {
1065         continue;
1066       }
1067       int32_t nBgn = std::max(nCharStart, nPageCharStart);
1068       int32_t nEnd = std::min(nCharEnd, nPageCharEnd);
1069       pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1,
1070                                 rectArr);
1071     }
1072     int32_t nCount = rectArr.GetSize();
1073     CFX_Path path;
1074     path.Create();
1075     for (i = 0; i < nCount; i++) {
1076       rectArr[i].left += fOffSetX;
1077       rectArr[i].top += fOffSetY;
1078       path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width,
1079                         rectArr[i].height);
1080     }
1081     pGraphics->SetClipRect(rtClip);
1082     CFWL_ThemeBackground param;
1083     param.m_pGraphics = pGraphics;
1084     param.m_matrix = *pMatrix;
1085     param.m_pWidget = m_pInterface;
1086     param.m_iPart = FWL_PART_EDT_Background;
1087     param.m_pPath = &path;
1088     pTheme->DrawBackground(&param);
1089   }
1090   CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice();
1091   if (!pRenderDev)
1092     return;
1093   IFDE_RenderDevice* pRenderDevice = IFDE_RenderDevice::Create(pRenderDev);
1094   if (!pRenderDevice)
1095     return;
1096   IFDE_RenderContext* pRenderContext = IFDE_RenderContext::Create();
1097   if (!pRenderContext)
1098     return;
1099   pRenderDevice->SetClipRect(rtClip);
1100   pRenderContext->StartRender(pRenderDevice, pPage, mt);
1101   pRenderContext->DoRender(NULL);
1102   pRenderContext->Release();
1103   pRenderDevice->Release();
1104   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
1105     pGraphics->RestoreGraphState();
1106     CFX_Path path;
1107     path.Create();
1108     int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1;
1109     FX_FLOAT fStep = m_rtEngine.width / iLimit;
1110     FX_FLOAT fLeft = m_rtEngine.left + 1;
1111     for (int32_t i = 1; i < iLimit; i++) {
1112       fLeft += fStep;
1113       path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom());
1114     }
1115     CFWL_ThemeBackground param;
1116     param.m_pGraphics = pGraphics;
1117     param.m_matrix = *pMatrix;
1118     param.m_pWidget = m_pInterface;
1119     param.m_iPart = FWL_PART_EDT_CombTextLine;
1120     param.m_pPath = &path;
1121     pTheme->DrawBackground(&param);
1122   }
1123   pGraphics->RestoreGraphState();
1124 }
UpdateEditEngine()1125 void CFWL_EditImp::UpdateEditEngine() {
1126   UpdateEditParams();
1127   UpdateEditLayout();
1128   if (m_nLimit > -1) {
1129     m_pEdtEngine->SetLimit(m_nLimit);
1130   }
1131 }
UpdateEditParams()1132 void CFWL_EditImp::UpdateEditParams() {
1133   FDE_TXTEDTPARAMS params;
1134   params.nHorzScale = 100;
1135   params.fPlateWidth = m_rtEngine.width;
1136   params.fPlateHeight = m_rtEngine.height;
1137   if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) {
1138     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL;
1139   }
1140   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) {
1141     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical;
1142   }
1143   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) {
1144     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial;
1145   }
1146   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) {
1147     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve;
1148   }
1149   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) {
1150     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes;
1151   }
1152   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) {
1153     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab;
1154   }
1155   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
1156     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText;
1157   }
1158   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) {
1159     params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight;
1160   }
1161   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) {
1162     params.dwMode |= FDE_TEXTEDITMODE_Validate;
1163   }
1164   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) {
1165     params.dwMode |= FDE_TEXTEDITMODE_Password;
1166   }
1167   switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) {
1168     case FWL_STYLEEXT_EDT_HNear: {
1169       params.dwAlignment |= FDE_TEXTEDITALIGN_Left;
1170       break;
1171     }
1172     case FWL_STYLEEXT_EDT_HCenter: {
1173       params.dwAlignment |= FDE_TEXTEDITALIGN_Center;
1174       break;
1175     }
1176     case FWL_STYLEEXT_EDT_HFar: {
1177       params.dwAlignment |= FDE_TEXTEDITALIGN_Right;
1178       break;
1179     }
1180     default: {}
1181   }
1182   switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) {
1183     case FWL_STYLEEXT_EDT_Justified: {
1184       params.dwAlignment |= FDE_TEXTEDITALIGN_Justified;
1185       break;
1186     }
1187     case FWL_STYLEEXT_EDT_Distributed: {
1188       params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed;
1189       break;
1190     }
1191     default: { params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; }
1192   }
1193   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
1194     params.dwMode |= FDE_TEXTEDITMODE_MultiLines;
1195     if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 &&
1196         (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
1197       params.dwMode |=
1198           FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz;
1199     }
1200     if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 &&
1201         (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) {
1202       params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert;
1203     } else {
1204       params.fPlateHeight = 0x00FFFFFF;
1205     }
1206   } else {
1207     if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
1208       params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz;
1209     }
1210   }
1211   if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
1212       (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
1213     params.dwMode |= FDE_TEXTEDITMODE_ReadOnly;
1214   }
1215   FX_FLOAT* pFontSize =
1216       static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FontSize));
1217   if (!pFontSize)
1218     return;
1219   m_fFontSize = *pFontSize;
1220   FX_DWORD* pFontColor =
1221       static_cast<FX_DWORD*>(GetThemeCapacity(FWL_WGTCAPACITY_TextColor));
1222   if (!pFontColor)
1223     return;
1224   params.dwFontColor = *pFontColor;
1225   FX_FLOAT* pLineHeight =
1226       static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_LineHeight));
1227   if (!pLineHeight)
1228     return;
1229   params.fLineSpace = *pLineHeight;
1230   IFX_Font* pFont =
1231       static_cast<IFX_Font*>(GetThemeCapacity(FWL_WGTCAPACITY_Font));
1232   if (!pFont)
1233     return;
1234   params.pFont = pFont;
1235   params.fFontSize = m_fFontSize;
1236   params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace);
1237   if (params.nLineCount <= 0) {
1238     params.nLineCount = 1;
1239   }
1240   params.fTabWidth = params.fFontSize * 1;
1241   params.bTabEquidistant = TRUE;
1242   params.wLineBreakChar = L'\n';
1243   params.nCharRotation = 0;
1244   params.pEventSink = this;
1245   m_pEdtEngine->SetEditParams(params);
1246 }
UpdateEditLayout()1247 void CFWL_EditImp::UpdateEditLayout() {
1248   if (m_pEdtEngine->GetTextLength() <= 0) {
1249     m_pEdtEngine->SetTextByStream(NULL);
1250   }
1251   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1252   if (pPage) {
1253     pPage->UnloadPage();
1254     pPage = NULL;
1255   }
1256   m_pEdtEngine->StartLayout();
1257   m_pEdtEngine->DoLayout(NULL);
1258   m_pEdtEngine->EndLayout();
1259   pPage = m_pEdtEngine->GetPage(0);
1260   if (pPage) {
1261     pPage->LoadPage();
1262   }
1263 }
UpdateOffset()1264 FX_BOOL CFWL_EditImp::UpdateOffset() {
1265   CFX_RectF rtCaret;
1266   m_pEdtEngine->GetCaretRect(rtCaret);
1267   FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
1268   FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
1269   rtCaret.Offset(fOffSetX, fOffSetY);
1270   const CFX_RectF& rtEidt = m_rtEngine;
1271   if (rtEidt.Contains(rtCaret)) {
1272     IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1273     if (!pPage)
1274       return FALSE;
1275     CFX_RectF rtFDE = pPage->GetContentsBox();
1276     rtFDE.Offset(fOffSetX, fOffSetY);
1277     if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) {
1278       m_fScrollOffsetX += rtFDE.right() - rtEidt.right();
1279       if (m_fScrollOffsetX < 0) {
1280         m_fScrollOffsetX = 0;
1281       }
1282     }
1283     if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) {
1284       m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom();
1285       if (m_fScrollOffsetY < 0) {
1286         m_fScrollOffsetY = 0;
1287       }
1288     }
1289     return FALSE;
1290   } else {
1291     FX_FLOAT offsetX = 0.0;
1292     FX_FLOAT offsetY = 0.0;
1293     if (rtCaret.left < rtEidt.left) {
1294       offsetX = rtCaret.left - rtEidt.left;
1295     }
1296     if (rtCaret.right() > rtEidt.right()) {
1297       offsetX = rtCaret.right() - rtEidt.right();
1298     }
1299     if (rtCaret.top < rtEidt.top) {
1300       offsetY = rtCaret.top - rtEidt.top;
1301     }
1302     if (rtCaret.bottom() > rtEidt.bottom()) {
1303       offsetY = rtCaret.bottom() - rtEidt.bottom();
1304     }
1305     if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) {
1306       m_fScrollOffsetX += offsetX;
1307     }
1308     if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) {
1309       m_fScrollOffsetY += offsetY;
1310     }
1311     if (m_fFontSize > m_rtEngine.height) {
1312       m_fScrollOffsetY = 0;
1313     }
1314     return TRUE;
1315   }
1316 }
UpdateOffset(IFWL_ScrollBar * pScrollBar,FX_FLOAT fPosChanged)1317 FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar* pScrollBar,
1318                                    FX_FLOAT fPosChanged) {
1319   if (pScrollBar == m_pHorzScrollBar.get()) {
1320     m_fScrollOffsetX += fPosChanged;
1321   } else {
1322     m_fScrollOffsetY += fPosChanged;
1323   }
1324   return TRUE;
1325 }
UpdateVAlignment()1326 void CFWL_EditImp::UpdateVAlignment() {
1327   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1328   if (!pPage)
1329     return;
1330   const CFX_RectF& rtFDE = pPage->GetContentsBox();
1331   FX_FLOAT fOffsetY = 0.0f;
1332   FX_FLOAT fSpaceAbove = 0.0f;
1333   FX_FLOAT fSpaceBelow = 0.0f;
1334   CFX_SizeF* pSpace = static_cast<CFX_SizeF*>(
1335       GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow));
1336   if (pSpace) {
1337     fSpaceAbove = pSpace->x;
1338     fSpaceBelow = pSpace->y;
1339   }
1340   if (fSpaceAbove < 0.1f) {
1341     fSpaceAbove = 0;
1342   }
1343   if (fSpaceBelow < 0.1f) {
1344     fSpaceBelow = 0;
1345   }
1346   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) {
1347     fOffsetY = (m_rtEngine.height - rtFDE.height) / 2;
1348     if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 &&
1349         fSpaceAbove < fSpaceBelow) {
1350       return;
1351     }
1352     fOffsetY += (fSpaceAbove - fSpaceBelow) / 2;
1353   } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) {
1354     fOffsetY = (m_rtEngine.height - rtFDE.height);
1355     fOffsetY -= fSpaceBelow;
1356   } else {
1357     fOffsetY += fSpaceAbove;
1358   }
1359   m_fVAlignOffset = fOffsetY;
1360   if (m_fVAlignOffset < 0) {
1361     m_fVAlignOffset = 0;
1362   }
1363 }
UpdateCaret()1364 void CFWL_EditImp::UpdateCaret() {
1365   CFX_RectF rtFDE;
1366   m_pEdtEngine->GetCaretRect(rtFDE);
1367   rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX,
1368                m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset);
1369   CFX_RectF rtCaret;
1370   rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height);
1371   CFX_RectF temp = rtCaret;
1372   CFX_RectF rtClient;
1373   GetClientRect(rtClient);
1374   rtCaret.Intersect(rtClient);
1375   if (rtCaret.left > rtClient.right()) {
1376     FX_FLOAT right = rtCaret.right();
1377     rtCaret.left = rtClient.right() - 1;
1378     rtCaret.width = right - rtCaret.left;
1379   }
1380   FX_BOOL bIntersect = !rtCaret.IsEmpty();
1381   FX_BOOL bShow = TRUE;
1382   FX_BOOL bShowWhole = FALSE;
1383   if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {
1384     bShow = FALSE;
1385   }
1386   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption &&
1387       temp.right() > m_rtEngine.right()) {
1388     bShowWhole = TRUE;
1389   }
1390   if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption &&
1391       temp.bottom() > m_rtEngine.bottom()) {
1392     bShowWhole = TRUE;
1393   } else {
1394     bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);
1395   }
1396   if (bShowWhole) {
1397     rtCaret = temp;
1398   }
1399   ShowCaret(bShow, &rtCaret);
1400 }
UpdateScroll()1401 IFWL_ScrollBar* CFWL_EditImp::UpdateScroll() {
1402   FX_BOOL bShowHorz =
1403       m_pHorzScrollBar &&
1404       ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
1405   FX_BOOL bShowVert =
1406       m_pVertScrollBar &&
1407       ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
1408   if (!bShowHorz && !bShowVert) {
1409     return NULL;
1410   }
1411   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1412   if (!pPage)
1413     return NULL;
1414   const CFX_RectF& rtFDE = pPage->GetContentsBox();
1415   IFWL_ScrollBar* pRepaint = NULL;
1416   if (bShowHorz) {
1417     CFX_RectF rtScroll;
1418     m_pHorzScrollBar->GetWidgetRect(rtScroll);
1419     if (rtScroll.width < rtFDE.width) {
1420       m_pHorzScrollBar->LockUpdate();
1421       FX_FLOAT fRange = rtFDE.width - rtScroll.width;
1422       m_pHorzScrollBar->SetRange(0.0f, fRange);
1423       FX_FLOAT fPos = m_fScrollOffsetX;
1424       if (fPos < 0.0f) {
1425         fPos = 0.0f;
1426       }
1427       if (fPos > fRange) {
1428         fPos = fRange;
1429       }
1430       m_pHorzScrollBar->SetPos(fPos);
1431       m_pHorzScrollBar->SetTrackPos(fPos);
1432       m_pHorzScrollBar->SetPageSize(rtScroll.width);
1433       m_pHorzScrollBar->SetStepSize(rtScroll.width / 10);
1434       m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
1435       m_pHorzScrollBar->UnlockUpdate();
1436       m_pHorzScrollBar->Update();
1437       pRepaint = m_pHorzScrollBar.get();
1438     } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
1439       m_pHorzScrollBar->LockUpdate();
1440       m_pHorzScrollBar->SetRange(0, -1);
1441       m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
1442       m_pHorzScrollBar->UnlockUpdate();
1443       m_pHorzScrollBar->Update();
1444       pRepaint = m_pHorzScrollBar.get();
1445     }
1446   }
1447   if (bShowVert) {
1448     CFX_RectF rtScroll;
1449     m_pVertScrollBar->GetWidgetRect(rtScroll);
1450     if (rtScroll.height < rtFDE.height) {
1451       m_pVertScrollBar->LockUpdate();
1452       FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace;
1453       FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;
1454       if (fRange < fStep) {
1455         fRange = fStep;
1456       }
1457       m_pVertScrollBar->SetRange(0.0f, fRange);
1458       FX_FLOAT fPos = m_fScrollOffsetY;
1459       if (fPos < 0.0f) {
1460         fPos = 0.0f;
1461       }
1462       if (fPos > fRange) {
1463         fPos = fRange;
1464       }
1465       m_pVertScrollBar->SetPos(fPos);
1466       m_pVertScrollBar->SetTrackPos(fPos);
1467       m_pVertScrollBar->SetPageSize(rtScroll.height);
1468       m_pVertScrollBar->SetStepSize(fStep);
1469       m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
1470       m_pVertScrollBar->UnlockUpdate();
1471       m_pVertScrollBar->Update();
1472       pRepaint = m_pVertScrollBar.get();
1473     } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
1474       m_pVertScrollBar->LockUpdate();
1475       m_pVertScrollBar->SetRange(0, -1);
1476       m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
1477       m_pVertScrollBar->UnlockUpdate();
1478       m_pVertScrollBar->Update();
1479       pRepaint = m_pVertScrollBar.get();
1480     }
1481   }
1482   return pRepaint;
1483 }
IsShowScrollBar(FX_BOOL bVert)1484 FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert) {
1485   FX_BOOL bShow =
1486       (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus)
1487           ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) ==
1488                 FWL_WGTSTATE_Focused
1489           : TRUE;
1490   if (bVert) {
1491     return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) &&
1492            (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) &&
1493            IsContentHeightOverflow();
1494   }
1495   return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) &&
1496          (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
1497 }
IsContentHeightOverflow()1498 FX_BOOL CFWL_EditImp::IsContentHeightOverflow() {
1499   if (!m_pEdtEngine)
1500     return FALSE;
1501   IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
1502   if (!pPage)
1503     return FALSE;
1504   return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f;
1505 }
AddDoRecord(const CFX_ByteStringC & bsDoRecord)1506 int32_t CFWL_EditImp::AddDoRecord(const CFX_ByteStringC& bsDoRecord) {
1507   int32_t nCount = m_RecordArr.GetSize();
1508   if (m_iCurRecord == nCount - 1) {
1509     if (nCount == m_iMaxRecord) {
1510       m_RecordArr.RemoveAt(0);
1511       m_iCurRecord--;
1512     }
1513   } else {
1514     for (int32_t i = nCount - 1; i > m_iCurRecord; i--) {
1515       m_RecordArr.RemoveAt(i);
1516     }
1517   }
1518   m_RecordArr.Add(bsDoRecord);
1519   return m_iCurRecord = m_RecordArr.GetSize() - 1;
1520 }
Layout()1521 void CFWL_EditImp::Layout() {
1522   GetClientRect(m_rtClient);
1523   m_rtEngine = m_rtClient;
1524   FX_FLOAT* pfWidth =
1525       static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1526   if (!pfWidth)
1527     return;
1528   FX_FLOAT fWidth = *pfWidth;
1529   if (!m_pOuter) {
1530     CFX_RectF* pUIMargin =
1531         static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin));
1532     if (pUIMargin) {
1533       m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
1534                          pUIMargin->height);
1535     }
1536   } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) {
1537     CFWL_ThemePart part;
1538     part.m_pWidget = m_pOuter;
1539     CFX_RectF* pUIMargin =
1540         static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity(
1541             &part, FWL_WGTCAPACITY_UIMargin));
1542     if (pUIMargin) {
1543       m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
1544                          pUIMargin->height);
1545     }
1546   }
1547   FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
1548   FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
1549   if (bShowVertScrollbar) {
1550     InitScrollBar();
1551     CFX_RectF rtVertScr;
1552     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
1553       rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
1554                     fWidth, m_rtClient.height);
1555     } else {
1556       rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
1557                     m_rtClient.height);
1558       if (bShowHorzScrollbar) {
1559         rtVertScr.height -= fWidth;
1560       }
1561       m_rtEngine.width -= fWidth;
1562     }
1563     m_pVertScrollBar->SetWidgetRect(rtVertScr);
1564     m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
1565     m_pVertScrollBar->Update();
1566   } else if (m_pVertScrollBar) {
1567     m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
1568   }
1569   if (bShowHorzScrollbar) {
1570     InitScrollBar(FALSE);
1571     CFX_RectF rtHoriScr;
1572     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
1573       rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
1574                     m_rtClient.width, fWidth);
1575     } else {
1576       rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
1577                     m_rtClient.width, fWidth);
1578       if (bShowVertScrollbar) {
1579         rtHoriScr.width -= fWidth;
1580       }
1581       m_rtEngine.height -= fWidth;
1582     }
1583     m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
1584     m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
1585     m_pHorzScrollBar->Update();
1586   } else if (m_pHorzScrollBar) {
1587     m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
1588   }
1589 }
LayoutScrollBar()1590 void CFWL_EditImp::LayoutScrollBar() {
1591   if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) ==
1592       0) {
1593     return;
1594   }
1595   FX_FLOAT* pfWidth = NULL;
1596   FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
1597   FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
1598   if (bShowVertScrollbar) {
1599     if (!m_pVertScrollBar) {
1600       pfWidth = static_cast<FX_FLOAT*>(
1601           GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1602       FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
1603       InitScrollBar();
1604       CFX_RectF rtVertScr;
1605       if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
1606         rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
1607                       fWidth, m_rtClient.height);
1608       } else {
1609         rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
1610                       m_rtClient.height);
1611         if (bShowHorzScrollbar) {
1612           rtVertScr.height -= fWidth;
1613         }
1614       }
1615       m_pVertScrollBar->SetWidgetRect(rtVertScr);
1616       m_pVertScrollBar->Update();
1617     }
1618     m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
1619   } else if (m_pVertScrollBar) {
1620     m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
1621   }
1622   if (bShowHorzScrollbar) {
1623     if (!m_pHorzScrollBar) {
1624       if (!pfWidth) {
1625         pfWidth = static_cast<FX_FLOAT*>(
1626             GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
1627       }
1628       FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
1629       InitScrollBar(FALSE);
1630       CFX_RectF rtHoriScr;
1631       if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
1632         rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
1633                       m_rtClient.width, fWidth);
1634       } else {
1635         rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
1636                       m_rtClient.width, fWidth);
1637         if (bShowVertScrollbar) {
1638           rtHoriScr.width -= (fWidth);
1639         }
1640       }
1641       m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
1642       m_pHorzScrollBar->Update();
1643     }
1644     m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
1645   } else if (m_pHorzScrollBar) {
1646     m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
1647   }
1648   if (bShowVertScrollbar || bShowHorzScrollbar) {
1649     UpdateScroll();
1650   }
1651 }
DeviceToEngine(CFX_PointF & pt)1652 void CFWL_EditImp::DeviceToEngine(CFX_PointF& pt) {
1653   pt.x += -m_rtEngine.left + m_fScrollOffsetX;
1654   pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY;
1655 }
InitScrollBar(FX_BOOL bVert)1656 void CFWL_EditImp::InitScrollBar(FX_BOOL bVert) {
1657   if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
1658     return;
1659   }
1660   CFWL_WidgetImpProperties prop;
1661   prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;
1662   prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible;
1663   prop.m_pParent = m_pInterface;
1664   prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
1665   IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, m_pInterface);
1666   pScrollBar->Initialize();
1667   (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar);
1668 }
InitEngine()1669 void CFWL_EditImp::InitEngine() {
1670   if (m_pEdtEngine) {
1671     return;
1672   }
1673   m_pEdtEngine = IFDE_TxtEdtEngine::Create();
1674 }
1675 extern FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
1676                              FX_BOOL bVisible,
1677                              const CFX_RectF* pRtAnchor);
ShowCaret(FX_BOOL bVisible,CFX_RectF * pRect)1678 void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF* pRect) {
1679   if (m_pCaret) {
1680     m_pCaret->ShowCaret(bVisible);
1681     if (bVisible && !pRect->IsEmpty()) {
1682       m_pCaret->SetWidgetRect(*pRect);
1683     }
1684     Repaint(&m_rtEngine);
1685   } else {
1686     IFWL_Widget* pOuter = m_pInterface;
1687     if (bVisible) {
1688       pRect->Offset(m_pProperties->m_rtWidget.left,
1689                     m_pProperties->m_rtWidget.top);
1690     }
1691     while (pOuter->GetOuter()) {
1692       pOuter = pOuter->GetOuter();
1693       if (bVisible) {
1694         CFX_RectF rtOuter;
1695         pOuter->GetWidgetRect(rtOuter);
1696         pRect->Offset(rtOuter.left, rtOuter.top);
1697       }
1698     }
1699     FWL_ShowCaret(pOuter, bVisible, pRect);
1700   }
1701 }
ValidateNumberChar(FX_WCHAR cNum)1702 FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum) {
1703   if (!m_pEdtEngine) {
1704     return FALSE;
1705   }
1706   if (!m_bSetRange) {
1707     return TRUE;
1708   }
1709   CFX_WideString wsOld, wsText;
1710   m_pEdtEngine->GetText(wsText, 0);
1711   if (wsText.IsEmpty()) {
1712     if (cNum == L'0') {
1713       return FALSE;
1714     }
1715     return TRUE;
1716   }
1717   int32_t caretPos = m_pEdtEngine->GetCaretPos();
1718   int32_t iSel = CountSelRanges();
1719   if (iSel == 0) {
1720     if (cNum == L'0' && caretPos == 0) {
1721       return FALSE;
1722     }
1723     int32_t nLen = wsText.GetLength();
1724     CFX_WideString l = wsText.Mid(0, caretPos);
1725     CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos);
1726     CFX_WideString wsNew = l + cNum + r;
1727     if (wsNew.GetInteger() <= m_iMax) {
1728       return TRUE;
1729     }
1730   } else {
1731     if (wsText.GetInteger() <= m_iMax) {
1732       return TRUE;
1733     }
1734   }
1735   return FALSE;
1736 }
InitCaret()1737 void CFWL_EditImp::InitCaret() {
1738   if (!m_pCaret) {
1739     if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) {
1740       CFWL_WidgetImpProperties prop;
1741       m_pCaret.reset(IFWL_Caret::Create(prop, m_pInterface));
1742       m_pCaret->Initialize();
1743       m_pCaret->SetParent(m_pInterface);
1744       m_pCaret->SetStates(m_pProperties->m_dwStates);
1745     }
1746   } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) ==
1747              0) {
1748     m_pCaret.reset();
1749   }
1750 }
ClearRecord()1751 void CFWL_EditImp::ClearRecord() {
1752   m_iCurRecord = -1;
1753   m_RecordArr.RemoveAll();
1754 }
ProcessInsertError(int32_t iError)1755 void CFWL_EditImp::ProcessInsertError(int32_t iError) {
1756   switch (iError) {
1757     case -2: {
1758       CFWL_EvtEdtTextFull textFullEvent;
1759       textFullEvent.m_pSrcTarget = m_pInterface;
1760       DispatchEvent(&textFullEvent);
1761       break;
1762     }
1763     default: {}
1764   }
1765 }
CFWL_EditImpDelegate(CFWL_EditImp * pOwner)1766 CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner)
1767     : m_pOwner(pOwner) {}
OnProcessMessage(CFWL_Message * pMessage)1768 int32_t CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
1769   if (!pMessage)
1770     return 0;
1771   FX_DWORD dwMsgCode = pMessage->GetClassID();
1772   int32_t iRet = 1;
1773   switch (dwMsgCode) {
1774     case FWL_MSGHASH_Activate: {
1775       DoActivate(static_cast<CFWL_MsgActivate*>(pMessage));
1776       break;
1777     }
1778     case FWL_MSGHASH_Deactivate: {
1779       DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage));
1780       break;
1781     }
1782     case FWL_MSGHASH_SetFocus:
1783     case FWL_MSGHASH_KillFocus: {
1784       OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
1785       break;
1786     }
1787     case FWL_MSGHASH_Mouse: {
1788       CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
1789       FX_DWORD dwCmd = pMsg->m_dwCmd;
1790       switch (dwCmd) {
1791         case FWL_MSGMOUSECMD_LButtonDown: {
1792           OnLButtonDown(pMsg);
1793           break;
1794         }
1795         case FWL_MSGMOUSECMD_LButtonUp: {
1796           OnLButtonUp(pMsg);
1797           break;
1798         }
1799         case FWL_MSGMOUSECMD_LButtonDblClk: {
1800           OnButtonDblClk(pMsg);
1801           break;
1802         }
1803         case FWL_MSGMOUSECMD_MouseMove: {
1804           OnMouseMove(pMsg);
1805           break;
1806         }
1807         case FWL_MSGMOUSECMD_RButtonDown: {
1808           DoButtonDown(pMsg);
1809           break;
1810         }
1811         default: {}
1812       }
1813       break;
1814     }
1815     case FWL_MSGHASH_Key: {
1816       CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
1817       FX_DWORD dwCmd = pKey->m_dwCmd;
1818       if (dwCmd == FWL_MSGKEYCMD_KeyDown) {
1819         OnKeyDown(pKey);
1820       } else if (dwCmd == FWL_MSGKEYCMD_Char) {
1821         OnChar(pKey);
1822       }
1823       break;
1824     }
1825     default: { iRet = 0; }
1826   }
1827   CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
1828   return iRet;
1829 }
OnProcessEvent(CFWL_Event * pEvent)1830 FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1831   if (!pEvent)
1832     return FWL_ERR_Indefinite;
1833   FX_DWORD dwHashCode = pEvent->GetClassID();
1834   if (dwHashCode != FWL_EVTHASH_Scroll) {
1835     return FWL_ERR_Succeeded;
1836   }
1837   IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
1838   if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() &&
1839        m_pOwner->m_pVertScrollBar) ||
1840       (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() &&
1841        m_pOwner->m_pHorzScrollBar)) {
1842     CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
1843     OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget),
1844              pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
1845   }
1846   return FWL_ERR_Succeeded;
1847 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1848 FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1849                                            const CFX_Matrix* pMatrix) {
1850   return m_pOwner->DrawWidget(pGraphics, pMatrix);
1851 }
DoActivate(CFWL_MsgActivate * pMsg)1852 void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate* pMsg) {
1853   m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;
1854   m_pOwner->Repaint(&m_pOwner->m_rtClient);
1855 }
DoDeactivate(CFWL_MsgDeactivate * pMsg)1856 void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate* pMsg) {
1857   m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;
1858   m_pOwner->Repaint(&m_pOwner->m_rtClient);
1859 }
DoButtonDown(CFWL_MsgMouse * pMsg)1860 void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse* pMsg) {
1861   if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
1862     m_pOwner->SetFocus(TRUE);
1863   }
1864   if (!m_pOwner->m_pEdtEngine) {
1865     m_pOwner->UpdateEditEngine();
1866   }
1867   IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
1868   if (!pPage)
1869     return;
1870   CFX_PointF pt;
1871   pt.Set(pMsg->m_fx, pMsg->m_fy);
1872   m_pOwner->DeviceToEngine(pt);
1873   FX_BOOL bBefore = TRUE;
1874   int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
1875   if (nIndex < 0) {
1876     nIndex = 0;
1877   }
1878   m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
1879 }
OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)1880 void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) {
1881   FX_DWORD dwStyleEx = m_pOwner->GetStylesEx();
1882   FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret;
1883   if (bSet) {
1884     m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
1885     if (!m_pOwner->m_pEdtEngine) {
1886       m_pOwner->UpdateEditEngine();
1887     }
1888     m_pOwner->UpdateVAlignment();
1889     m_pOwner->UpdateOffset();
1890     m_pOwner->UpdateCaret();
1891   } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
1892     m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
1893     m_pOwner->ShowCaret(FALSE);
1894     if (m_pOwner->m_pEdtEngine &&
1895         (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {
1896       int32_t nSel = m_pOwner->CountSelRanges();
1897       if (nSel > 0) {
1898         m_pOwner->ClearSelections();
1899         bRepaint = TRUE;
1900       }
1901       m_pOwner->SetCaretPos(0);
1902       m_pOwner->UpdateOffset();
1903     }
1904     m_pOwner->ClearRecord();
1905   }
1906   m_pOwner->LayoutScrollBar();
1907   if (bRepaint) {
1908     CFX_RectF rtInvalidate;
1909     rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
1910                      m_pOwner->m_pProperties->m_rtWidget.height);
1911     m_pOwner->Repaint(&rtInvalidate);
1912   }
1913 }
OnLButtonDown(CFWL_MsgMouse * pMsg)1914 void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
1915   DoCursor(pMsg);
1916   if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
1917     return;
1918   }
1919   m_pOwner->m_bLButtonDown = TRUE;
1920   m_pOwner->SetGrab(TRUE);
1921   DoButtonDown(pMsg);
1922   int32_t nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
1923   FX_BOOL bRepaint = FALSE;
1924   int32_t iCount = m_pOwner->m_pEdtEngine->CountSelRanges();
1925   if (iCount > 0) {
1926     m_pOwner->m_pEdtEngine->ClearSelection();
1927     bRepaint = TRUE;
1928   }
1929   FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
1930   if (bShift && m_pOwner->m_nSelStart != nIndex) {
1931     int32_t iStart = std::min(m_pOwner->m_nSelStart, nIndex);
1932     int32_t iEnd = std::max(m_pOwner->m_nSelStart, nIndex);
1933     m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);
1934     bRepaint = TRUE;
1935   } else {
1936     m_pOwner->m_nSelStart = nIndex;
1937   }
1938   if (bRepaint) {
1939     m_pOwner->Repaint(&m_pOwner->m_rtEngine);
1940   }
1941 }
OnLButtonUp(CFWL_MsgMouse * pMsg)1942 void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1943   DoCursor(pMsg);
1944   m_pOwner->m_bLButtonDown = FALSE;
1945   m_pOwner->SetGrab(FALSE);
1946 }
OnButtonDblClk(CFWL_MsgMouse * pMsg)1947 void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse* pMsg) {
1948   if (!m_pOwner->m_pEdtEngine)
1949     return;
1950   DoCursor(pMsg);
1951   IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
1952   if (!pPage)
1953     return;
1954   CFX_PointF pt;
1955   pt.Set(pMsg->m_fx, pMsg->m_fy);
1956   m_pOwner->DeviceToEngine(pt);
1957   int32_t nCount = 0;
1958   int32_t nIndex = pPage->SelectWord(pt, nCount);
1959   if (nIndex < 0) {
1960     return;
1961   }
1962   m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);
1963   m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);
1964   m_pOwner->Repaint(&m_pOwner->m_rtEngine);
1965 }
OnMouseMove(CFWL_MsgMouse * pMsg)1966 void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
1967   if (!m_pOwner->m_pEdtEngine)
1968     return;
1969   DoCursor(pMsg);
1970   if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {
1971     return;
1972   }
1973   IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
1974   if (!pPage)
1975     return;
1976   CFX_PointF pt;
1977   pt.Set(pMsg->m_fx, pMsg->m_fy);
1978   m_pOwner->DeviceToEngine(pt);
1979   FX_BOOL bBefore = TRUE;
1980   int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
1981   m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
1982   nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
1983   m_pOwner->m_pEdtEngine->ClearSelection();
1984   if (nIndex != m_pOwner->m_nSelStart) {
1985     int32_t nLen = m_pOwner->m_pEdtEngine->GetTextLength();
1986     if (m_pOwner->m_nSelStart >= nLen) {
1987       m_pOwner->m_nSelStart = nLen;
1988     }
1989     m_pOwner->m_pEdtEngine->AddSelRange(
1990         std::min(m_pOwner->m_nSelStart, nIndex),
1991         FXSYS_abs(nIndex - m_pOwner->m_nSelStart));
1992   }
1993 }
OnKeyDown(CFWL_MsgKey * pMsg)1994 void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
1995   if (!m_pOwner->m_pEdtEngine)
1996     return;
1997   FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;
1998   FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
1999   FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
2000   FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
2001   switch (dwKeyCode) {
2002     case FWL_VKEY_Left: {
2003       MoveCaret = MC_Left;
2004       break;
2005     }
2006     case FWL_VKEY_Right: {
2007       MoveCaret = MC_Right;
2008       break;
2009     }
2010     case FWL_VKEY_Up: {
2011       MoveCaret = MC_Up;
2012       break;
2013     }
2014     case FWL_VKEY_Down: {
2015       MoveCaret = MC_Down;
2016       break;
2017     }
2018     case FWL_VKEY_Home: {
2019       if (bCtrl) {
2020         MoveCaret = MC_Home;
2021       } else {
2022         MoveCaret = MC_LineStart;
2023       }
2024       break;
2025     }
2026     case FWL_VKEY_End: {
2027       if (bCtrl) {
2028         MoveCaret = MC_End;
2029       } else {
2030         MoveCaret = MC_LineEnd;
2031       }
2032       break;
2033     }
2034     case FWL_VKEY_Insert: {
2035       break;
2036     }
2037     case FWL_VKEY_Delete: {
2038       if ((m_pOwner->m_pProperties->m_dwStyleExes &
2039            FWL_STYLEEXT_EDT_ReadOnly) ||
2040           (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
2041         break;
2042       }
2043       int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
2044 #if (_FX_OS_ == _FX_MACOSX_)
2045       m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
2046 #else
2047       m_pOwner->m_pEdtEngine->Delete(nCaret);
2048 #endif
2049       break;
2050     }
2051     case FWL_VKEY_F2: {
2052       break;
2053     }
2054     case FWL_VKEY_Tab: {
2055       m_pOwner->DispatchKeyEvent(pMsg);
2056       break;
2057     }
2058     default: {
2059 #if (_FX_OS_ == _FX_MACOSX_)
2060       if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
2061 #else
2062       if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
2063 #endif
2064       {
2065         if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {
2066           m_pOwner->DoClipboard(1);
2067           return;
2068         }
2069         if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {
2070           m_pOwner->DoClipboard(2);
2071           return;
2072         }
2073         if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {
2074           m_pOwner->DoClipboard(3);
2075           return;
2076         }
2077       }
2078     }
2079   }
2080   if (MoveCaret != MC_MoveNone) {
2081     m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);
2082   }
2083 }
OnChar(CFWL_MsgKey * pMsg)2084 void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey* pMsg) {
2085   if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
2086       (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
2087     return;
2088   }
2089   if (!m_pOwner->m_pEdtEngine)
2090     return;
2091   int32_t iError = 0;
2092   FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;
2093   int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
2094   switch (c) {
2095     case FWL_VKEY_Back: {
2096       m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
2097       break;
2098     }
2099     case 0x0A: {
2100       break;
2101     }
2102     case FWL_VKEY_Escape: {
2103       break;
2104     }
2105     case FWL_VKEY_Tab: {
2106       iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\t", 1);
2107       break;
2108     }
2109     case FWL_VKEY_Return: {
2110       if (m_pOwner->m_pProperties->m_dwStyleExes &
2111           FWL_STYLEEXT_EDT_WantReturn) {
2112         iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\n", 1);
2113       }
2114       break;
2115     }
2116     default: {
2117       if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
2118         if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) {
2119           if (((pMsg->m_dwKeyCode < FWL_VKEY_0) &&
2120                (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) ||
2121               pMsg->m_dwKeyCode > FWL_VKEY_9) {
2122             break;
2123           }
2124           if (!m_pOwner->ValidateNumberChar(c)) {
2125             break;
2126           }
2127         }
2128       }
2129 #if (_FX_OS_ == _FX_MACOSX_)
2130       if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
2131 #else
2132       if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
2133 #endif
2134       {
2135         break;
2136       }
2137       iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);
2138       break;
2139     }
2140   }
2141   if (iError < 0) {
2142     m_pOwner->ProcessInsertError(iError);
2143   }
2144 }
OnScroll(IFWL_ScrollBar * pScrollBar,FX_DWORD dwCode,FX_FLOAT fPos)2145 FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar,
2146                                        FX_DWORD dwCode,
2147                                        FX_FLOAT fPos) {
2148   CFX_SizeF fs;
2149   pScrollBar->GetRange(fs.x, fs.y);
2150   FX_FLOAT iCurPos = pScrollBar->GetPos();
2151   FX_FLOAT fStep = pScrollBar->GetStepSize();
2152   switch (dwCode) {
2153     case FWL_SCBCODE_Min: {
2154       fPos = fs.x;
2155       break;
2156     }
2157     case FWL_SCBCODE_Max: {
2158       fPos = fs.y;
2159       break;
2160     }
2161     case FWL_SCBCODE_StepBackward: {
2162       fPos -= fStep;
2163       if (fPos < fs.x + fStep / 2) {
2164         fPos = fs.x;
2165       }
2166       break;
2167     }
2168     case FWL_SCBCODE_StepForward: {
2169       fPos += fStep;
2170       if (fPos > fs.y - fStep / 2) {
2171         fPos = fs.y;
2172       }
2173       break;
2174     }
2175     case FWL_SCBCODE_PageBackward: {
2176       fPos -= pScrollBar->GetPageSize();
2177       if (fPos < fs.x) {
2178         fPos = fs.x;
2179       }
2180       break;
2181     }
2182     case FWL_SCBCODE_PageForward: {
2183       fPos += pScrollBar->GetPageSize();
2184       if (fPos > fs.y) {
2185         fPos = fs.y;
2186       }
2187       break;
2188     }
2189     case FWL_SCBCODE_Pos:
2190     case FWL_SCBCODE_TrackPos: {
2191       break;
2192     }
2193     case FWL_SCBCODE_EndScroll: {
2194       return FALSE;
2195     }
2196     default: {}
2197   }
2198   if (iCurPos != fPos) {
2199     pScrollBar->SetPos(fPos);
2200     pScrollBar->SetTrackPos(fPos);
2201     m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);
2202     if (m_pOwner->m_pEdtEngine) {
2203       m_pOwner->UpdateCaret();
2204     }
2205     CFX_RectF rect;
2206     m_pOwner->GetWidgetRect(rect);
2207     CFX_RectF rtInvalidate;
2208     rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);
2209     m_pOwner->Repaint(&rtInvalidate);
2210   }
2211   return TRUE;
2212 }
DoCursor(CFWL_MsgMouse * pMsg)2213 void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {
2214   if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
2215     IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
2216     IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
2217     if (NULL != pCursorMgr) {
2218       FWL_HCURSOR hCursor =
2219           pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_InputBeam);
2220       pCursorMgr->SetCursor(hCursor);
2221       pCursorMgr->ShowCursor(TRUE);
2222     }
2223   }
2224 }
2225