xref: /aosp_15_r20/external/pdfium/fpdfsdk/pwl/cpwl_edit_impl.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/pwl/cpwl_edit_impl.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
10*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
11*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
12*3ac0a46fSAndroid Build Coastguard Worker 
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/font/cpdf_font.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/render/cpdf_renderoptions.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/render/cpdf_textrenderer.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpvt_word.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/ipvt_fontmap.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/autorestorer.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_codepage.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_fillrenderoptions.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_graphstatedata.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_path.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_renderdevice.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/pwl/cpwl_edit.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/pwl/cpwl_scroll_bar.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/pwl/ipwl_fillernotify.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check_op.h"
29*3ac0a46fSAndroid Build Coastguard Worker 
30*3ac0a46fSAndroid Build Coastguard Worker namespace {
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker const int kEditUndoMaxItems = 10000;
33*3ac0a46fSAndroid Build Coastguard Worker 
DrawTextString(CFX_RenderDevice * pDevice,const CFX_PointF & pt,CPDF_Font * pFont,float fFontSize,const CFX_Matrix & mtUser2Device,const ByteString & str,FX_ARGB crTextFill)34*3ac0a46fSAndroid Build Coastguard Worker void DrawTextString(CFX_RenderDevice* pDevice,
35*3ac0a46fSAndroid Build Coastguard Worker                     const CFX_PointF& pt,
36*3ac0a46fSAndroid Build Coastguard Worker                     CPDF_Font* pFont,
37*3ac0a46fSAndroid Build Coastguard Worker                     float fFontSize,
38*3ac0a46fSAndroid Build Coastguard Worker                     const CFX_Matrix& mtUser2Device,
39*3ac0a46fSAndroid Build Coastguard Worker                     const ByteString& str,
40*3ac0a46fSAndroid Build Coastguard Worker                     FX_ARGB crTextFill) {
41*3ac0a46fSAndroid Build Coastguard Worker   if (!pFont)
42*3ac0a46fSAndroid Build Coastguard Worker     return;
43*3ac0a46fSAndroid Build Coastguard Worker 
44*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF pos = mtUser2Device.Transform(pt);
45*3ac0a46fSAndroid Build Coastguard Worker   CPDF_RenderOptions ro;
46*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(ro.GetOptions().bClearType);
47*3ac0a46fSAndroid Build Coastguard Worker   ro.SetColorMode(CPDF_RenderOptions::kNormal);
48*3ac0a46fSAndroid Build Coastguard Worker   CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
49*3ac0a46fSAndroid Build Coastguard Worker                                     mtUser2Device, str, crTextFill, ro);
50*3ac0a46fSAndroid Build Coastguard Worker }
51*3ac0a46fSAndroid Build Coastguard Worker 
52*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
53*3ac0a46fSAndroid Build Coastguard Worker 
Iterator(CPWL_EditImpl * pEdit,CPVT_VariableText::Iterator * pVTIterator)54*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::Iterator::Iterator(CPWL_EditImpl* pEdit,
55*3ac0a46fSAndroid Build Coastguard Worker                                   CPVT_VariableText::Iterator* pVTIterator)
56*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
57*3ac0a46fSAndroid Build Coastguard Worker 
58*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::Iterator::~Iterator() = default;
59*3ac0a46fSAndroid Build Coastguard Worker 
NextWord()60*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Iterator::NextWord() {
61*3ac0a46fSAndroid Build Coastguard Worker   return m_pVTIterator->NextWord();
62*3ac0a46fSAndroid Build Coastguard Worker }
63*3ac0a46fSAndroid Build Coastguard Worker 
GetWord(CPVT_Word & word) const64*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Iterator::GetWord(CPVT_Word& word) const {
65*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
66*3ac0a46fSAndroid Build Coastguard Worker 
67*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVTIterator->GetWord(word)) {
68*3ac0a46fSAndroid Build Coastguard Worker     word.ptWord = m_pEdit->VTToEdit(word.ptWord);
69*3ac0a46fSAndroid Build Coastguard Worker     return true;
70*3ac0a46fSAndroid Build Coastguard Worker   }
71*3ac0a46fSAndroid Build Coastguard Worker   return false;
72*3ac0a46fSAndroid Build Coastguard Worker }
73*3ac0a46fSAndroid Build Coastguard Worker 
GetLine(CPVT_Line & line) const74*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Iterator::GetLine(CPVT_Line& line) const {
75*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
76*3ac0a46fSAndroid Build Coastguard Worker 
77*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVTIterator->GetLine(line)) {
78*3ac0a46fSAndroid Build Coastguard Worker     line.ptLine = m_pEdit->VTToEdit(line.ptLine);
79*3ac0a46fSAndroid Build Coastguard Worker     return true;
80*3ac0a46fSAndroid Build Coastguard Worker   }
81*3ac0a46fSAndroid Build Coastguard Worker   return false;
82*3ac0a46fSAndroid Build Coastguard Worker }
83*3ac0a46fSAndroid Build Coastguard Worker 
SetAt(int32_t nWordIndex)84*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::Iterator::SetAt(int32_t nWordIndex) {
85*3ac0a46fSAndroid Build Coastguard Worker   m_pVTIterator->SetAt(nWordIndex);
86*3ac0a46fSAndroid Build Coastguard Worker }
87*3ac0a46fSAndroid Build Coastguard Worker 
SetAt(const CPVT_WordPlace & place)88*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::Iterator::SetAt(const CPVT_WordPlace& place) {
89*3ac0a46fSAndroid Build Coastguard Worker   m_pVTIterator->SetAt(place);
90*3ac0a46fSAndroid Build Coastguard Worker }
91*3ac0a46fSAndroid Build Coastguard Worker 
GetAt() const92*3ac0a46fSAndroid Build Coastguard Worker const CPVT_WordPlace& CPWL_EditImpl::Iterator::GetAt() const {
93*3ac0a46fSAndroid Build Coastguard Worker   return m_pVTIterator->GetWordPlace();
94*3ac0a46fSAndroid Build Coastguard Worker }
95*3ac0a46fSAndroid Build Coastguard Worker 
96*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::Provider final : public CPVT_VariableText::Provider {
97*3ac0a46fSAndroid Build Coastguard Worker  public:
98*3ac0a46fSAndroid Build Coastguard Worker   explicit Provider(IPVT_FontMap* pFontMap);
99*3ac0a46fSAndroid Build Coastguard Worker   ~Provider() override;
100*3ac0a46fSAndroid Build Coastguard Worker 
101*3ac0a46fSAndroid Build Coastguard Worker   // CPVT_VariableText::Provider:
102*3ac0a46fSAndroid Build Coastguard Worker   int GetCharWidth(int32_t nFontIndex, uint16_t word) override;
103*3ac0a46fSAndroid Build Coastguard Worker   int32_t GetWordFontIndex(uint16_t word,
104*3ac0a46fSAndroid Build Coastguard Worker                            FX_Charset charset,
105*3ac0a46fSAndroid Build Coastguard Worker                            int32_t nFontIndex) override;
106*3ac0a46fSAndroid Build Coastguard Worker };
107*3ac0a46fSAndroid Build Coastguard Worker 
Provider(IPVT_FontMap * pFontMap)108*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::Provider::Provider(IPVT_FontMap* pFontMap)
109*3ac0a46fSAndroid Build Coastguard Worker     : CPVT_VariableText::Provider(pFontMap) {}
110*3ac0a46fSAndroid Build Coastguard Worker 
111*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::Provider::~Provider() = default;
112*3ac0a46fSAndroid Build Coastguard Worker 
GetCharWidth(int32_t nFontIndex,uint16_t word)113*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) {
114*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<CPDF_Font> pPDFFont = GetFontMap()->GetPDFFont(nFontIndex);
115*3ac0a46fSAndroid Build Coastguard Worker   if (!pPDFFont)
116*3ac0a46fSAndroid Build Coastguard Worker     return 0;
117*3ac0a46fSAndroid Build Coastguard Worker 
118*3ac0a46fSAndroid Build Coastguard Worker   uint32_t charcode = pPDFFont->IsUnicodeCompatible()
119*3ac0a46fSAndroid Build Coastguard Worker                           ? pPDFFont->CharCodeFromUnicode(word)
120*3ac0a46fSAndroid Build Coastguard Worker                           : GetFontMap()->CharCodeFromUnicode(nFontIndex, word);
121*3ac0a46fSAndroid Build Coastguard Worker   if (charcode == CPDF_Font::kInvalidCharCode)
122*3ac0a46fSAndroid Build Coastguard Worker     return 0;
123*3ac0a46fSAndroid Build Coastguard Worker 
124*3ac0a46fSAndroid Build Coastguard Worker   return pPDFFont->GetCharWidthF(charcode);
125*3ac0a46fSAndroid Build Coastguard Worker }
126*3ac0a46fSAndroid Build Coastguard Worker 
GetWordFontIndex(uint16_t word,FX_Charset charset,int32_t nFontIndex)127*3ac0a46fSAndroid Build Coastguard Worker int32_t CPWL_EditImpl::Provider::GetWordFontIndex(uint16_t word,
128*3ac0a46fSAndroid Build Coastguard Worker                                                   FX_Charset charset,
129*3ac0a46fSAndroid Build Coastguard Worker                                                   int32_t nFontIndex) {
130*3ac0a46fSAndroid Build Coastguard Worker   return GetFontMap()->GetWordFontIndex(word, charset, nFontIndex);
131*3ac0a46fSAndroid Build Coastguard Worker }
132*3ac0a46fSAndroid Build Coastguard Worker 
133*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::RefreshState::RefreshState() = default;
134*3ac0a46fSAndroid Build Coastguard Worker 
135*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::RefreshState::~RefreshState() = default;
136*3ac0a46fSAndroid Build Coastguard Worker 
BeginRefresh()137*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshState::BeginRefresh() {
138*3ac0a46fSAndroid Build Coastguard Worker   m_OldLineRects = std::move(m_NewLineRects);
139*3ac0a46fSAndroid Build Coastguard Worker   m_NewLineRects.clear();
140*3ac0a46fSAndroid Build Coastguard Worker   m_RefreshRects.clear();
141*3ac0a46fSAndroid Build Coastguard Worker }
142*3ac0a46fSAndroid Build Coastguard Worker 
Push(const CPVT_WordRange & linerange,const CFX_FloatRect & rect)143*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshState::Push(const CPVT_WordRange& linerange,
144*3ac0a46fSAndroid Build Coastguard Worker                                        const CFX_FloatRect& rect) {
145*3ac0a46fSAndroid Build Coastguard Worker   m_NewLineRects.emplace_back(LineRect(linerange, rect));
146*3ac0a46fSAndroid Build Coastguard Worker }
147*3ac0a46fSAndroid Build Coastguard Worker 
NoAnalyse()148*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshState::NoAnalyse() {
149*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& lineRect : m_OldLineRects)
150*3ac0a46fSAndroid Build Coastguard Worker     Add(lineRect.m_rcLine);
151*3ac0a46fSAndroid Build Coastguard Worker 
152*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& lineRect : m_NewLineRects)
153*3ac0a46fSAndroid Build Coastguard Worker     Add(lineRect.m_rcLine);
154*3ac0a46fSAndroid Build Coastguard Worker }
155*3ac0a46fSAndroid Build Coastguard Worker 
GetRefreshRects()156*3ac0a46fSAndroid Build Coastguard Worker std::vector<CFX_FloatRect>* CPWL_EditImpl::RefreshState::GetRefreshRects() {
157*3ac0a46fSAndroid Build Coastguard Worker   return &m_RefreshRects;
158*3ac0a46fSAndroid Build Coastguard Worker }
159*3ac0a46fSAndroid Build Coastguard Worker 
EndRefresh()160*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshState::EndRefresh() {
161*3ac0a46fSAndroid Build Coastguard Worker   m_RefreshRects.clear();
162*3ac0a46fSAndroid Build Coastguard Worker }
163*3ac0a46fSAndroid Build Coastguard Worker 
Add(const CFX_FloatRect & new_rect)164*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshState::Add(const CFX_FloatRect& new_rect) {
165*3ac0a46fSAndroid Build Coastguard Worker   // Check for overlapped area.
166*3ac0a46fSAndroid Build Coastguard Worker   for (const auto& rect : m_RefreshRects) {
167*3ac0a46fSAndroid Build Coastguard Worker     if (rect.Contains(new_rect))
168*3ac0a46fSAndroid Build Coastguard Worker       return;
169*3ac0a46fSAndroid Build Coastguard Worker   }
170*3ac0a46fSAndroid Build Coastguard Worker   m_RefreshRects.emplace_back(CFX_FloatRect(new_rect));
171*3ac0a46fSAndroid Build Coastguard Worker }
172*3ac0a46fSAndroid Build Coastguard Worker 
173*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoStack::UndoStack() = default;
174*3ac0a46fSAndroid Build Coastguard Worker 
175*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoStack::~UndoStack() = default;
176*3ac0a46fSAndroid Build Coastguard Worker 
CanUndo() const177*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::UndoStack::CanUndo() const {
178*3ac0a46fSAndroid Build Coastguard Worker   return m_nCurUndoPos > 0;
179*3ac0a46fSAndroid Build Coastguard Worker }
180*3ac0a46fSAndroid Build Coastguard Worker 
Undo()181*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::UndoStack::Undo() {
182*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(!m_bWorking);
183*3ac0a46fSAndroid Build Coastguard Worker   m_bWorking = true;
184*3ac0a46fSAndroid Build Coastguard Worker   int nUndoRemain = 1;
185*3ac0a46fSAndroid Build Coastguard Worker   while (CanUndo() && nUndoRemain > 0) {
186*3ac0a46fSAndroid Build Coastguard Worker     nUndoRemain += m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
187*3ac0a46fSAndroid Build Coastguard Worker     m_nCurUndoPos--;
188*3ac0a46fSAndroid Build Coastguard Worker     nUndoRemain--;
189*3ac0a46fSAndroid Build Coastguard Worker   }
190*3ac0a46fSAndroid Build Coastguard Worker   DCHECK_EQ(nUndoRemain, 0);
191*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_bWorking);
192*3ac0a46fSAndroid Build Coastguard Worker   m_bWorking = false;
193*3ac0a46fSAndroid Build Coastguard Worker }
194*3ac0a46fSAndroid Build Coastguard Worker 
CanRedo() const195*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::UndoStack::CanRedo() const {
196*3ac0a46fSAndroid Build Coastguard Worker   return m_nCurUndoPos < m_UndoItemStack.size();
197*3ac0a46fSAndroid Build Coastguard Worker }
198*3ac0a46fSAndroid Build Coastguard Worker 
Redo()199*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::UndoStack::Redo() {
200*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(!m_bWorking);
201*3ac0a46fSAndroid Build Coastguard Worker   m_bWorking = true;
202*3ac0a46fSAndroid Build Coastguard Worker   int nRedoRemain = 1;
203*3ac0a46fSAndroid Build Coastguard Worker   while (CanRedo() && nRedoRemain > 0) {
204*3ac0a46fSAndroid Build Coastguard Worker     nRedoRemain += m_UndoItemStack[m_nCurUndoPos]->Redo();
205*3ac0a46fSAndroid Build Coastguard Worker     m_nCurUndoPos++;
206*3ac0a46fSAndroid Build Coastguard Worker     nRedoRemain--;
207*3ac0a46fSAndroid Build Coastguard Worker   }
208*3ac0a46fSAndroid Build Coastguard Worker   DCHECK_EQ(nRedoRemain, 0);
209*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_bWorking);
210*3ac0a46fSAndroid Build Coastguard Worker   m_bWorking = false;
211*3ac0a46fSAndroid Build Coastguard Worker }
212*3ac0a46fSAndroid Build Coastguard Worker 
AddItem(std::unique_ptr<UndoItemIface> pItem)213*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::UndoStack::AddItem(std::unique_ptr<UndoItemIface> pItem) {
214*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(!m_bWorking);
215*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(pItem);
216*3ac0a46fSAndroid Build Coastguard Worker   if (CanRedo())
217*3ac0a46fSAndroid Build Coastguard Worker     RemoveTails();
218*3ac0a46fSAndroid Build Coastguard Worker 
219*3ac0a46fSAndroid Build Coastguard Worker   if (m_UndoItemStack.size() >= kEditUndoMaxItems)
220*3ac0a46fSAndroid Build Coastguard Worker     RemoveHeads();
221*3ac0a46fSAndroid Build Coastguard Worker 
222*3ac0a46fSAndroid Build Coastguard Worker   m_UndoItemStack.push_back(std::move(pItem));
223*3ac0a46fSAndroid Build Coastguard Worker   m_nCurUndoPos = m_UndoItemStack.size();
224*3ac0a46fSAndroid Build Coastguard Worker }
225*3ac0a46fSAndroid Build Coastguard Worker 
RemoveHeads()226*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::UndoStack::RemoveHeads() {
227*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_UndoItemStack.size() > 1);
228*3ac0a46fSAndroid Build Coastguard Worker   m_UndoItemStack.pop_front();
229*3ac0a46fSAndroid Build Coastguard Worker }
230*3ac0a46fSAndroid Build Coastguard Worker 
RemoveTails()231*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::UndoStack::RemoveTails() {
232*3ac0a46fSAndroid Build Coastguard Worker   while (CanRedo())
233*3ac0a46fSAndroid Build Coastguard Worker     m_UndoItemStack.pop_back();
234*3ac0a46fSAndroid Build Coastguard Worker }
235*3ac0a46fSAndroid Build Coastguard Worker 
236*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoInsertWord final
237*3ac0a46fSAndroid Build Coastguard Worker     : public CPWL_EditImpl::UndoItemIface {
238*3ac0a46fSAndroid Build Coastguard Worker  public:
239*3ac0a46fSAndroid Build Coastguard Worker   UndoInsertWord(CPWL_EditImpl* pEdit,
240*3ac0a46fSAndroid Build Coastguard Worker                  const CPVT_WordPlace& wpOldPlace,
241*3ac0a46fSAndroid Build Coastguard Worker                  const CPVT_WordPlace& wpNewPlace,
242*3ac0a46fSAndroid Build Coastguard Worker                  uint16_t word,
243*3ac0a46fSAndroid Build Coastguard Worker                  FX_Charset charset);
244*3ac0a46fSAndroid Build Coastguard Worker   ~UndoInsertWord() override;
245*3ac0a46fSAndroid Build Coastguard Worker 
246*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
247*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
248*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
249*3ac0a46fSAndroid Build Coastguard Worker 
250*3ac0a46fSAndroid Build Coastguard Worker  private:
251*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
252*3ac0a46fSAndroid Build Coastguard Worker 
253*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpOld;
254*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpNew;
255*3ac0a46fSAndroid Build Coastguard Worker   uint16_t m_Word;
256*3ac0a46fSAndroid Build Coastguard Worker   FX_Charset m_nCharset;
257*3ac0a46fSAndroid Build Coastguard Worker };
258*3ac0a46fSAndroid Build Coastguard Worker 
UndoInsertWord(CPWL_EditImpl * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,uint16_t word,FX_Charset charset)259*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertWord::UndoInsertWord(CPWL_EditImpl* pEdit,
260*3ac0a46fSAndroid Build Coastguard Worker                                               const CPVT_WordPlace& wpOldPlace,
261*3ac0a46fSAndroid Build Coastguard Worker                                               const CPVT_WordPlace& wpNewPlace,
262*3ac0a46fSAndroid Build Coastguard Worker                                               uint16_t word,
263*3ac0a46fSAndroid Build Coastguard Worker                                               FX_Charset charset)
264*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit),
265*3ac0a46fSAndroid Build Coastguard Worker       m_wpOld(wpOldPlace),
266*3ac0a46fSAndroid Build Coastguard Worker       m_wpNew(wpNewPlace),
267*3ac0a46fSAndroid Build Coastguard Worker       m_Word(word),
268*3ac0a46fSAndroid Build Coastguard Worker       m_nCharset(charset) {
269*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
270*3ac0a46fSAndroid Build Coastguard Worker }
271*3ac0a46fSAndroid Build Coastguard Worker 
272*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertWord::~UndoInsertWord() = default;
273*3ac0a46fSAndroid Build Coastguard Worker 
Redo()274*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertWord::Redo() {
275*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
276*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpOld);
277*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->InsertWord(m_Word, m_nCharset, false);
278*3ac0a46fSAndroid Build Coastguard Worker   return 0;
279*3ac0a46fSAndroid Build Coastguard Worker }
280*3ac0a46fSAndroid Build Coastguard Worker 
Undo()281*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertWord::Undo() {
282*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
283*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpNew);
284*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Backspace(false);
285*3ac0a46fSAndroid Build Coastguard Worker   return 0;
286*3ac0a46fSAndroid Build Coastguard Worker }
287*3ac0a46fSAndroid Build Coastguard Worker 
288*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoInsertReturn final
289*3ac0a46fSAndroid Build Coastguard Worker     : public CPWL_EditImpl::UndoItemIface {
290*3ac0a46fSAndroid Build Coastguard Worker  public:
291*3ac0a46fSAndroid Build Coastguard Worker   UndoInsertReturn(CPWL_EditImpl* pEdit,
292*3ac0a46fSAndroid Build Coastguard Worker                    const CPVT_WordPlace& wpOldPlace,
293*3ac0a46fSAndroid Build Coastguard Worker                    const CPVT_WordPlace& wpNewPlace);
294*3ac0a46fSAndroid Build Coastguard Worker   ~UndoInsertReturn() override;
295*3ac0a46fSAndroid Build Coastguard Worker 
296*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
297*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
298*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
299*3ac0a46fSAndroid Build Coastguard Worker 
300*3ac0a46fSAndroid Build Coastguard Worker  private:
301*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
302*3ac0a46fSAndroid Build Coastguard Worker 
303*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpOld;
304*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpNew;
305*3ac0a46fSAndroid Build Coastguard Worker };
306*3ac0a46fSAndroid Build Coastguard Worker 
UndoInsertReturn(CPWL_EditImpl * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace)307*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertReturn::UndoInsertReturn(
308*3ac0a46fSAndroid Build Coastguard Worker     CPWL_EditImpl* pEdit,
309*3ac0a46fSAndroid Build Coastguard Worker     const CPVT_WordPlace& wpOldPlace,
310*3ac0a46fSAndroid Build Coastguard Worker     const CPVT_WordPlace& wpNewPlace)
311*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace) {
312*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
313*3ac0a46fSAndroid Build Coastguard Worker }
314*3ac0a46fSAndroid Build Coastguard Worker 
315*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertReturn::~UndoInsertReturn() = default;
316*3ac0a46fSAndroid Build Coastguard Worker 
Redo()317*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertReturn::Redo() {
318*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
319*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpOld);
320*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->InsertReturn(false);
321*3ac0a46fSAndroid Build Coastguard Worker   return 0;
322*3ac0a46fSAndroid Build Coastguard Worker }
323*3ac0a46fSAndroid Build Coastguard Worker 
Undo()324*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertReturn::Undo() {
325*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
326*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpNew);
327*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Backspace(false);
328*3ac0a46fSAndroid Build Coastguard Worker   return 0;
329*3ac0a46fSAndroid Build Coastguard Worker }
330*3ac0a46fSAndroid Build Coastguard Worker 
331*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoReplaceSelection final
332*3ac0a46fSAndroid Build Coastguard Worker     : public CPWL_EditImpl::UndoItemIface {
333*3ac0a46fSAndroid Build Coastguard Worker  public:
334*3ac0a46fSAndroid Build Coastguard Worker   UndoReplaceSelection(CPWL_EditImpl* pEdit, bool bIsEnd);
335*3ac0a46fSAndroid Build Coastguard Worker   ~UndoReplaceSelection() override;
336*3ac0a46fSAndroid Build Coastguard Worker 
337*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
338*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
339*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
340*3ac0a46fSAndroid Build Coastguard Worker 
341*3ac0a46fSAndroid Build Coastguard Worker  private:
IsEnd() const342*3ac0a46fSAndroid Build Coastguard Worker   bool IsEnd() const { return m_bEnd; }
343*3ac0a46fSAndroid Build Coastguard Worker 
344*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
345*3ac0a46fSAndroid Build Coastguard Worker   const bool m_bEnd;  // indicate whether this is the end of replace action
346*3ac0a46fSAndroid Build Coastguard Worker };
347*3ac0a46fSAndroid Build Coastguard Worker 
UndoReplaceSelection(CPWL_EditImpl * pEdit,bool bIsEnd)348*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoReplaceSelection::UndoReplaceSelection(CPWL_EditImpl* pEdit,
349*3ac0a46fSAndroid Build Coastguard Worker                                                           bool bIsEnd)
350*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit), m_bEnd(bIsEnd) {
351*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
352*3ac0a46fSAndroid Build Coastguard Worker }
353*3ac0a46fSAndroid Build Coastguard Worker 
354*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoReplaceSelection::~UndoReplaceSelection() = default;
355*3ac0a46fSAndroid Build Coastguard Worker 
Redo()356*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoReplaceSelection::Redo() {
357*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
358*3ac0a46fSAndroid Build Coastguard Worker   if (IsEnd())
359*3ac0a46fSAndroid Build Coastguard Worker     return 0;
360*3ac0a46fSAndroid Build Coastguard Worker   // Redo ClearSelection, InsertText and ReplaceSelection's end marker
361*3ac0a46fSAndroid Build Coastguard Worker   return 3;
362*3ac0a46fSAndroid Build Coastguard Worker }
363*3ac0a46fSAndroid Build Coastguard Worker 
Undo()364*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoReplaceSelection::Undo() {
365*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
366*3ac0a46fSAndroid Build Coastguard Worker   if (!IsEnd())
367*3ac0a46fSAndroid Build Coastguard Worker     return 0;
368*3ac0a46fSAndroid Build Coastguard Worker   // Undo InsertText, ClearSelection and ReplaceSelection's beginning
369*3ac0a46fSAndroid Build Coastguard Worker   // marker
370*3ac0a46fSAndroid Build Coastguard Worker   return 3;
371*3ac0a46fSAndroid Build Coastguard Worker }
372*3ac0a46fSAndroid Build Coastguard Worker 
373*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoBackspace final : public CPWL_EditImpl::UndoItemIface {
374*3ac0a46fSAndroid Build Coastguard Worker  public:
375*3ac0a46fSAndroid Build Coastguard Worker   UndoBackspace(CPWL_EditImpl* pEdit,
376*3ac0a46fSAndroid Build Coastguard Worker                 const CPVT_WordPlace& wpOldPlace,
377*3ac0a46fSAndroid Build Coastguard Worker                 const CPVT_WordPlace& wpNewPlace,
378*3ac0a46fSAndroid Build Coastguard Worker                 uint16_t word,
379*3ac0a46fSAndroid Build Coastguard Worker                 FX_Charset charset);
380*3ac0a46fSAndroid Build Coastguard Worker   ~UndoBackspace() override;
381*3ac0a46fSAndroid Build Coastguard Worker 
382*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
383*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
384*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
385*3ac0a46fSAndroid Build Coastguard Worker 
386*3ac0a46fSAndroid Build Coastguard Worker  private:
387*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
388*3ac0a46fSAndroid Build Coastguard Worker 
389*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpOld;
390*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpNew;
391*3ac0a46fSAndroid Build Coastguard Worker   uint16_t m_Word;
392*3ac0a46fSAndroid Build Coastguard Worker   FX_Charset m_nCharset;
393*3ac0a46fSAndroid Build Coastguard Worker };
394*3ac0a46fSAndroid Build Coastguard Worker 
UndoBackspace(CPWL_EditImpl * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,uint16_t word,FX_Charset charset)395*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoBackspace::UndoBackspace(CPWL_EditImpl* pEdit,
396*3ac0a46fSAndroid Build Coastguard Worker                                             const CPVT_WordPlace& wpOldPlace,
397*3ac0a46fSAndroid Build Coastguard Worker                                             const CPVT_WordPlace& wpNewPlace,
398*3ac0a46fSAndroid Build Coastguard Worker                                             uint16_t word,
399*3ac0a46fSAndroid Build Coastguard Worker                                             FX_Charset charset)
400*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit),
401*3ac0a46fSAndroid Build Coastguard Worker       m_wpOld(wpOldPlace),
402*3ac0a46fSAndroid Build Coastguard Worker       m_wpNew(wpNewPlace),
403*3ac0a46fSAndroid Build Coastguard Worker       m_Word(word),
404*3ac0a46fSAndroid Build Coastguard Worker       m_nCharset(charset) {
405*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
406*3ac0a46fSAndroid Build Coastguard Worker }
407*3ac0a46fSAndroid Build Coastguard Worker 
408*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoBackspace::~UndoBackspace() = default;
409*3ac0a46fSAndroid Build Coastguard Worker 
Redo()410*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoBackspace::Redo() {
411*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
412*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpOld);
413*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Backspace(false);
414*3ac0a46fSAndroid Build Coastguard Worker   return 0;
415*3ac0a46fSAndroid Build Coastguard Worker }
416*3ac0a46fSAndroid Build Coastguard Worker 
Undo()417*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoBackspace::Undo() {
418*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
419*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpNew);
420*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
421*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->InsertReturn(false);
422*3ac0a46fSAndroid Build Coastguard Worker   else
423*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->InsertWord(m_Word, m_nCharset, false);
424*3ac0a46fSAndroid Build Coastguard Worker   return 0;
425*3ac0a46fSAndroid Build Coastguard Worker }
426*3ac0a46fSAndroid Build Coastguard Worker 
427*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoDelete final : public CPWL_EditImpl::UndoItemIface {
428*3ac0a46fSAndroid Build Coastguard Worker  public:
429*3ac0a46fSAndroid Build Coastguard Worker   UndoDelete(CPWL_EditImpl* pEdit,
430*3ac0a46fSAndroid Build Coastguard Worker              const CPVT_WordPlace& wpOldPlace,
431*3ac0a46fSAndroid Build Coastguard Worker              const CPVT_WordPlace& wpNewPlace,
432*3ac0a46fSAndroid Build Coastguard Worker              uint16_t word,
433*3ac0a46fSAndroid Build Coastguard Worker              FX_Charset charset,
434*3ac0a46fSAndroid Build Coastguard Worker              bool bSecEnd);
435*3ac0a46fSAndroid Build Coastguard Worker   ~UndoDelete() override;
436*3ac0a46fSAndroid Build Coastguard Worker 
437*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
438*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
439*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
440*3ac0a46fSAndroid Build Coastguard Worker 
441*3ac0a46fSAndroid Build Coastguard Worker  private:
442*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
443*3ac0a46fSAndroid Build Coastguard Worker 
444*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpOld;
445*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpNew;
446*3ac0a46fSAndroid Build Coastguard Worker   uint16_t m_Word;
447*3ac0a46fSAndroid Build Coastguard Worker   FX_Charset m_nCharset;
448*3ac0a46fSAndroid Build Coastguard Worker   bool m_bSecEnd;
449*3ac0a46fSAndroid Build Coastguard Worker };
450*3ac0a46fSAndroid Build Coastguard Worker 
UndoDelete(CPWL_EditImpl * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,uint16_t word,FX_Charset charset,bool bSecEnd)451*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoDelete::UndoDelete(CPWL_EditImpl* pEdit,
452*3ac0a46fSAndroid Build Coastguard Worker                                       const CPVT_WordPlace& wpOldPlace,
453*3ac0a46fSAndroid Build Coastguard Worker                                       const CPVT_WordPlace& wpNewPlace,
454*3ac0a46fSAndroid Build Coastguard Worker                                       uint16_t word,
455*3ac0a46fSAndroid Build Coastguard Worker                                       FX_Charset charset,
456*3ac0a46fSAndroid Build Coastguard Worker                                       bool bSecEnd)
457*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit),
458*3ac0a46fSAndroid Build Coastguard Worker       m_wpOld(wpOldPlace),
459*3ac0a46fSAndroid Build Coastguard Worker       m_wpNew(wpNewPlace),
460*3ac0a46fSAndroid Build Coastguard Worker       m_Word(word),
461*3ac0a46fSAndroid Build Coastguard Worker       m_nCharset(charset),
462*3ac0a46fSAndroid Build Coastguard Worker       m_bSecEnd(bSecEnd) {
463*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
464*3ac0a46fSAndroid Build Coastguard Worker }
465*3ac0a46fSAndroid Build Coastguard Worker 
466*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoDelete::~UndoDelete() = default;
467*3ac0a46fSAndroid Build Coastguard Worker 
Redo()468*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoDelete::Redo() {
469*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
470*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpOld);
471*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Delete(false);
472*3ac0a46fSAndroid Build Coastguard Worker   return 0;
473*3ac0a46fSAndroid Build Coastguard Worker }
474*3ac0a46fSAndroid Build Coastguard Worker 
Undo()475*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoDelete::Undo() {
476*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
477*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpNew);
478*3ac0a46fSAndroid Build Coastguard Worker   if (m_bSecEnd)
479*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->InsertReturn(false);
480*3ac0a46fSAndroid Build Coastguard Worker   else
481*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->InsertWord(m_Word, m_nCharset, false);
482*3ac0a46fSAndroid Build Coastguard Worker   return 0;
483*3ac0a46fSAndroid Build Coastguard Worker }
484*3ac0a46fSAndroid Build Coastguard Worker 
485*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoClear final : public CPWL_EditImpl::UndoItemIface {
486*3ac0a46fSAndroid Build Coastguard Worker  public:
487*3ac0a46fSAndroid Build Coastguard Worker   UndoClear(CPWL_EditImpl* pEdit,
488*3ac0a46fSAndroid Build Coastguard Worker             const CPVT_WordRange& wrSel,
489*3ac0a46fSAndroid Build Coastguard Worker             const WideString& swText);
490*3ac0a46fSAndroid Build Coastguard Worker   ~UndoClear() override;
491*3ac0a46fSAndroid Build Coastguard Worker 
492*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
493*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
494*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
495*3ac0a46fSAndroid Build Coastguard Worker 
496*3ac0a46fSAndroid Build Coastguard Worker  private:
497*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
498*3ac0a46fSAndroid Build Coastguard Worker 
499*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordRange m_wrSel;
500*3ac0a46fSAndroid Build Coastguard Worker   WideString m_swText;
501*3ac0a46fSAndroid Build Coastguard Worker };
502*3ac0a46fSAndroid Build Coastguard Worker 
UndoClear(CPWL_EditImpl * pEdit,const CPVT_WordRange & wrSel,const WideString & swText)503*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoClear::UndoClear(CPWL_EditImpl* pEdit,
504*3ac0a46fSAndroid Build Coastguard Worker                                     const CPVT_WordRange& wrSel,
505*3ac0a46fSAndroid Build Coastguard Worker                                     const WideString& swText)
506*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {
507*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
508*3ac0a46fSAndroid Build Coastguard Worker }
509*3ac0a46fSAndroid Build Coastguard Worker 
510*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoClear::~UndoClear() = default;
511*3ac0a46fSAndroid Build Coastguard Worker 
Redo()512*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoClear::Redo() {
513*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
514*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
515*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Clear(false);
516*3ac0a46fSAndroid Build Coastguard Worker   return 0;
517*3ac0a46fSAndroid Build Coastguard Worker }
518*3ac0a46fSAndroid Build Coastguard Worker 
Undo()519*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoClear::Undo() {
520*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
521*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wrSel.BeginPos);
522*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->InsertText(m_swText, FX_Charset::kDefault, false);
523*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
524*3ac0a46fSAndroid Build Coastguard Worker   return 0;
525*3ac0a46fSAndroid Build Coastguard Worker }
526*3ac0a46fSAndroid Build Coastguard Worker 
527*3ac0a46fSAndroid Build Coastguard Worker class CPWL_EditImpl::UndoInsertText final
528*3ac0a46fSAndroid Build Coastguard Worker     : public CPWL_EditImpl::UndoItemIface {
529*3ac0a46fSAndroid Build Coastguard Worker  public:
530*3ac0a46fSAndroid Build Coastguard Worker   UndoInsertText(CPWL_EditImpl* pEdit,
531*3ac0a46fSAndroid Build Coastguard Worker                  const CPVT_WordPlace& wpOldPlace,
532*3ac0a46fSAndroid Build Coastguard Worker                  const CPVT_WordPlace& wpNewPlace,
533*3ac0a46fSAndroid Build Coastguard Worker                  const WideString& swText,
534*3ac0a46fSAndroid Build Coastguard Worker                  FX_Charset charset);
535*3ac0a46fSAndroid Build Coastguard Worker   ~UndoInsertText() override;
536*3ac0a46fSAndroid Build Coastguard Worker 
537*3ac0a46fSAndroid Build Coastguard Worker   // UndoItemIface:
538*3ac0a46fSAndroid Build Coastguard Worker   int Redo() override;
539*3ac0a46fSAndroid Build Coastguard Worker   int Undo() override;
540*3ac0a46fSAndroid Build Coastguard Worker 
541*3ac0a46fSAndroid Build Coastguard Worker  private:
542*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<CPWL_EditImpl> m_pEdit;
543*3ac0a46fSAndroid Build Coastguard Worker 
544*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpOld;
545*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace m_wpNew;
546*3ac0a46fSAndroid Build Coastguard Worker   WideString m_swText;
547*3ac0a46fSAndroid Build Coastguard Worker   FX_Charset m_nCharset;
548*3ac0a46fSAndroid Build Coastguard Worker };
549*3ac0a46fSAndroid Build Coastguard Worker 
UndoInsertText(CPWL_EditImpl * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const WideString & swText,FX_Charset charset)550*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertText::UndoInsertText(CPWL_EditImpl* pEdit,
551*3ac0a46fSAndroid Build Coastguard Worker                                               const CPVT_WordPlace& wpOldPlace,
552*3ac0a46fSAndroid Build Coastguard Worker                                               const CPVT_WordPlace& wpNewPlace,
553*3ac0a46fSAndroid Build Coastguard Worker                                               const WideString& swText,
554*3ac0a46fSAndroid Build Coastguard Worker                                               FX_Charset charset)
555*3ac0a46fSAndroid Build Coastguard Worker     : m_pEdit(pEdit),
556*3ac0a46fSAndroid Build Coastguard Worker       m_wpOld(wpOldPlace),
557*3ac0a46fSAndroid Build Coastguard Worker       m_wpNew(wpNewPlace),
558*3ac0a46fSAndroid Build Coastguard Worker       m_swText(swText),
559*3ac0a46fSAndroid Build Coastguard Worker       m_nCharset(charset) {
560*3ac0a46fSAndroid Build Coastguard Worker   DCHECK(m_pEdit);
561*3ac0a46fSAndroid Build Coastguard Worker }
562*3ac0a46fSAndroid Build Coastguard Worker 
563*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::UndoInsertText::~UndoInsertText() = default;
564*3ac0a46fSAndroid Build Coastguard Worker 
Redo()565*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertText::Redo() {
566*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
567*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetCaret(m_wpOld);
568*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->InsertText(m_swText, m_nCharset, false);
569*3ac0a46fSAndroid Build Coastguard Worker   return 0;
570*3ac0a46fSAndroid Build Coastguard Worker }
571*3ac0a46fSAndroid Build Coastguard Worker 
Undo()572*3ac0a46fSAndroid Build Coastguard Worker int CPWL_EditImpl::UndoInsertText::Undo() {
573*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectNone();
574*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetSelection(m_wpOld, m_wpNew);
575*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Clear(false);
576*3ac0a46fSAndroid Build Coastguard Worker   return 0;
577*3ac0a46fSAndroid Build Coastguard Worker }
578*3ac0a46fSAndroid Build Coastguard Worker 
DrawEdit(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,FX_COLORREF crTextFill,const CFX_FloatRect & rcClip,const CFX_PointF & ptOffset,const CPVT_WordRange * pRange,IPWL_FillerNotify * pFillerNotify,IPWL_FillerNotify::PerWindowData * pSystemData)579*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
580*3ac0a46fSAndroid Build Coastguard Worker                              const CFX_Matrix& mtUser2Device,
581*3ac0a46fSAndroid Build Coastguard Worker                              FX_COLORREF crTextFill,
582*3ac0a46fSAndroid Build Coastguard Worker                              const CFX_FloatRect& rcClip,
583*3ac0a46fSAndroid Build Coastguard Worker                              const CFX_PointF& ptOffset,
584*3ac0a46fSAndroid Build Coastguard Worker                              const CPVT_WordRange* pRange,
585*3ac0a46fSAndroid Build Coastguard Worker                              IPWL_FillerNotify* pFillerNotify,
586*3ac0a46fSAndroid Build Coastguard Worker                              IPWL_FillerNotify::PerWindowData* pSystemData) {
587*3ac0a46fSAndroid Build Coastguard Worker   const bool bContinuous = GetCharArray() == 0;
588*3ac0a46fSAndroid Build Coastguard Worker   uint16_t SubWord = GetPasswordChar();
589*3ac0a46fSAndroid Build Coastguard Worker   float fFontSize = GetFontSize();
590*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordRange wrSelect = GetSelectWordRange();
591*3ac0a46fSAndroid Build Coastguard Worker   FX_COLORREF crCurFill = crTextFill;
592*3ac0a46fSAndroid Build Coastguard Worker   FX_COLORREF crOldFill = crCurFill;
593*3ac0a46fSAndroid Build Coastguard Worker   bool bSelect = false;
594*3ac0a46fSAndroid Build Coastguard Worker   const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
595*3ac0a46fSAndroid Build Coastguard Worker   const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
596*3ac0a46fSAndroid Build Coastguard Worker 
597*3ac0a46fSAndroid Build Coastguard Worker   int32_t nFontIndex = -1;
598*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptBT;
599*3ac0a46fSAndroid Build Coastguard Worker   CFX_RenderDevice::StateRestorer restorer(pDevice);
600*3ac0a46fSAndroid Build Coastguard Worker   if (!rcClip.IsEmpty())
601*3ac0a46fSAndroid Build Coastguard Worker     pDevice->SetClip_Rect(mtUser2Device.TransformRect(rcClip).ToFxRect());
602*3ac0a46fSAndroid Build Coastguard Worker 
603*3ac0a46fSAndroid Build Coastguard Worker   Iterator* pIterator = GetIterator();
604*3ac0a46fSAndroid Build Coastguard Worker   IPVT_FontMap* pFontMap = GetFontMap();
605*3ac0a46fSAndroid Build Coastguard Worker   if (!pFontMap)
606*3ac0a46fSAndroid Build Coastguard Worker     return;
607*3ac0a46fSAndroid Build Coastguard Worker 
608*3ac0a46fSAndroid Build Coastguard Worker   if (pRange)
609*3ac0a46fSAndroid Build Coastguard Worker     pIterator->SetAt(pRange->BeginPos);
610*3ac0a46fSAndroid Build Coastguard Worker   else
611*3ac0a46fSAndroid Build Coastguard Worker     pIterator->SetAt(0);
612*3ac0a46fSAndroid Build Coastguard Worker 
613*3ac0a46fSAndroid Build Coastguard Worker   ByteString sTextBuf;
614*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace oldplace;
615*3ac0a46fSAndroid Build Coastguard Worker   while (pIterator->NextWord()) {
616*3ac0a46fSAndroid Build Coastguard Worker     CPVT_WordPlace place = pIterator->GetAt();
617*3ac0a46fSAndroid Build Coastguard Worker     if (pRange && place > pRange->EndPos)
618*3ac0a46fSAndroid Build Coastguard Worker       break;
619*3ac0a46fSAndroid Build Coastguard Worker 
620*3ac0a46fSAndroid Build Coastguard Worker     if (!wrSelect.IsEmpty()) {
621*3ac0a46fSAndroid Build Coastguard Worker       bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
622*3ac0a46fSAndroid Build Coastguard Worker       crCurFill = bSelect ? crWhite : crTextFill;
623*3ac0a46fSAndroid Build Coastguard Worker     }
624*3ac0a46fSAndroid Build Coastguard Worker     if (pFillerNotify->IsSelectionImplemented()) {
625*3ac0a46fSAndroid Build Coastguard Worker       crCurFill = crTextFill;
626*3ac0a46fSAndroid Build Coastguard Worker       crOldFill = crCurFill;
627*3ac0a46fSAndroid Build Coastguard Worker     }
628*3ac0a46fSAndroid Build Coastguard Worker     CPVT_Word word;
629*3ac0a46fSAndroid Build Coastguard Worker     if (pIterator->GetWord(word)) {
630*3ac0a46fSAndroid Build Coastguard Worker       if (bSelect) {
631*3ac0a46fSAndroid Build Coastguard Worker         CPVT_Line line;
632*3ac0a46fSAndroid Build Coastguard Worker         pIterator->GetLine(line);
633*3ac0a46fSAndroid Build Coastguard Worker         if (pFillerNotify->IsSelectionImplemented()) {
634*3ac0a46fSAndroid Build Coastguard Worker           CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
635*3ac0a46fSAndroid Build Coastguard Worker                            word.ptWord.x + word.fWidth,
636*3ac0a46fSAndroid Build Coastguard Worker                            line.ptLine.y + line.fLineAscent);
637*3ac0a46fSAndroid Build Coastguard Worker           rc.Intersect(rcClip);
638*3ac0a46fSAndroid Build Coastguard Worker           pFillerNotify->OutputSelectedRect(pSystemData, rc);
639*3ac0a46fSAndroid Build Coastguard Worker         } else {
640*3ac0a46fSAndroid Build Coastguard Worker           CFX_Path pathSelBK;
641*3ac0a46fSAndroid Build Coastguard Worker           pathSelBK.AppendRect(word.ptWord.x, line.ptLine.y + line.fLineDescent,
642*3ac0a46fSAndroid Build Coastguard Worker                                word.ptWord.x + word.fWidth,
643*3ac0a46fSAndroid Build Coastguard Worker                                line.ptLine.y + line.fLineAscent);
644*3ac0a46fSAndroid Build Coastguard Worker 
645*3ac0a46fSAndroid Build Coastguard Worker           pDevice->DrawPath(pathSelBK, &mtUser2Device, nullptr, crSelBK, 0,
646*3ac0a46fSAndroid Build Coastguard Worker                             CFX_FillRenderOptions::WindingOptions());
647*3ac0a46fSAndroid Build Coastguard Worker         }
648*3ac0a46fSAndroid Build Coastguard Worker       }
649*3ac0a46fSAndroid Build Coastguard Worker       if (bContinuous) {
650*3ac0a46fSAndroid Build Coastguard Worker         if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
651*3ac0a46fSAndroid Build Coastguard Worker             crOldFill != crCurFill) {
652*3ac0a46fSAndroid Build Coastguard Worker           if (!sTextBuf.IsEmpty()) {
653*3ac0a46fSAndroid Build Coastguard Worker             DrawTextString(pDevice,
654*3ac0a46fSAndroid Build Coastguard Worker                            CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
655*3ac0a46fSAndroid Build Coastguard Worker                            pFontMap->GetPDFFont(nFontIndex).Get(), fFontSize,
656*3ac0a46fSAndroid Build Coastguard Worker                            mtUser2Device, sTextBuf, crOldFill);
657*3ac0a46fSAndroid Build Coastguard Worker             sTextBuf.clear();
658*3ac0a46fSAndroid Build Coastguard Worker           }
659*3ac0a46fSAndroid Build Coastguard Worker           nFontIndex = word.nFontIndex;
660*3ac0a46fSAndroid Build Coastguard Worker           ptBT = word.ptWord;
661*3ac0a46fSAndroid Build Coastguard Worker           crOldFill = crCurFill;
662*3ac0a46fSAndroid Build Coastguard Worker         }
663*3ac0a46fSAndroid Build Coastguard Worker         sTextBuf += GetPDFWordString(word.nFontIndex, word.Word, SubWord);
664*3ac0a46fSAndroid Build Coastguard Worker       } else {
665*3ac0a46fSAndroid Build Coastguard Worker         DrawTextString(
666*3ac0a46fSAndroid Build Coastguard Worker             pDevice,
667*3ac0a46fSAndroid Build Coastguard Worker             CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y),
668*3ac0a46fSAndroid Build Coastguard Worker             pFontMap->GetPDFFont(word.nFontIndex).Get(), fFontSize,
669*3ac0a46fSAndroid Build Coastguard Worker             mtUser2Device,
670*3ac0a46fSAndroid Build Coastguard Worker             GetPDFWordString(word.nFontIndex, word.Word, SubWord), crCurFill);
671*3ac0a46fSAndroid Build Coastguard Worker       }
672*3ac0a46fSAndroid Build Coastguard Worker       oldplace = place;
673*3ac0a46fSAndroid Build Coastguard Worker     }
674*3ac0a46fSAndroid Build Coastguard Worker   }
675*3ac0a46fSAndroid Build Coastguard Worker   if (!sTextBuf.IsEmpty()) {
676*3ac0a46fSAndroid Build Coastguard Worker     DrawTextString(pDevice,
677*3ac0a46fSAndroid Build Coastguard Worker                    CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
678*3ac0a46fSAndroid Build Coastguard Worker                    pFontMap->GetPDFFont(nFontIndex).Get(), fFontSize,
679*3ac0a46fSAndroid Build Coastguard Worker                    mtUser2Device, sTextBuf, crOldFill);
680*3ac0a46fSAndroid Build Coastguard Worker   }
681*3ac0a46fSAndroid Build Coastguard Worker }
682*3ac0a46fSAndroid Build Coastguard Worker 
CPWL_EditImpl()683*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::CPWL_EditImpl()
684*3ac0a46fSAndroid Build Coastguard Worker     : m_pVT(std::make_unique<CPVT_VariableText>(nullptr)) {}
685*3ac0a46fSAndroid Build Coastguard Worker 
686*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::~CPWL_EditImpl() = default;
687*3ac0a46fSAndroid Build Coastguard Worker 
Initialize()688*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::Initialize() {
689*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->Initialize();
690*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->GetBeginWordPlace());
691*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
692*3ac0a46fSAndroid Build Coastguard Worker }
693*3ac0a46fSAndroid Build Coastguard Worker 
SetFontMap(IPVT_FontMap * pFontMap)694*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
695*3ac0a46fSAndroid Build Coastguard Worker   m_pVTProvider = std::make_unique<Provider>(pFontMap);
696*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetProvider(m_pVTProvider.get());
697*3ac0a46fSAndroid Build Coastguard Worker }
698*3ac0a46fSAndroid Build Coastguard Worker 
SetNotify(CPWL_Edit * pNotify)699*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetNotify(CPWL_Edit* pNotify) {
700*3ac0a46fSAndroid Build Coastguard Worker   m_pNotify = pNotify;
701*3ac0a46fSAndroid Build Coastguard Worker }
702*3ac0a46fSAndroid Build Coastguard Worker 
GetIterator()703*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::Iterator* CPWL_EditImpl::GetIterator() {
704*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pIterator)
705*3ac0a46fSAndroid Build Coastguard Worker     m_pIterator = std::make_unique<Iterator>(this, m_pVT->GetIterator());
706*3ac0a46fSAndroid Build Coastguard Worker   return m_pIterator.get();
707*3ac0a46fSAndroid Build Coastguard Worker }
708*3ac0a46fSAndroid Build Coastguard Worker 
GetFontMap()709*3ac0a46fSAndroid Build Coastguard Worker IPVT_FontMap* CPWL_EditImpl::GetFontMap() {
710*3ac0a46fSAndroid Build Coastguard Worker   return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
711*3ac0a46fSAndroid Build Coastguard Worker }
712*3ac0a46fSAndroid Build Coastguard Worker 
SetPlateRect(const CFX_FloatRect & rect)713*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) {
714*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetPlateRect(rect);
715*3ac0a46fSAndroid Build Coastguard Worker   m_ptScrollPos = CFX_PointF(rect.left, rect.top);
716*3ac0a46fSAndroid Build Coastguard Worker }
717*3ac0a46fSAndroid Build Coastguard Worker 
SetAlignmentH(int32_t nFormat)718*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetAlignmentH(int32_t nFormat) {
719*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetAlignment(nFormat);
720*3ac0a46fSAndroid Build Coastguard Worker }
721*3ac0a46fSAndroid Build Coastguard Worker 
SetAlignmentV(int32_t nFormat)722*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetAlignmentV(int32_t nFormat) {
723*3ac0a46fSAndroid Build Coastguard Worker   m_nAlignment = nFormat;
724*3ac0a46fSAndroid Build Coastguard Worker }
725*3ac0a46fSAndroid Build Coastguard Worker 
SetPasswordChar(uint16_t wSubWord)726*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord) {
727*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetPasswordChar(wSubWord);
728*3ac0a46fSAndroid Build Coastguard Worker }
729*3ac0a46fSAndroid Build Coastguard Worker 
SetLimitChar(int32_t nLimitChar)730*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) {
731*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetLimitChar(nLimitChar);
732*3ac0a46fSAndroid Build Coastguard Worker }
733*3ac0a46fSAndroid Build Coastguard Worker 
SetCharArray(int32_t nCharArray)734*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetCharArray(int32_t nCharArray) {
735*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetCharArray(nCharArray);
736*3ac0a46fSAndroid Build Coastguard Worker }
737*3ac0a46fSAndroid Build Coastguard Worker 
SetMultiLine(bool bMultiLine)738*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetMultiLine(bool bMultiLine) {
739*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetMultiLine(bMultiLine);
740*3ac0a46fSAndroid Build Coastguard Worker }
741*3ac0a46fSAndroid Build Coastguard Worker 
SetAutoReturn(bool bAuto)742*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetAutoReturn(bool bAuto) {
743*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetAutoReturn(bAuto);
744*3ac0a46fSAndroid Build Coastguard Worker }
745*3ac0a46fSAndroid Build Coastguard Worker 
SetAutoFontSize(bool bAuto)746*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetAutoFontSize(bool bAuto) {
747*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetAutoFontSize(bAuto);
748*3ac0a46fSAndroid Build Coastguard Worker }
749*3ac0a46fSAndroid Build Coastguard Worker 
SetFontSize(float fFontSize)750*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetFontSize(float fFontSize) {
751*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->SetFontSize(fFontSize);
752*3ac0a46fSAndroid Build Coastguard Worker }
753*3ac0a46fSAndroid Build Coastguard Worker 
SetAutoScroll(bool bAuto)754*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetAutoScroll(bool bAuto) {
755*3ac0a46fSAndroid Build Coastguard Worker   m_bEnableScroll = bAuto;
756*3ac0a46fSAndroid Build Coastguard Worker }
757*3ac0a46fSAndroid Build Coastguard Worker 
SetTextOverflow(bool bAllowed)758*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetTextOverflow(bool bAllowed) {
759*3ac0a46fSAndroid Build Coastguard Worker   m_bEnableOverflow = bAllowed;
760*3ac0a46fSAndroid Build Coastguard Worker }
761*3ac0a46fSAndroid Build Coastguard Worker 
SetSelection(int32_t nStartChar,int32_t nEndChar)762*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) {
763*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
764*3ac0a46fSAndroid Build Coastguard Worker     if (nStartChar == 0 && nEndChar < 0) {
765*3ac0a46fSAndroid Build Coastguard Worker       SelectAll();
766*3ac0a46fSAndroid Build Coastguard Worker     } else if (nStartChar < 0) {
767*3ac0a46fSAndroid Build Coastguard Worker       SelectNone();
768*3ac0a46fSAndroid Build Coastguard Worker     } else {
769*3ac0a46fSAndroid Build Coastguard Worker       if (nStartChar < nEndChar) {
770*3ac0a46fSAndroid Build Coastguard Worker         SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
771*3ac0a46fSAndroid Build Coastguard Worker                      m_pVT->WordIndexToWordPlace(nEndChar));
772*3ac0a46fSAndroid Build Coastguard Worker       } else {
773*3ac0a46fSAndroid Build Coastguard Worker         SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
774*3ac0a46fSAndroid Build Coastguard Worker                      m_pVT->WordIndexToWordPlace(nStartChar));
775*3ac0a46fSAndroid Build Coastguard Worker       }
776*3ac0a46fSAndroid Build Coastguard Worker     }
777*3ac0a46fSAndroid Build Coastguard Worker   }
778*3ac0a46fSAndroid Build Coastguard Worker }
779*3ac0a46fSAndroid Build Coastguard Worker 
SetSelection(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)780*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin,
781*3ac0a46fSAndroid Build Coastguard Worker                                  const CPVT_WordPlace& end) {
782*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
783*3ac0a46fSAndroid Build Coastguard Worker     return;
784*3ac0a46fSAndroid Build Coastguard Worker 
785*3ac0a46fSAndroid Build Coastguard Worker   SelectNone();
786*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(begin, end);
787*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_SelState.EndPos);
788*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
789*3ac0a46fSAndroid Build Coastguard Worker   if (!m_SelState.IsEmpty())
790*3ac0a46fSAndroid Build Coastguard Worker     Refresh();
791*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
792*3ac0a46fSAndroid Build Coastguard Worker }
793*3ac0a46fSAndroid Build Coastguard Worker 
GetSelection() const794*3ac0a46fSAndroid Build Coastguard Worker std::pair<int32_t, int32_t> CPWL_EditImpl::GetSelection() const {
795*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
796*3ac0a46fSAndroid Build Coastguard Worker     return std::make_pair(-1, -1);
797*3ac0a46fSAndroid Build Coastguard Worker 
798*3ac0a46fSAndroid Build Coastguard Worker   if (m_SelState.IsEmpty()) {
799*3ac0a46fSAndroid Build Coastguard Worker     return std::make_pair(m_pVT->WordPlaceToWordIndex(m_wpCaret),
800*3ac0a46fSAndroid Build Coastguard Worker                           m_pVT->WordPlaceToWordIndex(m_wpCaret));
801*3ac0a46fSAndroid Build Coastguard Worker   }
802*3ac0a46fSAndroid Build Coastguard Worker   if (m_SelState.BeginPos < m_SelState.EndPos) {
803*3ac0a46fSAndroid Build Coastguard Worker     return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos),
804*3ac0a46fSAndroid Build Coastguard Worker                           m_pVT->WordPlaceToWordIndex(m_SelState.EndPos));
805*3ac0a46fSAndroid Build Coastguard Worker   }
806*3ac0a46fSAndroid Build Coastguard Worker   return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.EndPos),
807*3ac0a46fSAndroid Build Coastguard Worker                         m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos));
808*3ac0a46fSAndroid Build Coastguard Worker }
809*3ac0a46fSAndroid Build Coastguard Worker 
GetCaret() const810*3ac0a46fSAndroid Build Coastguard Worker int32_t CPWL_EditImpl::GetCaret() const {
811*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid())
812*3ac0a46fSAndroid Build Coastguard Worker     return m_pVT->WordPlaceToWordIndex(m_wpCaret);
813*3ac0a46fSAndroid Build Coastguard Worker 
814*3ac0a46fSAndroid Build Coastguard Worker   return -1;
815*3ac0a46fSAndroid Build Coastguard Worker }
816*3ac0a46fSAndroid Build Coastguard Worker 
GetCaretWordPlace() const817*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const {
818*3ac0a46fSAndroid Build Coastguard Worker   return m_wpCaret;
819*3ac0a46fSAndroid Build Coastguard Worker }
820*3ac0a46fSAndroid Build Coastguard Worker 
GetText() const821*3ac0a46fSAndroid Build Coastguard Worker WideString CPWL_EditImpl::GetText() const {
822*3ac0a46fSAndroid Build Coastguard Worker   WideString swRet;
823*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
824*3ac0a46fSAndroid Build Coastguard Worker     return swRet;
825*3ac0a46fSAndroid Build Coastguard Worker 
826*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
827*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(0);
828*3ac0a46fSAndroid Build Coastguard Worker 
829*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word wordinfo;
830*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace oldplace = pIterator->GetWordPlace();
831*3ac0a46fSAndroid Build Coastguard Worker   while (pIterator->NextWord()) {
832*3ac0a46fSAndroid Build Coastguard Worker     CPVT_WordPlace place = pIterator->GetWordPlace();
833*3ac0a46fSAndroid Build Coastguard Worker     if (pIterator->GetWord(wordinfo))
834*3ac0a46fSAndroid Build Coastguard Worker       swRet += wordinfo.Word;
835*3ac0a46fSAndroid Build Coastguard Worker     if (oldplace.nSecIndex != place.nSecIndex)
836*3ac0a46fSAndroid Build Coastguard Worker       swRet += L"\r\n";
837*3ac0a46fSAndroid Build Coastguard Worker     oldplace = place;
838*3ac0a46fSAndroid Build Coastguard Worker   }
839*3ac0a46fSAndroid Build Coastguard Worker   return swRet;
840*3ac0a46fSAndroid Build Coastguard Worker }
841*3ac0a46fSAndroid Build Coastguard Worker 
GetRangeText(const CPVT_WordRange & range) const842*3ac0a46fSAndroid Build Coastguard Worker WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
843*3ac0a46fSAndroid Build Coastguard Worker   WideString swRet;
844*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
845*3ac0a46fSAndroid Build Coastguard Worker     return swRet;
846*3ac0a46fSAndroid Build Coastguard Worker 
847*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
848*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordRange wrTemp = range;
849*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wrTemp.BeginPos);
850*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wrTemp.EndPos);
851*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(wrTemp.BeginPos);
852*3ac0a46fSAndroid Build Coastguard Worker 
853*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word wordinfo;
854*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace oldplace = wrTemp.BeginPos;
855*3ac0a46fSAndroid Build Coastguard Worker   while (pIterator->NextWord()) {
856*3ac0a46fSAndroid Build Coastguard Worker     CPVT_WordPlace place = pIterator->GetWordPlace();
857*3ac0a46fSAndroid Build Coastguard Worker     if (place > wrTemp.EndPos)
858*3ac0a46fSAndroid Build Coastguard Worker       break;
859*3ac0a46fSAndroid Build Coastguard Worker     if (pIterator->GetWord(wordinfo))
860*3ac0a46fSAndroid Build Coastguard Worker       swRet += wordinfo.Word;
861*3ac0a46fSAndroid Build Coastguard Worker     if (oldplace.nSecIndex != place.nSecIndex)
862*3ac0a46fSAndroid Build Coastguard Worker       swRet += L"\r\n";
863*3ac0a46fSAndroid Build Coastguard Worker     oldplace = place;
864*3ac0a46fSAndroid Build Coastguard Worker   }
865*3ac0a46fSAndroid Build Coastguard Worker   return swRet;
866*3ac0a46fSAndroid Build Coastguard Worker }
867*3ac0a46fSAndroid Build Coastguard Worker 
GetSelectedText() const868*3ac0a46fSAndroid Build Coastguard Worker WideString CPWL_EditImpl::GetSelectedText() const {
869*3ac0a46fSAndroid Build Coastguard Worker   return GetRangeText(m_SelState.ConvertToWordRange());
870*3ac0a46fSAndroid Build Coastguard Worker }
871*3ac0a46fSAndroid Build Coastguard Worker 
GetTotalLines() const872*3ac0a46fSAndroid Build Coastguard Worker int32_t CPWL_EditImpl::GetTotalLines() const {
873*3ac0a46fSAndroid Build Coastguard Worker   int32_t nLines = 1;
874*3ac0a46fSAndroid Build Coastguard Worker 
875*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
876*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(0);
877*3ac0a46fSAndroid Build Coastguard Worker   while (pIterator->NextLine())
878*3ac0a46fSAndroid Build Coastguard Worker     ++nLines;
879*3ac0a46fSAndroid Build Coastguard Worker 
880*3ac0a46fSAndroid Build Coastguard Worker   return nLines;
881*3ac0a46fSAndroid Build Coastguard Worker }
882*3ac0a46fSAndroid Build Coastguard Worker 
GetSelectWordRange() const883*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const {
884*3ac0a46fSAndroid Build Coastguard Worker   return m_SelState.ConvertToWordRange();
885*3ac0a46fSAndroid Build Coastguard Worker }
886*3ac0a46fSAndroid Build Coastguard Worker 
SetText(const WideString & sText)887*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetText(const WideString& sText) {
888*3ac0a46fSAndroid Build Coastguard Worker   Clear();
889*3ac0a46fSAndroid Build Coastguard Worker   DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_Charset::kDefault);
890*3ac0a46fSAndroid Build Coastguard Worker }
891*3ac0a46fSAndroid Build Coastguard Worker 
InsertWord(uint16_t word,FX_Charset charset)892*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertWord(uint16_t word, FX_Charset charset) {
893*3ac0a46fSAndroid Build Coastguard Worker   return InsertWord(word, charset, true);
894*3ac0a46fSAndroid Build Coastguard Worker }
895*3ac0a46fSAndroid Build Coastguard Worker 
InsertReturn()896*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertReturn() {
897*3ac0a46fSAndroid Build Coastguard Worker   return InsertReturn(true);
898*3ac0a46fSAndroid Build Coastguard Worker }
899*3ac0a46fSAndroid Build Coastguard Worker 
Backspace()900*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Backspace() {
901*3ac0a46fSAndroid Build Coastguard Worker   return Backspace(true);
902*3ac0a46fSAndroid Build Coastguard Worker }
903*3ac0a46fSAndroid Build Coastguard Worker 
Delete()904*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Delete() {
905*3ac0a46fSAndroid Build Coastguard Worker   return Delete(true);
906*3ac0a46fSAndroid Build Coastguard Worker }
907*3ac0a46fSAndroid Build Coastguard Worker 
ClearSelection()908*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::ClearSelection() {
909*3ac0a46fSAndroid Build Coastguard Worker   return Clear(true);
910*3ac0a46fSAndroid Build Coastguard Worker }
911*3ac0a46fSAndroid Build Coastguard Worker 
InsertText(const WideString & sText,FX_Charset charset)912*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertText(const WideString& sText, FX_Charset charset) {
913*3ac0a46fSAndroid Build Coastguard Worker   return InsertText(sText, charset, true);
914*3ac0a46fSAndroid Build Coastguard Worker }
915*3ac0a46fSAndroid Build Coastguard Worker 
GetFontSize() const916*3ac0a46fSAndroid Build Coastguard Worker float CPWL_EditImpl::GetFontSize() const {
917*3ac0a46fSAndroid Build Coastguard Worker   return m_pVT->GetFontSize();
918*3ac0a46fSAndroid Build Coastguard Worker }
919*3ac0a46fSAndroid Build Coastguard Worker 
GetPasswordChar() const920*3ac0a46fSAndroid Build Coastguard Worker uint16_t CPWL_EditImpl::GetPasswordChar() const {
921*3ac0a46fSAndroid Build Coastguard Worker   return m_pVT->GetPasswordChar();
922*3ac0a46fSAndroid Build Coastguard Worker }
923*3ac0a46fSAndroid Build Coastguard Worker 
GetCharArray() const924*3ac0a46fSAndroid Build Coastguard Worker int32_t CPWL_EditImpl::GetCharArray() const {
925*3ac0a46fSAndroid Build Coastguard Worker   return m_pVT->GetCharArray();
926*3ac0a46fSAndroid Build Coastguard Worker }
927*3ac0a46fSAndroid Build Coastguard Worker 
GetContentRect() const928*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect CPWL_EditImpl::GetContentRect() const {
929*3ac0a46fSAndroid Build Coastguard Worker   return VTToEdit(m_pVT->GetContentRect());
930*3ac0a46fSAndroid Build Coastguard Worker }
931*3ac0a46fSAndroid Build Coastguard Worker 
GetWholeWordRange() const932*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const {
933*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid())
934*3ac0a46fSAndroid Build Coastguard Worker     return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
935*3ac0a46fSAndroid Build Coastguard Worker 
936*3ac0a46fSAndroid Build Coastguard Worker   return CPVT_WordRange();
937*3ac0a46fSAndroid Build Coastguard Worker }
938*3ac0a46fSAndroid Build Coastguard Worker 
GetVisibleWordRange() const939*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const {
940*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableOverflow)
941*3ac0a46fSAndroid Build Coastguard Worker     return GetWholeWordRange();
942*3ac0a46fSAndroid Build Coastguard Worker 
943*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
944*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
945*3ac0a46fSAndroid Build Coastguard Worker 
946*3ac0a46fSAndroid Build Coastguard Worker     CPVT_WordPlace place1 =
947*3ac0a46fSAndroid Build Coastguard Worker         m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
948*3ac0a46fSAndroid Build Coastguard Worker     CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
949*3ac0a46fSAndroid Build Coastguard Worker         EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
950*3ac0a46fSAndroid Build Coastguard Worker 
951*3ac0a46fSAndroid Build Coastguard Worker     return CPVT_WordRange(place1, place2);
952*3ac0a46fSAndroid Build Coastguard Worker   }
953*3ac0a46fSAndroid Build Coastguard Worker 
954*3ac0a46fSAndroid Build Coastguard Worker   return CPVT_WordRange();
955*3ac0a46fSAndroid Build Coastguard Worker }
956*3ac0a46fSAndroid Build Coastguard Worker 
SearchWordPlace(const CFX_PointF & point) const957*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const {
958*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
959*3ac0a46fSAndroid Build Coastguard Worker     return m_pVT->SearchWordPlace(EditToVT(point));
960*3ac0a46fSAndroid Build Coastguard Worker   }
961*3ac0a46fSAndroid Build Coastguard Worker 
962*3ac0a46fSAndroid Build Coastguard Worker   return CPVT_WordPlace();
963*3ac0a46fSAndroid Build Coastguard Worker }
964*3ac0a46fSAndroid Build Coastguard Worker 
Paint()965*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::Paint() {
966*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
967*3ac0a46fSAndroid Build Coastguard Worker     RearrangeAll();
968*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
969*3ac0a46fSAndroid Build Coastguard Worker     Refresh();
970*3ac0a46fSAndroid Build Coastguard Worker     SetCaretOrigin();
971*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
972*3ac0a46fSAndroid Build Coastguard Worker   }
973*3ac0a46fSAndroid Build Coastguard Worker }
974*3ac0a46fSAndroid Build Coastguard Worker 
RearrangeAll()975*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RearrangeAll() {
976*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
977*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->UpdateWordPlace(m_wpCaret);
978*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->RearrangeAll();
979*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->UpdateWordPlace(m_wpCaret);
980*3ac0a46fSAndroid Build Coastguard Worker     SetScrollInfo();
981*3ac0a46fSAndroid Build Coastguard Worker     SetContentChanged();
982*3ac0a46fSAndroid Build Coastguard Worker   }
983*3ac0a46fSAndroid Build Coastguard Worker }
984*3ac0a46fSAndroid Build Coastguard Worker 
RearrangePart(const CPVT_WordRange & range)985*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) {
986*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
987*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->UpdateWordPlace(m_wpCaret);
988*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->RearrangePart(range);
989*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->UpdateWordPlace(m_wpCaret);
990*3ac0a46fSAndroid Build Coastguard Worker     SetScrollInfo();
991*3ac0a46fSAndroid Build Coastguard Worker     SetContentChanged();
992*3ac0a46fSAndroid Build Coastguard Worker   }
993*3ac0a46fSAndroid Build Coastguard Worker }
994*3ac0a46fSAndroid Build Coastguard Worker 
SetContentChanged()995*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetContentChanged() {
996*3ac0a46fSAndroid Build Coastguard Worker   if (m_pNotify) {
997*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcContent = m_pVT->GetContentRect();
998*3ac0a46fSAndroid Build Coastguard Worker     if (rcContent.Width() != m_rcOldContent.Width() ||
999*3ac0a46fSAndroid Build Coastguard Worker         rcContent.Height() != m_rcOldContent.Height()) {
1000*3ac0a46fSAndroid Build Coastguard Worker       m_rcOldContent = rcContent;
1001*3ac0a46fSAndroid Build Coastguard Worker     }
1002*3ac0a46fSAndroid Build Coastguard Worker   }
1003*3ac0a46fSAndroid Build Coastguard Worker }
1004*3ac0a46fSAndroid Build Coastguard Worker 
SelectAll()1005*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SelectAll() {
1006*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1007*3ac0a46fSAndroid Build Coastguard Worker     return;
1008*3ac0a46fSAndroid Build Coastguard Worker   m_SelState = SelectState(GetWholeWordRange());
1009*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_SelState.EndPos);
1010*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1011*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1012*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1013*3ac0a46fSAndroid Build Coastguard Worker }
1014*3ac0a46fSAndroid Build Coastguard Worker 
SelectNone()1015*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SelectNone() {
1016*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1017*3ac0a46fSAndroid Build Coastguard Worker     return;
1018*3ac0a46fSAndroid Build Coastguard Worker 
1019*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Reset();
1020*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1021*3ac0a46fSAndroid Build Coastguard Worker }
1022*3ac0a46fSAndroid Build Coastguard Worker 
IsSelected() const1023*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::IsSelected() const {
1024*3ac0a46fSAndroid Build Coastguard Worker   return !m_SelState.IsEmpty();
1025*3ac0a46fSAndroid Build Coastguard Worker }
1026*3ac0a46fSAndroid Build Coastguard Worker 
VTToEdit(const CFX_PointF & point) const1027*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const {
1028*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcContent = m_pVT->GetContentRect();
1029*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1030*3ac0a46fSAndroid Build Coastguard Worker 
1031*3ac0a46fSAndroid Build Coastguard Worker   float fPadding = 0.0f;
1032*3ac0a46fSAndroid Build Coastguard Worker 
1033*3ac0a46fSAndroid Build Coastguard Worker   switch (m_nAlignment) {
1034*3ac0a46fSAndroid Build Coastguard Worker     case 0:
1035*3ac0a46fSAndroid Build Coastguard Worker       fPadding = 0.0f;
1036*3ac0a46fSAndroid Build Coastguard Worker       break;
1037*3ac0a46fSAndroid Build Coastguard Worker     case 1:
1038*3ac0a46fSAndroid Build Coastguard Worker       fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1039*3ac0a46fSAndroid Build Coastguard Worker       break;
1040*3ac0a46fSAndroid Build Coastguard Worker     case 2:
1041*3ac0a46fSAndroid Build Coastguard Worker       fPadding = rcPlate.Height() - rcContent.Height();
1042*3ac0a46fSAndroid Build Coastguard Worker       break;
1043*3ac0a46fSAndroid Build Coastguard Worker   }
1044*3ac0a46fSAndroid Build Coastguard Worker 
1045*3ac0a46fSAndroid Build Coastguard Worker   return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1046*3ac0a46fSAndroid Build Coastguard Worker                     point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
1047*3ac0a46fSAndroid Build Coastguard Worker }
1048*3ac0a46fSAndroid Build Coastguard Worker 
EditToVT(const CFX_PointF & point) const1049*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const {
1050*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcContent = m_pVT->GetContentRect();
1051*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1052*3ac0a46fSAndroid Build Coastguard Worker 
1053*3ac0a46fSAndroid Build Coastguard Worker   float fPadding = 0.0f;
1054*3ac0a46fSAndroid Build Coastguard Worker 
1055*3ac0a46fSAndroid Build Coastguard Worker   switch (m_nAlignment) {
1056*3ac0a46fSAndroid Build Coastguard Worker     case 0:
1057*3ac0a46fSAndroid Build Coastguard Worker       fPadding = 0.0f;
1058*3ac0a46fSAndroid Build Coastguard Worker       break;
1059*3ac0a46fSAndroid Build Coastguard Worker     case 1:
1060*3ac0a46fSAndroid Build Coastguard Worker       fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1061*3ac0a46fSAndroid Build Coastguard Worker       break;
1062*3ac0a46fSAndroid Build Coastguard Worker     case 2:
1063*3ac0a46fSAndroid Build Coastguard Worker       fPadding = rcPlate.Height() - rcContent.Height();
1064*3ac0a46fSAndroid Build Coastguard Worker       break;
1065*3ac0a46fSAndroid Build Coastguard Worker   }
1066*3ac0a46fSAndroid Build Coastguard Worker 
1067*3ac0a46fSAndroid Build Coastguard Worker   return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1068*3ac0a46fSAndroid Build Coastguard Worker                     point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
1069*3ac0a46fSAndroid Build Coastguard Worker }
1070*3ac0a46fSAndroid Build Coastguard Worker 
VTToEdit(const CFX_FloatRect & rect) const1071*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const {
1072*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1073*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
1074*3ac0a46fSAndroid Build Coastguard Worker 
1075*3ac0a46fSAndroid Build Coastguard Worker   return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1076*3ac0a46fSAndroid Build Coastguard Worker                        ptRightTop.y);
1077*3ac0a46fSAndroid Build Coastguard Worker }
1078*3ac0a46fSAndroid Build Coastguard Worker 
SetScrollInfo()1079*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetScrollInfo() {
1080*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pNotify)
1081*3ac0a46fSAndroid Build Coastguard Worker     return;
1082*3ac0a46fSAndroid Build Coastguard Worker 
1083*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1084*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcContent = m_pVT->GetContentRect();
1085*3ac0a46fSAndroid Build Coastguard Worker   if (m_bNotifyFlag)
1086*3ac0a46fSAndroid Build Coastguard Worker     return;
1087*3ac0a46fSAndroid Build Coastguard Worker 
1088*3ac0a46fSAndroid Build Coastguard Worker   AutoRestorer<bool> restorer(&m_bNotifyFlag);
1089*3ac0a46fSAndroid Build Coastguard Worker   m_bNotifyFlag = true;
1090*3ac0a46fSAndroid Build Coastguard Worker 
1091*3ac0a46fSAndroid Build Coastguard Worker   PWL_SCROLL_INFO Info;
1092*3ac0a46fSAndroid Build Coastguard Worker   Info.fPlateWidth = rcPlate.top - rcPlate.bottom;
1093*3ac0a46fSAndroid Build Coastguard Worker   Info.fContentMin = rcContent.bottom;
1094*3ac0a46fSAndroid Build Coastguard Worker   Info.fContentMax = rcContent.top;
1095*3ac0a46fSAndroid Build Coastguard Worker   Info.fSmallStep = rcPlate.Height() / 3;
1096*3ac0a46fSAndroid Build Coastguard Worker   Info.fBigStep = rcPlate.Height();
1097*3ac0a46fSAndroid Build Coastguard Worker   m_pNotify->SetScrollInfo(Info);
1098*3ac0a46fSAndroid Build Coastguard Worker }
1099*3ac0a46fSAndroid Build Coastguard Worker 
SetScrollPosX(float fx)1100*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetScrollPosX(float fx) {
1101*3ac0a46fSAndroid Build Coastguard Worker   if (!m_bEnableScroll)
1102*3ac0a46fSAndroid Build Coastguard Worker     return;
1103*3ac0a46fSAndroid Build Coastguard Worker 
1104*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
1105*3ac0a46fSAndroid Build Coastguard Worker     if (!FXSYS_IsFloatEqual(m_ptScrollPos.x, fx)) {
1106*3ac0a46fSAndroid Build Coastguard Worker       m_ptScrollPos.x = fx;
1107*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1108*3ac0a46fSAndroid Build Coastguard Worker     }
1109*3ac0a46fSAndroid Build Coastguard Worker   }
1110*3ac0a46fSAndroid Build Coastguard Worker }
1111*3ac0a46fSAndroid Build Coastguard Worker 
SetScrollPosY(float fy)1112*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetScrollPosY(float fy) {
1113*3ac0a46fSAndroid Build Coastguard Worker   if (!m_bEnableScroll)
1114*3ac0a46fSAndroid Build Coastguard Worker     return;
1115*3ac0a46fSAndroid Build Coastguard Worker 
1116*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
1117*3ac0a46fSAndroid Build Coastguard Worker     if (!FXSYS_IsFloatEqual(m_ptScrollPos.y, fy)) {
1118*3ac0a46fSAndroid Build Coastguard Worker       m_ptScrollPos.y = fy;
1119*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1120*3ac0a46fSAndroid Build Coastguard Worker 
1121*3ac0a46fSAndroid Build Coastguard Worker       if (m_pNotify) {
1122*3ac0a46fSAndroid Build Coastguard Worker         if (!m_bNotifyFlag) {
1123*3ac0a46fSAndroid Build Coastguard Worker           AutoRestorer<bool> restorer(&m_bNotifyFlag);
1124*3ac0a46fSAndroid Build Coastguard Worker           m_bNotifyFlag = true;
1125*3ac0a46fSAndroid Build Coastguard Worker           m_pNotify->SetScrollPosition(fy);
1126*3ac0a46fSAndroid Build Coastguard Worker         }
1127*3ac0a46fSAndroid Build Coastguard Worker       }
1128*3ac0a46fSAndroid Build Coastguard Worker     }
1129*3ac0a46fSAndroid Build Coastguard Worker   }
1130*3ac0a46fSAndroid Build Coastguard Worker }
1131*3ac0a46fSAndroid Build Coastguard Worker 
SetScrollPos(const CFX_PointF & point)1132*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) {
1133*3ac0a46fSAndroid Build Coastguard Worker   SetScrollPosX(point.x);
1134*3ac0a46fSAndroid Build Coastguard Worker   SetScrollPosY(point.y);
1135*3ac0a46fSAndroid Build Coastguard Worker   SetScrollLimit();
1136*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1137*3ac0a46fSAndroid Build Coastguard Worker }
1138*3ac0a46fSAndroid Build Coastguard Worker 
GetScrollPos() const1139*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF CPWL_EditImpl::GetScrollPos() const {
1140*3ac0a46fSAndroid Build Coastguard Worker   return m_ptScrollPos;
1141*3ac0a46fSAndroid Build Coastguard Worker }
1142*3ac0a46fSAndroid Build Coastguard Worker 
SetScrollLimit()1143*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetScrollLimit() {
1144*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
1145*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcContent = m_pVT->GetContentRect();
1146*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1147*3ac0a46fSAndroid Build Coastguard Worker 
1148*3ac0a46fSAndroid Build Coastguard Worker     if (rcPlate.Width() > rcContent.Width()) {
1149*3ac0a46fSAndroid Build Coastguard Worker       SetScrollPosX(rcPlate.left);
1150*3ac0a46fSAndroid Build Coastguard Worker     } else {
1151*3ac0a46fSAndroid Build Coastguard Worker       if (FXSYS_IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
1152*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosX(rcContent.left);
1153*3ac0a46fSAndroid Build Coastguard Worker       } else if (FXSYS_IsFloatBigger(m_ptScrollPos.x,
1154*3ac0a46fSAndroid Build Coastguard Worker                                      rcContent.right - rcPlate.Width())) {
1155*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosX(rcContent.right - rcPlate.Width());
1156*3ac0a46fSAndroid Build Coastguard Worker       }
1157*3ac0a46fSAndroid Build Coastguard Worker     }
1158*3ac0a46fSAndroid Build Coastguard Worker 
1159*3ac0a46fSAndroid Build Coastguard Worker     if (rcPlate.Height() > rcContent.Height()) {
1160*3ac0a46fSAndroid Build Coastguard Worker       SetScrollPosY(rcPlate.top);
1161*3ac0a46fSAndroid Build Coastguard Worker     } else {
1162*3ac0a46fSAndroid Build Coastguard Worker       if (FXSYS_IsFloatSmaller(m_ptScrollPos.y,
1163*3ac0a46fSAndroid Build Coastguard Worker                                rcContent.bottom + rcPlate.Height())) {
1164*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosY(rcContent.bottom + rcPlate.Height());
1165*3ac0a46fSAndroid Build Coastguard Worker       } else if (FXSYS_IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
1166*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosY(rcContent.top);
1167*3ac0a46fSAndroid Build Coastguard Worker       }
1168*3ac0a46fSAndroid Build Coastguard Worker     }
1169*3ac0a46fSAndroid Build Coastguard Worker   }
1170*3ac0a46fSAndroid Build Coastguard Worker }
1171*3ac0a46fSAndroid Build Coastguard Worker 
ScrollToCaret()1172*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::ScrollToCaret() {
1173*3ac0a46fSAndroid Build Coastguard Worker   SetScrollLimit();
1174*3ac0a46fSAndroid Build Coastguard Worker 
1175*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1176*3ac0a46fSAndroid Build Coastguard Worker     return;
1177*3ac0a46fSAndroid Build Coastguard Worker 
1178*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1179*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(m_wpCaret);
1180*3ac0a46fSAndroid Build Coastguard Worker 
1181*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptHead;
1182*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptFoot;
1183*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word word;
1184*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Line line;
1185*3ac0a46fSAndroid Build Coastguard Worker   if (pIterator->GetWord(word)) {
1186*3ac0a46fSAndroid Build Coastguard Worker     ptHead.x = word.ptWord.x + word.fWidth;
1187*3ac0a46fSAndroid Build Coastguard Worker     ptHead.y = word.ptWord.y + word.fAscent;
1188*3ac0a46fSAndroid Build Coastguard Worker     ptFoot.x = word.ptWord.x + word.fWidth;
1189*3ac0a46fSAndroid Build Coastguard Worker     ptFoot.y = word.ptWord.y + word.fDescent;
1190*3ac0a46fSAndroid Build Coastguard Worker   } else if (pIterator->GetLine(line)) {
1191*3ac0a46fSAndroid Build Coastguard Worker     ptHead.x = line.ptLine.x;
1192*3ac0a46fSAndroid Build Coastguard Worker     ptHead.y = line.ptLine.y + line.fLineAscent;
1193*3ac0a46fSAndroid Build Coastguard Worker     ptFoot.x = line.ptLine.x;
1194*3ac0a46fSAndroid Build Coastguard Worker     ptFoot.y = line.ptLine.y + line.fLineDescent;
1195*3ac0a46fSAndroid Build Coastguard Worker   }
1196*3ac0a46fSAndroid Build Coastguard Worker 
1197*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1198*3ac0a46fSAndroid Build Coastguard Worker   CFX_PointF ptFootEdit = VTToEdit(ptFoot);
1199*3ac0a46fSAndroid Build Coastguard Worker   CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1200*3ac0a46fSAndroid Build Coastguard Worker   if (!FXSYS_IsFloatEqual(rcPlate.left, rcPlate.right)) {
1201*3ac0a46fSAndroid Build Coastguard Worker     if (FXSYS_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1202*3ac0a46fSAndroid Build Coastguard Worker         FXSYS_IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
1203*3ac0a46fSAndroid Build Coastguard Worker       SetScrollPosX(ptHead.x);
1204*3ac0a46fSAndroid Build Coastguard Worker     } else if (FXSYS_IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
1205*3ac0a46fSAndroid Build Coastguard Worker       SetScrollPosX(ptHead.x - rcPlate.Width());
1206*3ac0a46fSAndroid Build Coastguard Worker     }
1207*3ac0a46fSAndroid Build Coastguard Worker   }
1208*3ac0a46fSAndroid Build Coastguard Worker 
1209*3ac0a46fSAndroid Build Coastguard Worker   if (!FXSYS_IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1210*3ac0a46fSAndroid Build Coastguard Worker     if (FXSYS_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1211*3ac0a46fSAndroid Build Coastguard Worker         FXSYS_IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1212*3ac0a46fSAndroid Build Coastguard Worker       if (FXSYS_IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
1213*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosY(ptFoot.y + rcPlate.Height());
1214*3ac0a46fSAndroid Build Coastguard Worker       }
1215*3ac0a46fSAndroid Build Coastguard Worker     } else if (FXSYS_IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1216*3ac0a46fSAndroid Build Coastguard Worker       if (FXSYS_IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
1217*3ac0a46fSAndroid Build Coastguard Worker         SetScrollPosY(ptHead.y);
1218*3ac0a46fSAndroid Build Coastguard Worker       }
1219*3ac0a46fSAndroid Build Coastguard Worker     }
1220*3ac0a46fSAndroid Build Coastguard Worker   }
1221*3ac0a46fSAndroid Build Coastguard Worker }
1222*3ac0a46fSAndroid Build Coastguard Worker 
Refresh()1223*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::Refresh() {
1224*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableRefresh && m_pVT->IsValid()) {
1225*3ac0a46fSAndroid Build Coastguard Worker     m_Refresh.BeginRefresh();
1226*3ac0a46fSAndroid Build Coastguard Worker     RefreshPushLineRects(GetVisibleWordRange());
1227*3ac0a46fSAndroid Build Coastguard Worker 
1228*3ac0a46fSAndroid Build Coastguard Worker     m_Refresh.NoAnalyse();
1229*3ac0a46fSAndroid Build Coastguard Worker     m_ptRefreshScrollPos = m_ptScrollPos;
1230*3ac0a46fSAndroid Build Coastguard Worker 
1231*3ac0a46fSAndroid Build Coastguard Worker     if (m_pNotify) {
1232*3ac0a46fSAndroid Build Coastguard Worker       if (!m_bNotifyFlag) {
1233*3ac0a46fSAndroid Build Coastguard Worker         AutoRestorer<bool> restorer(&m_bNotifyFlag);
1234*3ac0a46fSAndroid Build Coastguard Worker         m_bNotifyFlag = true;
1235*3ac0a46fSAndroid Build Coastguard Worker         std::vector<CFX_FloatRect>* pRects = m_Refresh.GetRefreshRects();
1236*3ac0a46fSAndroid Build Coastguard Worker         for (auto& rect : *pRects) {
1237*3ac0a46fSAndroid Build Coastguard Worker           if (!m_pNotify->InvalidateRect(&rect)) {
1238*3ac0a46fSAndroid Build Coastguard Worker             m_pNotify = nullptr;  // Gone, dangling even.
1239*3ac0a46fSAndroid Build Coastguard Worker             break;
1240*3ac0a46fSAndroid Build Coastguard Worker           }
1241*3ac0a46fSAndroid Build Coastguard Worker         }
1242*3ac0a46fSAndroid Build Coastguard Worker       }
1243*3ac0a46fSAndroid Build Coastguard Worker     }
1244*3ac0a46fSAndroid Build Coastguard Worker 
1245*3ac0a46fSAndroid Build Coastguard Worker     m_Refresh.EndRefresh();
1246*3ac0a46fSAndroid Build Coastguard Worker   }
1247*3ac0a46fSAndroid Build Coastguard Worker }
1248*3ac0a46fSAndroid Build Coastguard Worker 
RefreshPushLineRects(const CPVT_WordRange & wr)1249*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) {
1250*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1251*3ac0a46fSAndroid Build Coastguard Worker     return;
1252*3ac0a46fSAndroid Build Coastguard Worker 
1253*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1254*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace wpBegin = wr.BeginPos;
1255*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wpBegin);
1256*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace wpEnd = wr.EndPos;
1257*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wpEnd);
1258*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(wpBegin);
1259*3ac0a46fSAndroid Build Coastguard Worker 
1260*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Line lineinfo;
1261*3ac0a46fSAndroid Build Coastguard Worker   do {
1262*3ac0a46fSAndroid Build Coastguard Worker     if (!pIterator->GetLine(lineinfo))
1263*3ac0a46fSAndroid Build Coastguard Worker       break;
1264*3ac0a46fSAndroid Build Coastguard Worker     if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1265*3ac0a46fSAndroid Build Coastguard Worker       break;
1266*3ac0a46fSAndroid Build Coastguard Worker 
1267*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcLine(lineinfo.ptLine.x,
1268*3ac0a46fSAndroid Build Coastguard Worker                          lineinfo.ptLine.y + lineinfo.fLineDescent,
1269*3ac0a46fSAndroid Build Coastguard Worker                          lineinfo.ptLine.x + lineinfo.fLineWidth,
1270*3ac0a46fSAndroid Build Coastguard Worker                          lineinfo.ptLine.y + lineinfo.fLineAscent);
1271*3ac0a46fSAndroid Build Coastguard Worker 
1272*3ac0a46fSAndroid Build Coastguard Worker     m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1273*3ac0a46fSAndroid Build Coastguard Worker                    VTToEdit(rcLine));
1274*3ac0a46fSAndroid Build Coastguard Worker   } while (pIterator->NextLine());
1275*3ac0a46fSAndroid Build Coastguard Worker }
1276*3ac0a46fSAndroid Build Coastguard Worker 
RefreshWordRange(const CPVT_WordRange & wr)1277*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) {
1278*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1279*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordRange wrTemp = wr;
1280*3ac0a46fSAndroid Build Coastguard Worker 
1281*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1282*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(wrTemp.EndPos);
1283*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(wrTemp.BeginPos);
1284*3ac0a46fSAndroid Build Coastguard Worker 
1285*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word wordinfo;
1286*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Line lineinfo;
1287*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace place;
1288*3ac0a46fSAndroid Build Coastguard Worker 
1289*3ac0a46fSAndroid Build Coastguard Worker   while (pIterator->NextWord()) {
1290*3ac0a46fSAndroid Build Coastguard Worker     place = pIterator->GetWordPlace();
1291*3ac0a46fSAndroid Build Coastguard Worker     if (place > wrTemp.EndPos)
1292*3ac0a46fSAndroid Build Coastguard Worker       break;
1293*3ac0a46fSAndroid Build Coastguard Worker 
1294*3ac0a46fSAndroid Build Coastguard Worker     pIterator->GetWord(wordinfo);
1295*3ac0a46fSAndroid Build Coastguard Worker     pIterator->GetLine(lineinfo);
1296*3ac0a46fSAndroid Build Coastguard Worker     if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1297*3ac0a46fSAndroid Build Coastguard Worker         place.LineCmp(wrTemp.EndPos) == 0) {
1298*3ac0a46fSAndroid Build Coastguard Worker       CFX_FloatRect rcWord(wordinfo.ptWord.x,
1299*3ac0a46fSAndroid Build Coastguard Worker                            lineinfo.ptLine.y + lineinfo.fLineDescent,
1300*3ac0a46fSAndroid Build Coastguard Worker                            wordinfo.ptWord.x + wordinfo.fWidth,
1301*3ac0a46fSAndroid Build Coastguard Worker                            lineinfo.ptLine.y + lineinfo.fLineAscent);
1302*3ac0a46fSAndroid Build Coastguard Worker 
1303*3ac0a46fSAndroid Build Coastguard Worker       if (m_pNotify) {
1304*3ac0a46fSAndroid Build Coastguard Worker         if (!m_bNotifyFlag) {
1305*3ac0a46fSAndroid Build Coastguard Worker           AutoRestorer<bool> restorer(&m_bNotifyFlag);
1306*3ac0a46fSAndroid Build Coastguard Worker           m_bNotifyFlag = true;
1307*3ac0a46fSAndroid Build Coastguard Worker           CFX_FloatRect rcRefresh = VTToEdit(rcWord);
1308*3ac0a46fSAndroid Build Coastguard Worker           if (!m_pNotify->InvalidateRect(&rcRefresh)) {
1309*3ac0a46fSAndroid Build Coastguard Worker             m_pNotify = nullptr;  // Gone, dangling even.
1310*3ac0a46fSAndroid Build Coastguard Worker           }
1311*3ac0a46fSAndroid Build Coastguard Worker         }
1312*3ac0a46fSAndroid Build Coastguard Worker       }
1313*3ac0a46fSAndroid Build Coastguard Worker     } else {
1314*3ac0a46fSAndroid Build Coastguard Worker       CFX_FloatRect rcLine(lineinfo.ptLine.x,
1315*3ac0a46fSAndroid Build Coastguard Worker                            lineinfo.ptLine.y + lineinfo.fLineDescent,
1316*3ac0a46fSAndroid Build Coastguard Worker                            lineinfo.ptLine.x + lineinfo.fLineWidth,
1317*3ac0a46fSAndroid Build Coastguard Worker                            lineinfo.ptLine.y + lineinfo.fLineAscent);
1318*3ac0a46fSAndroid Build Coastguard Worker 
1319*3ac0a46fSAndroid Build Coastguard Worker       if (m_pNotify) {
1320*3ac0a46fSAndroid Build Coastguard Worker         if (!m_bNotifyFlag) {
1321*3ac0a46fSAndroid Build Coastguard Worker           AutoRestorer<bool> restorer(&m_bNotifyFlag);
1322*3ac0a46fSAndroid Build Coastguard Worker           m_bNotifyFlag = true;
1323*3ac0a46fSAndroid Build Coastguard Worker           CFX_FloatRect rcRefresh = VTToEdit(rcLine);
1324*3ac0a46fSAndroid Build Coastguard Worker           if (!m_pNotify->InvalidateRect(&rcRefresh)) {
1325*3ac0a46fSAndroid Build Coastguard Worker             m_pNotify = nullptr;  // Gone, dangling even.
1326*3ac0a46fSAndroid Build Coastguard Worker           }
1327*3ac0a46fSAndroid Build Coastguard Worker         }
1328*3ac0a46fSAndroid Build Coastguard Worker       }
1329*3ac0a46fSAndroid Build Coastguard Worker 
1330*3ac0a46fSAndroid Build Coastguard Worker       pIterator->NextLine();
1331*3ac0a46fSAndroid Build Coastguard Worker     }
1332*3ac0a46fSAndroid Build Coastguard Worker   }
1333*3ac0a46fSAndroid Build Coastguard Worker }
1334*3ac0a46fSAndroid Build Coastguard Worker 
SetCaret(const CPVT_WordPlace & place)1335*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) {
1336*3ac0a46fSAndroid Build Coastguard Worker   m_wpOldCaret = m_wpCaret;
1337*3ac0a46fSAndroid Build Coastguard Worker   m_wpCaret = place;
1338*3ac0a46fSAndroid Build Coastguard Worker }
1339*3ac0a46fSAndroid Build Coastguard Worker 
SetCaretInfo()1340*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetCaretInfo() {
1341*3ac0a46fSAndroid Build Coastguard Worker   if (m_pNotify) {
1342*3ac0a46fSAndroid Build Coastguard Worker     if (!m_bNotifyFlag) {
1343*3ac0a46fSAndroid Build Coastguard Worker       CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1344*3ac0a46fSAndroid Build Coastguard Worker       pIterator->SetAt(m_wpCaret);
1345*3ac0a46fSAndroid Build Coastguard Worker 
1346*3ac0a46fSAndroid Build Coastguard Worker       CFX_PointF ptHead;
1347*3ac0a46fSAndroid Build Coastguard Worker       CFX_PointF ptFoot;
1348*3ac0a46fSAndroid Build Coastguard Worker       CPVT_Word word;
1349*3ac0a46fSAndroid Build Coastguard Worker       CPVT_Line line;
1350*3ac0a46fSAndroid Build Coastguard Worker       if (pIterator->GetWord(word)) {
1351*3ac0a46fSAndroid Build Coastguard Worker         ptHead.x = word.ptWord.x + word.fWidth;
1352*3ac0a46fSAndroid Build Coastguard Worker         ptHead.y = word.ptWord.y + word.fAscent;
1353*3ac0a46fSAndroid Build Coastguard Worker         ptFoot.x = word.ptWord.x + word.fWidth;
1354*3ac0a46fSAndroid Build Coastguard Worker         ptFoot.y = word.ptWord.y + word.fDescent;
1355*3ac0a46fSAndroid Build Coastguard Worker       } else if (pIterator->GetLine(line)) {
1356*3ac0a46fSAndroid Build Coastguard Worker         ptHead.x = line.ptLine.x;
1357*3ac0a46fSAndroid Build Coastguard Worker         ptHead.y = line.ptLine.y + line.fLineAscent;
1358*3ac0a46fSAndroid Build Coastguard Worker         ptFoot.x = line.ptLine.x;
1359*3ac0a46fSAndroid Build Coastguard Worker         ptFoot.y = line.ptLine.y + line.fLineDescent;
1360*3ac0a46fSAndroid Build Coastguard Worker       }
1361*3ac0a46fSAndroid Build Coastguard Worker 
1362*3ac0a46fSAndroid Build Coastguard Worker       AutoRestorer<bool> restorer(&m_bNotifyFlag);
1363*3ac0a46fSAndroid Build Coastguard Worker       m_bNotifyFlag = true;
1364*3ac0a46fSAndroid Build Coastguard Worker       m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1365*3ac0a46fSAndroid Build Coastguard Worker                           VTToEdit(ptFoot));
1366*3ac0a46fSAndroid Build Coastguard Worker     }
1367*3ac0a46fSAndroid Build Coastguard Worker   }
1368*3ac0a46fSAndroid Build Coastguard Worker }
1369*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseDown(const CFX_PointF & point,bool bShift,bool bCtrl)1370*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point,
1371*3ac0a46fSAndroid Build Coastguard Worker                                 bool bShift,
1372*3ac0a46fSAndroid Build Coastguard Worker                                 bool bCtrl) {
1373*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1374*3ac0a46fSAndroid Build Coastguard Worker     return;
1375*3ac0a46fSAndroid Build Coastguard Worker 
1376*3ac0a46fSAndroid Build Coastguard Worker   SelectNone();
1377*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1378*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1379*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1380*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1381*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1382*3ac0a46fSAndroid Build Coastguard Worker }
1383*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseMove(const CFX_PointF & point,bool bShift,bool bCtrl)1384*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point,
1385*3ac0a46fSAndroid Build Coastguard Worker                                 bool bShift,
1386*3ac0a46fSAndroid Build Coastguard Worker                                 bool bCtrl) {
1387*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1388*3ac0a46fSAndroid Build Coastguard Worker     return;
1389*3ac0a46fSAndroid Build Coastguard Worker 
1390*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1391*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpCaret == m_wpOldCaret)
1392*3ac0a46fSAndroid Build Coastguard Worker     return;
1393*3ac0a46fSAndroid Build Coastguard Worker 
1394*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.SetEndPos(m_wpCaret);
1395*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1396*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1397*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1398*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1399*3ac0a46fSAndroid Build Coastguard Worker }
1400*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_UP(bool bShift)1401*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_UP(bool bShift) {
1402*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1403*3ac0a46fSAndroid Build Coastguard Worker     return;
1404*3ac0a46fSAndroid Build Coastguard Worker 
1405*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1406*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1407*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1408*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1409*3ac0a46fSAndroid Build Coastguard Worker     else
1410*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1411*3ac0a46fSAndroid Build Coastguard Worker 
1412*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpOldCaret != m_wpCaret) {
1413*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1414*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1415*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1416*3ac0a46fSAndroid Build Coastguard Worker     }
1417*3ac0a46fSAndroid Build Coastguard Worker   } else {
1418*3ac0a46fSAndroid Build Coastguard Worker     SelectNone();
1419*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
1420*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
1421*3ac0a46fSAndroid Build Coastguard Worker   }
1422*3ac0a46fSAndroid Build Coastguard Worker }
1423*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_DOWN(bool bShift)1424*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_DOWN(bool bShift) {
1425*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1426*3ac0a46fSAndroid Build Coastguard Worker     return;
1427*3ac0a46fSAndroid Build Coastguard Worker 
1428*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1429*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1430*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1431*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1432*3ac0a46fSAndroid Build Coastguard Worker     else
1433*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1434*3ac0a46fSAndroid Build Coastguard Worker 
1435*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpOldCaret != m_wpCaret) {
1436*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1437*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1438*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1439*3ac0a46fSAndroid Build Coastguard Worker     }
1440*3ac0a46fSAndroid Build Coastguard Worker   } else {
1441*3ac0a46fSAndroid Build Coastguard Worker     SelectNone();
1442*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
1443*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
1444*3ac0a46fSAndroid Build Coastguard Worker   }
1445*3ac0a46fSAndroid Build Coastguard Worker }
1446*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_LEFT(bool bShift)1447*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_LEFT(bool bShift) {
1448*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1449*3ac0a46fSAndroid Build Coastguard Worker     return;
1450*3ac0a46fSAndroid Build Coastguard Worker 
1451*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1452*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1453*3ac0a46fSAndroid Build Coastguard Worker         m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1454*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1455*3ac0a46fSAndroid Build Coastguard Worker     }
1456*3ac0a46fSAndroid Build Coastguard Worker     SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1457*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1458*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1459*3ac0a46fSAndroid Build Coastguard Worker     else
1460*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1461*3ac0a46fSAndroid Build Coastguard Worker 
1462*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpOldCaret != m_wpCaret) {
1463*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1464*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1465*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1466*3ac0a46fSAndroid Build Coastguard Worker     }
1467*3ac0a46fSAndroid Build Coastguard Worker   } else {
1468*3ac0a46fSAndroid Build Coastguard Worker     if (!m_SelState.IsEmpty()) {
1469*3ac0a46fSAndroid Build Coastguard Worker       if (m_SelState.BeginPos < m_SelState.EndPos)
1470*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_SelState.BeginPos);
1471*3ac0a46fSAndroid Build Coastguard Worker       else
1472*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_SelState.EndPos);
1473*3ac0a46fSAndroid Build Coastguard Worker 
1474*3ac0a46fSAndroid Build Coastguard Worker       SelectNone();
1475*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1476*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1477*3ac0a46fSAndroid Build Coastguard Worker     } else {
1478*3ac0a46fSAndroid Build Coastguard Worker       if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1479*3ac0a46fSAndroid Build Coastguard Worker           m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1480*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1481*3ac0a46fSAndroid Build Coastguard Worker       }
1482*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1483*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1484*3ac0a46fSAndroid Build Coastguard Worker       SetCaretOrigin();
1485*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1486*3ac0a46fSAndroid Build Coastguard Worker     }
1487*3ac0a46fSAndroid Build Coastguard Worker   }
1488*3ac0a46fSAndroid Build Coastguard Worker }
1489*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_RIGHT(bool bShift)1490*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_RIGHT(bool bShift) {
1491*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1492*3ac0a46fSAndroid Build Coastguard Worker     return;
1493*3ac0a46fSAndroid Build Coastguard Worker 
1494*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1495*3ac0a46fSAndroid Build Coastguard Worker     SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1496*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1497*3ac0a46fSAndroid Build Coastguard Worker         m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
1498*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1499*3ac0a46fSAndroid Build Coastguard Worker 
1500*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1501*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1502*3ac0a46fSAndroid Build Coastguard Worker     else
1503*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1504*3ac0a46fSAndroid Build Coastguard Worker 
1505*3ac0a46fSAndroid Build Coastguard Worker     if (m_wpOldCaret != m_wpCaret) {
1506*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1507*3ac0a46fSAndroid Build Coastguard Worker       Refresh();
1508*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1509*3ac0a46fSAndroid Build Coastguard Worker     }
1510*3ac0a46fSAndroid Build Coastguard Worker   } else {
1511*3ac0a46fSAndroid Build Coastguard Worker     if (!m_SelState.IsEmpty()) {
1512*3ac0a46fSAndroid Build Coastguard Worker       if (m_SelState.BeginPos > m_SelState.EndPos)
1513*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_SelState.BeginPos);
1514*3ac0a46fSAndroid Build Coastguard Worker       else
1515*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_SelState.EndPos);
1516*3ac0a46fSAndroid Build Coastguard Worker 
1517*3ac0a46fSAndroid Build Coastguard Worker       SelectNone();
1518*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1519*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1520*3ac0a46fSAndroid Build Coastguard Worker     } else {
1521*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1522*3ac0a46fSAndroid Build Coastguard Worker       if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1523*3ac0a46fSAndroid Build Coastguard Worker           m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
1524*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1525*3ac0a46fSAndroid Build Coastguard Worker       }
1526*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1527*3ac0a46fSAndroid Build Coastguard Worker       SetCaretOrigin();
1528*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1529*3ac0a46fSAndroid Build Coastguard Worker     }
1530*3ac0a46fSAndroid Build Coastguard Worker   }
1531*3ac0a46fSAndroid Build Coastguard Worker }
1532*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_HOME(bool bShift,bool bCtrl)1533*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) {
1534*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1535*3ac0a46fSAndroid Build Coastguard Worker     return;
1536*3ac0a46fSAndroid Build Coastguard Worker 
1537*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1538*3ac0a46fSAndroid Build Coastguard Worker     if (bCtrl)
1539*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetBeginWordPlace());
1540*3ac0a46fSAndroid Build Coastguard Worker     else
1541*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1542*3ac0a46fSAndroid Build Coastguard Worker 
1543*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1544*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1545*3ac0a46fSAndroid Build Coastguard Worker     else
1546*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1547*3ac0a46fSAndroid Build Coastguard Worker 
1548*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
1549*3ac0a46fSAndroid Build Coastguard Worker     Refresh();
1550*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
1551*3ac0a46fSAndroid Build Coastguard Worker   } else {
1552*3ac0a46fSAndroid Build Coastguard Worker     if (!m_SelState.IsEmpty()) {
1553*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1554*3ac0a46fSAndroid Build Coastguard Worker       SelectNone();
1555*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1556*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1557*3ac0a46fSAndroid Build Coastguard Worker     } else {
1558*3ac0a46fSAndroid Build Coastguard Worker       if (bCtrl)
1559*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetBeginWordPlace());
1560*3ac0a46fSAndroid Build Coastguard Worker       else
1561*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1562*3ac0a46fSAndroid Build Coastguard Worker 
1563*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1564*3ac0a46fSAndroid Build Coastguard Worker       SetCaretOrigin();
1565*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1566*3ac0a46fSAndroid Build Coastguard Worker     }
1567*3ac0a46fSAndroid Build Coastguard Worker   }
1568*3ac0a46fSAndroid Build Coastguard Worker }
1569*3ac0a46fSAndroid Build Coastguard Worker 
OnVK_END(bool bShift,bool bCtrl)1570*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) {
1571*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1572*3ac0a46fSAndroid Build Coastguard Worker     return;
1573*3ac0a46fSAndroid Build Coastguard Worker 
1574*3ac0a46fSAndroid Build Coastguard Worker   if (bShift) {
1575*3ac0a46fSAndroid Build Coastguard Worker     if (bCtrl)
1576*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetEndWordPlace());
1577*3ac0a46fSAndroid Build Coastguard Worker     else
1578*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1579*3ac0a46fSAndroid Build Coastguard Worker 
1580*3ac0a46fSAndroid Build Coastguard Worker     if (m_SelState.IsEmpty())
1581*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.Set(m_wpOldCaret, m_wpCaret);
1582*3ac0a46fSAndroid Build Coastguard Worker     else
1583*3ac0a46fSAndroid Build Coastguard Worker       m_SelState.SetEndPos(m_wpCaret);
1584*3ac0a46fSAndroid Build Coastguard Worker 
1585*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
1586*3ac0a46fSAndroid Build Coastguard Worker     Refresh();
1587*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
1588*3ac0a46fSAndroid Build Coastguard Worker   } else {
1589*3ac0a46fSAndroid Build Coastguard Worker     if (!m_SelState.IsEmpty()) {
1590*3ac0a46fSAndroid Build Coastguard Worker       SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1591*3ac0a46fSAndroid Build Coastguard Worker       SelectNone();
1592*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1593*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1594*3ac0a46fSAndroid Build Coastguard Worker     } else {
1595*3ac0a46fSAndroid Build Coastguard Worker       if (bCtrl)
1596*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetEndWordPlace());
1597*3ac0a46fSAndroid Build Coastguard Worker       else
1598*3ac0a46fSAndroid Build Coastguard Worker         SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1599*3ac0a46fSAndroid Build Coastguard Worker 
1600*3ac0a46fSAndroid Build Coastguard Worker       ScrollToCaret();
1601*3ac0a46fSAndroid Build Coastguard Worker       SetCaretOrigin();
1602*3ac0a46fSAndroid Build Coastguard Worker       SetCaretInfo();
1603*3ac0a46fSAndroid Build Coastguard Worker     }
1604*3ac0a46fSAndroid Build Coastguard Worker   }
1605*3ac0a46fSAndroid Build Coastguard Worker }
1606*3ac0a46fSAndroid Build Coastguard Worker 
InsertWord(uint16_t word,FX_Charset charset,bool bAddUndo)1607*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertWord(uint16_t word,
1608*3ac0a46fSAndroid Build Coastguard Worker                                FX_Charset charset,
1609*3ac0a46fSAndroid Build Coastguard Worker                                bool bAddUndo) {
1610*3ac0a46fSAndroid Build Coastguard Worker   if (IsTextOverflow() || !m_pVT->IsValid())
1611*3ac0a46fSAndroid Build Coastguard Worker     return false;
1612*3ac0a46fSAndroid Build Coastguard Worker 
1613*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(m_wpCaret);
1614*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(
1615*3ac0a46fSAndroid Build Coastguard Worker       m_pVT->InsertWord(m_wpCaret, word, GetCharSetFromUnicode(word, charset)));
1616*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1617*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpCaret == m_wpOldCaret)
1618*3ac0a46fSAndroid Build Coastguard Worker     return false;
1619*3ac0a46fSAndroid Build Coastguard Worker 
1620*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1621*3ac0a46fSAndroid Build Coastguard Worker     AddEditUndoItem(std::make_unique<UndoInsertWord>(this, m_wpOldCaret,
1622*3ac0a46fSAndroid Build Coastguard Worker                                                      m_wpCaret, word, charset));
1623*3ac0a46fSAndroid Build Coastguard Worker   }
1624*3ac0a46fSAndroid Build Coastguard Worker   PaintInsertText(m_wpOldCaret, m_wpCaret);
1625*3ac0a46fSAndroid Build Coastguard Worker   return true;
1626*3ac0a46fSAndroid Build Coastguard Worker }
1627*3ac0a46fSAndroid Build Coastguard Worker 
InsertReturn(bool bAddUndo)1628*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertReturn(bool bAddUndo) {
1629*3ac0a46fSAndroid Build Coastguard Worker   if (IsTextOverflow() || !m_pVT->IsValid())
1630*3ac0a46fSAndroid Build Coastguard Worker     return false;
1631*3ac0a46fSAndroid Build Coastguard Worker 
1632*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(m_wpCaret);
1633*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->InsertSection(m_wpCaret));
1634*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1635*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpCaret == m_wpOldCaret)
1636*3ac0a46fSAndroid Build Coastguard Worker     return false;
1637*3ac0a46fSAndroid Build Coastguard Worker 
1638*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1639*3ac0a46fSAndroid Build Coastguard Worker     AddEditUndoItem(
1640*3ac0a46fSAndroid Build Coastguard Worker         std::make_unique<UndoInsertReturn>(this, m_wpOldCaret, m_wpCaret));
1641*3ac0a46fSAndroid Build Coastguard Worker   }
1642*3ac0a46fSAndroid Build Coastguard Worker   RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1643*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1644*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1645*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1646*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1647*3ac0a46fSAndroid Build Coastguard Worker   return true;
1648*3ac0a46fSAndroid Build Coastguard Worker }
1649*3ac0a46fSAndroid Build Coastguard Worker 
Backspace(bool bAddUndo)1650*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Backspace(bool bAddUndo) {
1651*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1652*3ac0a46fSAndroid Build Coastguard Worker     return false;
1653*3ac0a46fSAndroid Build Coastguard Worker 
1654*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word word;
1655*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo) {
1656*3ac0a46fSAndroid Build Coastguard Worker     CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1657*3ac0a46fSAndroid Build Coastguard Worker     pIterator->SetAt(m_wpCaret);
1658*3ac0a46fSAndroid Build Coastguard Worker     pIterator->GetWord(word);
1659*3ac0a46fSAndroid Build Coastguard Worker   }
1660*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(m_wpCaret);
1661*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1662*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1663*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpCaret == m_wpOldCaret)
1664*3ac0a46fSAndroid Build Coastguard Worker     return false;
1665*3ac0a46fSAndroid Build Coastguard Worker 
1666*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1667*3ac0a46fSAndroid Build Coastguard Worker     AddEditUndoItem(std::make_unique<UndoBackspace>(
1668*3ac0a46fSAndroid Build Coastguard Worker         this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset));
1669*3ac0a46fSAndroid Build Coastguard Worker   }
1670*3ac0a46fSAndroid Build Coastguard Worker   RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1671*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1672*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1673*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1674*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1675*3ac0a46fSAndroid Build Coastguard Worker   return true;
1676*3ac0a46fSAndroid Build Coastguard Worker }
1677*3ac0a46fSAndroid Build Coastguard Worker 
Delete(bool bAddUndo)1678*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Delete(bool bAddUndo) {
1679*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1680*3ac0a46fSAndroid Build Coastguard Worker     return false;
1681*3ac0a46fSAndroid Build Coastguard Worker 
1682*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word word;
1683*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo) {
1684*3ac0a46fSAndroid Build Coastguard Worker     CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1685*3ac0a46fSAndroid Build Coastguard Worker     pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1686*3ac0a46fSAndroid Build Coastguard Worker     pIterator->GetWord(word);
1687*3ac0a46fSAndroid Build Coastguard Worker   }
1688*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(m_wpCaret);
1689*3ac0a46fSAndroid Build Coastguard Worker   bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1690*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->DeleteWord(m_wpCaret));
1691*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1692*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1693*3ac0a46fSAndroid Build Coastguard Worker     if (bSecEnd) {
1694*3ac0a46fSAndroid Build Coastguard Worker       AddEditUndoItem(std::make_unique<UndoDelete>(
1695*3ac0a46fSAndroid Build Coastguard Worker           this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
1696*3ac0a46fSAndroid Build Coastguard Worker     } else {
1697*3ac0a46fSAndroid Build Coastguard Worker       AddEditUndoItem(std::make_unique<UndoDelete>(
1698*3ac0a46fSAndroid Build Coastguard Worker           this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
1699*3ac0a46fSAndroid Build Coastguard Worker     }
1700*3ac0a46fSAndroid Build Coastguard Worker   }
1701*3ac0a46fSAndroid Build Coastguard Worker   RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1702*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1703*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1704*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1705*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1706*3ac0a46fSAndroid Build Coastguard Worker   return true;
1707*3ac0a46fSAndroid Build Coastguard Worker }
1708*3ac0a46fSAndroid Build Coastguard Worker 
Clear()1709*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Clear() {
1710*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
1711*3ac0a46fSAndroid Build Coastguard Worker     m_pVT->DeleteWords(GetWholeWordRange());
1712*3ac0a46fSAndroid Build Coastguard Worker     SetCaret(m_pVT->GetBeginWordPlace());
1713*3ac0a46fSAndroid Build Coastguard Worker 
1714*3ac0a46fSAndroid Build Coastguard Worker     return true;
1715*3ac0a46fSAndroid Build Coastguard Worker   }
1716*3ac0a46fSAndroid Build Coastguard Worker 
1717*3ac0a46fSAndroid Build Coastguard Worker   return false;
1718*3ac0a46fSAndroid Build Coastguard Worker }
1719*3ac0a46fSAndroid Build Coastguard Worker 
Clear(bool bAddUndo)1720*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Clear(bool bAddUndo) {
1721*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1722*3ac0a46fSAndroid Build Coastguard Worker     return false;
1723*3ac0a46fSAndroid Build Coastguard Worker 
1724*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordRange range = m_SelState.ConvertToWordRange();
1725*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1726*3ac0a46fSAndroid Build Coastguard Worker     AddEditUndoItem(
1727*3ac0a46fSAndroid Build Coastguard Worker         std::make_unique<UndoClear>(this, range, GetSelectedText()));
1728*3ac0a46fSAndroid Build Coastguard Worker   }
1729*3ac0a46fSAndroid Build Coastguard Worker   SelectNone();
1730*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(m_pVT->DeleteWords(range));
1731*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1732*3ac0a46fSAndroid Build Coastguard Worker   RearrangePart(range);
1733*3ac0a46fSAndroid Build Coastguard Worker   ScrollToCaret();
1734*3ac0a46fSAndroid Build Coastguard Worker   Refresh();
1735*3ac0a46fSAndroid Build Coastguard Worker   SetCaretOrigin();
1736*3ac0a46fSAndroid Build Coastguard Worker   SetCaretInfo();
1737*3ac0a46fSAndroid Build Coastguard Worker   return true;
1738*3ac0a46fSAndroid Build Coastguard Worker }
1739*3ac0a46fSAndroid Build Coastguard Worker 
InsertText(const WideString & sText,FX_Charset charset,bool bAddUndo)1740*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::InsertText(const WideString& sText,
1741*3ac0a46fSAndroid Build Coastguard Worker                                FX_Charset charset,
1742*3ac0a46fSAndroid Build Coastguard Worker                                bool bAddUndo) {
1743*3ac0a46fSAndroid Build Coastguard Worker   if (IsTextOverflow())
1744*3ac0a46fSAndroid Build Coastguard Worker     return false;
1745*3ac0a46fSAndroid Build Coastguard Worker 
1746*3ac0a46fSAndroid Build Coastguard Worker   m_pVT->UpdateWordPlace(m_wpCaret);
1747*3ac0a46fSAndroid Build Coastguard Worker   SetCaret(DoInsertText(m_wpCaret, sText, charset));
1748*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(m_wpCaret, m_wpCaret);
1749*3ac0a46fSAndroid Build Coastguard Worker   if (m_wpCaret == m_wpOldCaret)
1750*3ac0a46fSAndroid Build Coastguard Worker     return false;
1751*3ac0a46fSAndroid Build Coastguard Worker 
1752*3ac0a46fSAndroid Build Coastguard Worker   if (bAddUndo && m_bEnableUndo) {
1753*3ac0a46fSAndroid Build Coastguard Worker     AddEditUndoItem(std::make_unique<UndoInsertText>(
1754*3ac0a46fSAndroid Build Coastguard Worker         this, m_wpOldCaret, m_wpCaret, sText, charset));
1755*3ac0a46fSAndroid Build Coastguard Worker   }
1756*3ac0a46fSAndroid Build Coastguard Worker   PaintInsertText(m_wpOldCaret, m_wpCaret);
1757*3ac0a46fSAndroid Build Coastguard Worker   return true;
1758*3ac0a46fSAndroid Build Coastguard Worker }
1759*3ac0a46fSAndroid Build Coastguard Worker 
PaintInsertText(const CPVT_WordPlace & wpOld,const CPVT_WordPlace & wpNew)1760*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld,
1761*3ac0a46fSAndroid Build Coastguard Worker                                     const CPVT_WordPlace& wpNew) {
1762*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid()) {
1763*3ac0a46fSAndroid Build Coastguard Worker     RearrangePart(CPVT_WordRange(wpOld, wpNew));
1764*3ac0a46fSAndroid Build Coastguard Worker     ScrollToCaret();
1765*3ac0a46fSAndroid Build Coastguard Worker     Refresh();
1766*3ac0a46fSAndroid Build Coastguard Worker     SetCaretOrigin();
1767*3ac0a46fSAndroid Build Coastguard Worker     SetCaretInfo();
1768*3ac0a46fSAndroid Build Coastguard Worker   }
1769*3ac0a46fSAndroid Build Coastguard Worker }
1770*3ac0a46fSAndroid Build Coastguard Worker 
ReplaceAndKeepSelection(const WideString & text)1771*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::ReplaceAndKeepSelection(const WideString& text) {
1772*3ac0a46fSAndroid Build Coastguard Worker   AddEditUndoItem(std::make_unique<UndoReplaceSelection>(this, false));
1773*3ac0a46fSAndroid Build Coastguard Worker   ClearSelection();
1774*3ac0a46fSAndroid Build Coastguard Worker 
1775*3ac0a46fSAndroid Build Coastguard Worker   // Select the inserted text.
1776*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace caret_before_insert = m_wpCaret;
1777*3ac0a46fSAndroid Build Coastguard Worker   InsertText(text, FX_Charset::kDefault);
1778*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace caret_after_insert = m_wpCaret;
1779*3ac0a46fSAndroid Build Coastguard Worker   m_SelState.Set(caret_before_insert, caret_after_insert);
1780*3ac0a46fSAndroid Build Coastguard Worker 
1781*3ac0a46fSAndroid Build Coastguard Worker   AddEditUndoItem(std::make_unique<UndoReplaceSelection>(this, true));
1782*3ac0a46fSAndroid Build Coastguard Worker }
1783*3ac0a46fSAndroid Build Coastguard Worker 
ReplaceSelection(const WideString & text)1784*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::ReplaceSelection(const WideString& text) {
1785*3ac0a46fSAndroid Build Coastguard Worker   AddEditUndoItem(std::make_unique<UndoReplaceSelection>(this, false));
1786*3ac0a46fSAndroid Build Coastguard Worker   ClearSelection();
1787*3ac0a46fSAndroid Build Coastguard Worker   InsertText(text, FX_Charset::kDefault);
1788*3ac0a46fSAndroid Build Coastguard Worker   AddEditUndoItem(std::make_unique<UndoReplaceSelection>(this, true));
1789*3ac0a46fSAndroid Build Coastguard Worker }
1790*3ac0a46fSAndroid Build Coastguard Worker 
Redo()1791*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Redo() {
1792*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableUndo) {
1793*3ac0a46fSAndroid Build Coastguard Worker     if (m_Undo.CanRedo()) {
1794*3ac0a46fSAndroid Build Coastguard Worker       m_Undo.Redo();
1795*3ac0a46fSAndroid Build Coastguard Worker       return true;
1796*3ac0a46fSAndroid Build Coastguard Worker     }
1797*3ac0a46fSAndroid Build Coastguard Worker   }
1798*3ac0a46fSAndroid Build Coastguard Worker 
1799*3ac0a46fSAndroid Build Coastguard Worker   return false;
1800*3ac0a46fSAndroid Build Coastguard Worker }
1801*3ac0a46fSAndroid Build Coastguard Worker 
Undo()1802*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::Undo() {
1803*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableUndo) {
1804*3ac0a46fSAndroid Build Coastguard Worker     if (m_Undo.CanUndo()) {
1805*3ac0a46fSAndroid Build Coastguard Worker       m_Undo.Undo();
1806*3ac0a46fSAndroid Build Coastguard Worker       return true;
1807*3ac0a46fSAndroid Build Coastguard Worker     }
1808*3ac0a46fSAndroid Build Coastguard Worker   }
1809*3ac0a46fSAndroid Build Coastguard Worker 
1810*3ac0a46fSAndroid Build Coastguard Worker   return false;
1811*3ac0a46fSAndroid Build Coastguard Worker }
1812*3ac0a46fSAndroid Build Coastguard Worker 
SetCaretOrigin()1813*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SetCaretOrigin() {
1814*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1815*3ac0a46fSAndroid Build Coastguard Worker     return;
1816*3ac0a46fSAndroid Build Coastguard Worker 
1817*3ac0a46fSAndroid Build Coastguard Worker   CPVT_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1818*3ac0a46fSAndroid Build Coastguard Worker   pIterator->SetAt(m_wpCaret);
1819*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Word word;
1820*3ac0a46fSAndroid Build Coastguard Worker   CPVT_Line line;
1821*3ac0a46fSAndroid Build Coastguard Worker   if (pIterator->GetWord(word)) {
1822*3ac0a46fSAndroid Build Coastguard Worker     m_ptCaret.x = word.ptWord.x + word.fWidth;
1823*3ac0a46fSAndroid Build Coastguard Worker     m_ptCaret.y = word.ptWord.y;
1824*3ac0a46fSAndroid Build Coastguard Worker   } else if (pIterator->GetLine(line)) {
1825*3ac0a46fSAndroid Build Coastguard Worker     m_ptCaret.x = line.ptLine.x;
1826*3ac0a46fSAndroid Build Coastguard Worker     m_ptCaret.y = line.ptLine.y;
1827*3ac0a46fSAndroid Build Coastguard Worker   }
1828*3ac0a46fSAndroid Build Coastguard Worker }
1829*3ac0a46fSAndroid Build Coastguard Worker 
WordIndexToWordPlace(int32_t index) const1830*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const {
1831*3ac0a46fSAndroid Build Coastguard Worker   if (m_pVT->IsValid())
1832*3ac0a46fSAndroid Build Coastguard Worker     return m_pVT->WordIndexToWordPlace(index);
1833*3ac0a46fSAndroid Build Coastguard Worker 
1834*3ac0a46fSAndroid Build Coastguard Worker   return CPVT_WordPlace();
1835*3ac0a46fSAndroid Build Coastguard Worker }
1836*3ac0a46fSAndroid Build Coastguard Worker 
IsTextFull() const1837*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::IsTextFull() const {
1838*3ac0a46fSAndroid Build Coastguard Worker   int32_t nTotalWords = m_pVT->GetTotalWords();
1839*3ac0a46fSAndroid Build Coastguard Worker   int32_t nLimitChar = m_pVT->GetLimitChar();
1840*3ac0a46fSAndroid Build Coastguard Worker   int32_t nCharArray = m_pVT->GetCharArray();
1841*3ac0a46fSAndroid Build Coastguard Worker 
1842*3ac0a46fSAndroid Build Coastguard Worker   return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1843*3ac0a46fSAndroid Build Coastguard Worker          (nCharArray > 0 && nTotalWords >= nCharArray);
1844*3ac0a46fSAndroid Build Coastguard Worker }
1845*3ac0a46fSAndroid Build Coastguard Worker 
IsTextOverflow() const1846*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::IsTextOverflow() const {
1847*3ac0a46fSAndroid Build Coastguard Worker   if (!m_bEnableScroll && !m_bEnableOverflow) {
1848*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1849*3ac0a46fSAndroid Build Coastguard Worker     CFX_FloatRect rcContent = m_pVT->GetContentRect();
1850*3ac0a46fSAndroid Build Coastguard Worker 
1851*3ac0a46fSAndroid Build Coastguard Worker     if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1852*3ac0a46fSAndroid Build Coastguard Worker         FXSYS_IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
1853*3ac0a46fSAndroid Build Coastguard Worker       return true;
1854*3ac0a46fSAndroid Build Coastguard Worker     }
1855*3ac0a46fSAndroid Build Coastguard Worker 
1856*3ac0a46fSAndroid Build Coastguard Worker     if (FXSYS_IsFloatBigger(rcContent.Width(), rcPlate.Width()))
1857*3ac0a46fSAndroid Build Coastguard Worker       return true;
1858*3ac0a46fSAndroid Build Coastguard Worker   }
1859*3ac0a46fSAndroid Build Coastguard Worker 
1860*3ac0a46fSAndroid Build Coastguard Worker   return false;
1861*3ac0a46fSAndroid Build Coastguard Worker }
1862*3ac0a46fSAndroid Build Coastguard Worker 
CanUndo() const1863*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::CanUndo() const {
1864*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableUndo) {
1865*3ac0a46fSAndroid Build Coastguard Worker     return m_Undo.CanUndo();
1866*3ac0a46fSAndroid Build Coastguard Worker   }
1867*3ac0a46fSAndroid Build Coastguard Worker 
1868*3ac0a46fSAndroid Build Coastguard Worker   return false;
1869*3ac0a46fSAndroid Build Coastguard Worker }
1870*3ac0a46fSAndroid Build Coastguard Worker 
CanRedo() const1871*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::CanRedo() const {
1872*3ac0a46fSAndroid Build Coastguard Worker   if (m_bEnableUndo) {
1873*3ac0a46fSAndroid Build Coastguard Worker     return m_Undo.CanRedo();
1874*3ac0a46fSAndroid Build Coastguard Worker   }
1875*3ac0a46fSAndroid Build Coastguard Worker 
1876*3ac0a46fSAndroid Build Coastguard Worker   return false;
1877*3ac0a46fSAndroid Build Coastguard Worker }
1878*3ac0a46fSAndroid Build Coastguard Worker 
EnableRefresh(bool bRefresh)1879*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::EnableRefresh(bool bRefresh) {
1880*3ac0a46fSAndroid Build Coastguard Worker   m_bEnableRefresh = bRefresh;
1881*3ac0a46fSAndroid Build Coastguard Worker }
1882*3ac0a46fSAndroid Build Coastguard Worker 
EnableUndo(bool bUndo)1883*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::EnableUndo(bool bUndo) {
1884*3ac0a46fSAndroid Build Coastguard Worker   m_bEnableUndo = bUndo;
1885*3ac0a46fSAndroid Build Coastguard Worker }
1886*3ac0a46fSAndroid Build Coastguard Worker 
DoInsertText(const CPVT_WordPlace & place,const WideString & sText,FX_Charset charset)1887*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
1888*3ac0a46fSAndroid Build Coastguard Worker                                            const WideString& sText,
1889*3ac0a46fSAndroid Build Coastguard Worker                                            FX_Charset charset) {
1890*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pVT->IsValid())
1891*3ac0a46fSAndroid Build Coastguard Worker     return place;
1892*3ac0a46fSAndroid Build Coastguard Worker 
1893*3ac0a46fSAndroid Build Coastguard Worker   CPVT_WordPlace wp = place;
1894*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < sText.GetLength(); ++i) {
1895*3ac0a46fSAndroid Build Coastguard Worker     uint16_t word = sText[i];
1896*3ac0a46fSAndroid Build Coastguard Worker     switch (word) {
1897*3ac0a46fSAndroid Build Coastguard Worker       case '\r':
1898*3ac0a46fSAndroid Build Coastguard Worker         wp = m_pVT->InsertSection(wp);
1899*3ac0a46fSAndroid Build Coastguard Worker         if (i + 1 < sText.GetLength() && sText[i + 1] == '\n')
1900*3ac0a46fSAndroid Build Coastguard Worker           i++;
1901*3ac0a46fSAndroid Build Coastguard Worker         break;
1902*3ac0a46fSAndroid Build Coastguard Worker       case '\n':
1903*3ac0a46fSAndroid Build Coastguard Worker         wp = m_pVT->InsertSection(wp);
1904*3ac0a46fSAndroid Build Coastguard Worker         break;
1905*3ac0a46fSAndroid Build Coastguard Worker       case '\t':
1906*3ac0a46fSAndroid Build Coastguard Worker         word = ' ';
1907*3ac0a46fSAndroid Build Coastguard Worker         [[fallthrough]];
1908*3ac0a46fSAndroid Build Coastguard Worker       default:
1909*3ac0a46fSAndroid Build Coastguard Worker         wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset));
1910*3ac0a46fSAndroid Build Coastguard Worker         break;
1911*3ac0a46fSAndroid Build Coastguard Worker     }
1912*3ac0a46fSAndroid Build Coastguard Worker   }
1913*3ac0a46fSAndroid Build Coastguard Worker   return wp;
1914*3ac0a46fSAndroid Build Coastguard Worker }
1915*3ac0a46fSAndroid Build Coastguard Worker 
GetCharSetFromUnicode(uint16_t word,FX_Charset nOldCharset)1916*3ac0a46fSAndroid Build Coastguard Worker FX_Charset CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word,
1917*3ac0a46fSAndroid Build Coastguard Worker                                                 FX_Charset nOldCharset) {
1918*3ac0a46fSAndroid Build Coastguard Worker   if (IPVT_FontMap* pFontMap = GetFontMap())
1919*3ac0a46fSAndroid Build Coastguard Worker     return pFontMap->CharSetFromUnicode(word, nOldCharset);
1920*3ac0a46fSAndroid Build Coastguard Worker   return nOldCharset;
1921*3ac0a46fSAndroid Build Coastguard Worker }
1922*3ac0a46fSAndroid Build Coastguard Worker 
AddEditUndoItem(std::unique_ptr<UndoItemIface> pEditUndoItem)1923*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::AddEditUndoItem(
1924*3ac0a46fSAndroid Build Coastguard Worker     std::unique_ptr<UndoItemIface> pEditUndoItem) {
1925*3ac0a46fSAndroid Build Coastguard Worker   m_Undo.AddItem(std::move(pEditUndoItem));
1926*3ac0a46fSAndroid Build Coastguard Worker }
1927*3ac0a46fSAndroid Build Coastguard Worker 
GetPDFWordString(int32_t nFontIndex,uint16_t Word,uint16_t SubWord)1928*3ac0a46fSAndroid Build Coastguard Worker ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
1929*3ac0a46fSAndroid Build Coastguard Worker                                            uint16_t Word,
1930*3ac0a46fSAndroid Build Coastguard Worker                                            uint16_t SubWord) {
1931*3ac0a46fSAndroid Build Coastguard Worker   IPVT_FontMap* pFontMap = GetFontMap();
1932*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<CPDF_Font> pPDFFont = pFontMap->GetPDFFont(nFontIndex);
1933*3ac0a46fSAndroid Build Coastguard Worker   if (!pPDFFont)
1934*3ac0a46fSAndroid Build Coastguard Worker     return ByteString();
1935*3ac0a46fSAndroid Build Coastguard Worker 
1936*3ac0a46fSAndroid Build Coastguard Worker   ByteString sWord;
1937*3ac0a46fSAndroid Build Coastguard Worker   if (SubWord > 0) {
1938*3ac0a46fSAndroid Build Coastguard Worker     Word = SubWord;
1939*3ac0a46fSAndroid Build Coastguard Worker   } else {
1940*3ac0a46fSAndroid Build Coastguard Worker     uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1941*3ac0a46fSAndroid Build Coastguard Worker                               ? pPDFFont->CharCodeFromUnicode(Word)
1942*3ac0a46fSAndroid Build Coastguard Worker                               : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
1943*3ac0a46fSAndroid Build Coastguard Worker     if (dwCharCode > 0) {
1944*3ac0a46fSAndroid Build Coastguard Worker       pPDFFont->AppendChar(&sWord, dwCharCode);
1945*3ac0a46fSAndroid Build Coastguard Worker       return sWord;
1946*3ac0a46fSAndroid Build Coastguard Worker     }
1947*3ac0a46fSAndroid Build Coastguard Worker   }
1948*3ac0a46fSAndroid Build Coastguard Worker   pPDFFont->AppendChar(&sWord, Word);
1949*3ac0a46fSAndroid Build Coastguard Worker   return sWord;
1950*3ac0a46fSAndroid Build Coastguard Worker }
1951*3ac0a46fSAndroid Build Coastguard Worker 
1952*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::SelectState::SelectState() = default;
1953*3ac0a46fSAndroid Build Coastguard Worker 
SelectState(const CPVT_WordRange & range)1954*3ac0a46fSAndroid Build Coastguard Worker CPWL_EditImpl::SelectState::SelectState(const CPVT_WordRange& range) {
1955*3ac0a46fSAndroid Build Coastguard Worker   Set(range.BeginPos, range.EndPos);
1956*3ac0a46fSAndroid Build Coastguard Worker }
1957*3ac0a46fSAndroid Build Coastguard Worker 
ConvertToWordRange() const1958*3ac0a46fSAndroid Build Coastguard Worker CPVT_WordRange CPWL_EditImpl::SelectState::ConvertToWordRange() const {
1959*3ac0a46fSAndroid Build Coastguard Worker   return CPVT_WordRange(BeginPos, EndPos);
1960*3ac0a46fSAndroid Build Coastguard Worker }
1961*3ac0a46fSAndroid Build Coastguard Worker 
Reset()1962*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SelectState::Reset() {
1963*3ac0a46fSAndroid Build Coastguard Worker   BeginPos.Reset();
1964*3ac0a46fSAndroid Build Coastguard Worker   EndPos.Reset();
1965*3ac0a46fSAndroid Build Coastguard Worker }
1966*3ac0a46fSAndroid Build Coastguard Worker 
Set(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)1967*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SelectState::Set(const CPVT_WordPlace& begin,
1968*3ac0a46fSAndroid Build Coastguard Worker                                      const CPVT_WordPlace& end) {
1969*3ac0a46fSAndroid Build Coastguard Worker   BeginPos = begin;
1970*3ac0a46fSAndroid Build Coastguard Worker   EndPos = end;
1971*3ac0a46fSAndroid Build Coastguard Worker }
1972*3ac0a46fSAndroid Build Coastguard Worker 
SetEndPos(const CPVT_WordPlace & end)1973*3ac0a46fSAndroid Build Coastguard Worker void CPWL_EditImpl::SelectState::SetEndPos(const CPVT_WordPlace& end) {
1974*3ac0a46fSAndroid Build Coastguard Worker   EndPos = end;
1975*3ac0a46fSAndroid Build Coastguard Worker }
1976*3ac0a46fSAndroid Build Coastguard Worker 
IsEmpty() const1977*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_EditImpl::SelectState::IsEmpty() const {
1978*3ac0a46fSAndroid Build Coastguard Worker   return BeginPos == EndPos;
1979*3ac0a46fSAndroid Build Coastguard Worker }
1980