Rename Init methods to more accurately describe purpose
[pdfium.git] / fpdfsdk / src / formfiller / FFL_TextField.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../include/formfiller/FFL_TextField.h"
8 #include "../../include/formfiller/FFL_CBA_Fontmap.h"
9
10 /* ------------------------------- CFFL_TextField
11  * ------------------------------- */
12
13 CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
14     : CFFL_FormFiller(pApp, pAnnot),
15       m_pFontMap(NULL)  //,
16 // m_pSpellCheck(NULL)
17 {
18   m_State.nStart = m_State.nEnd = 0;
19 }
20
21 CFFL_TextField::~CFFL_TextField() {
22   delete m_pFontMap;
23 }
24
25 PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
26   PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
27
28   ASSERT(m_pWidget != NULL);
29   int nFlags = m_pWidget->GetFieldFlags();
30
31   if (nFlags & FIELDFLAG_PASSWORD) {
32     cp.dwFlags |= PES_PASSWORD;
33   }
34
35   if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK)) {
36   }
37
38   if (nFlags & FIELDFLAG_MULTILINE) {
39     cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
40
41     if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
42       cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
43     }
44   } else {
45     cp.dwFlags |= PES_CENTER;
46
47     if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
48       cp.dwFlags |= PES_AUTOSCROLL;
49     }
50   }
51
52   if (nFlags & FIELDFLAG_COMB) {
53     cp.dwFlags |= PES_CHARARRAY;
54   }
55
56   if (nFlags & FIELDFLAG_RICHTEXT) {
57     cp.dwFlags |= PES_RICH;
58   }
59
60   cp.dwFlags |= PES_UNDO;
61
62   switch (m_pWidget->GetAlignment()) {
63     default:
64     case BF_ALIGN_LEFT:
65       cp.dwFlags |= PES_LEFT;
66       break;
67     case BF_ALIGN_MIDDLE:
68       cp.dwFlags |= PES_MIDDLE;
69       break;
70     case BF_ALIGN_RIGHT:
71       cp.dwFlags |= PES_RIGHT;
72       break;
73   }
74
75   if (!m_pFontMap) {
76     m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
77     m_pFontMap->Initial();
78   }
79   cp.pFontMap = m_pFontMap;
80   cp.pFocusHandler = this;
81
82   return cp;
83 }
84
85 CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
86                                        CPDFSDK_PageView* pPageView) {
87   CPWL_Edit* pWnd = new CPWL_Edit();
88   pWnd->AttachFFLData(this);
89   pWnd->Create(cp);
90
91   ASSERT(m_pApp != NULL);
92   CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
93   pWnd->SetFillerNotify(pIFormFiller);
94
95   ASSERT(m_pWidget != NULL);
96   int32_t nMaxLen = m_pWidget->GetMaxLen();
97   CFX_WideString swValue = m_pWidget->GetValue();
98
99   if (nMaxLen > 0) {
100     if (pWnd->HasFlag(PES_CHARARRAY)) {
101       pWnd->SetCharArray(nMaxLen);
102       pWnd->SetAlignFormatV(PEAV_CENTER);
103     } else {
104       pWnd->SetLimitChar(nMaxLen);
105     }
106   }
107
108   pWnd->SetText(swValue.c_str());
109   return pWnd;
110 }
111
112 FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
113                                FX_UINT nChar,
114                                FX_UINT nFlags) {
115   switch (nChar) {
116     case FWL_VKEY_Return:
117       if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
118         CPDFSDK_PageView* pPageView = GetCurPageView();
119         ASSERT(pPageView != NULL);
120         m_bValid = !m_bValid;
121         CPDF_Rect rcAnnot = pAnnot->GetRect();
122         m_pApp->FFI_Invalidate(pAnnot->GetPDFPage(), rcAnnot.left, rcAnnot.top,
123                                rcAnnot.right, rcAnnot.bottom);
124
125         if (m_bValid) {
126           if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
127             pWnd->SetFocus();
128         } else {
129           if (CommitData(pPageView, nFlags)) {
130             DestroyPDFWindow(pPageView);
131             return TRUE;
132           }
133           return FALSE;
134         }
135       }
136       break;
137     case FWL_VKEY_Escape: {
138       CPDFSDK_PageView* pPageView = GetCurPageView();
139       ASSERT(pPageView != NULL);
140       EscapeFiller(pPageView, TRUE);
141       return TRUE;
142     }
143   }
144
145   return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
146 }
147
148 FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
149   ASSERT(m_pWidget != NULL);
150
151   if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
152     return pEdit->GetText() != m_pWidget->GetValue();
153
154   return FALSE;
155 }
156
157 void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
158   ASSERT(m_pWidget != NULL);
159
160   if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
161     CFX_WideString sOldValue = m_pWidget->GetValue();
162     CFX_WideString sNewValue = pWnd->GetText();
163
164     m_pWidget->SetValue(sNewValue, FALSE);
165     m_pWidget->ResetFieldAppearance(TRUE);
166     m_pWidget->UpdateField();
167     SetChangeMark();
168   }
169 }
170
171 void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
172                                    CPDF_AAction::AActionType type,
173                                    PDFSDK_FieldAction& fa) {
174   switch (type) {
175     case CPDF_AAction::KeyStroke:
176       if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
177         fa.bFieldFull = pWnd->IsTextFull();
178
179         fa.sValue = pWnd->GetText();
180
181         if (fa.bFieldFull) {
182           fa.sChange = L"";
183           fa.sChangeEx = L"";
184         }
185       }
186       break;
187     case CPDF_AAction::Validate:
188       if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
189         fa.sValue = pWnd->GetText();
190       }
191       break;
192     case CPDF_AAction::LoseFocus:
193     case CPDF_AAction::GetFocus:
194       ASSERT(m_pWidget != NULL);
195       fa.sValue = m_pWidget->GetValue();
196       break;
197     default:
198       break;
199   }
200 }
201
202 void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
203                                    CPDF_AAction::AActionType type,
204                                    const PDFSDK_FieldAction& fa) {
205   switch (type) {
206     case CPDF_AAction::KeyStroke:
207       if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
208         pEdit->SetFocus();
209         pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
210         pEdit->ReplaceSel(fa.sChange.c_str());
211       }
212       break;
213     default:
214       break;
215   }
216 }
217
218 FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
219                                             const PDFSDK_FieldAction& faOld,
220                                             const PDFSDK_FieldAction& faNew) {
221   switch (type) {
222     case CPDF_AAction::KeyStroke:
223       return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
224              faOld.nSelStart != faNew.nSelStart ||
225              faOld.sChange != faNew.sChange;
226     default:
227       break;
228   }
229
230   return FALSE;
231 }
232
233 void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
234   ASSERT(pPageView != NULL);
235
236   if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
237     pWnd->GetSel(m_State.nStart, m_State.nEnd);
238     m_State.sValue = pWnd->GetText();
239   }
240 }
241
242 void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
243   ASSERT(pPageView != NULL);
244
245   if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
246     pWnd->SetText(m_State.sValue.c_str());
247     pWnd->SetSel(m_State.nStart, m_State.nEnd);
248   }
249 }
250
251 CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
252                                          FX_BOOL bRestoreValue) {
253   if (bRestoreValue)
254     SaveState(pPageView);
255
256   DestroyPDFWindow(pPageView);
257
258   CPWL_Wnd* pRet = NULL;
259
260   if (bRestoreValue) {
261     RestoreState(pPageView);
262     pRet = GetPDFWindow(pPageView, FALSE);
263   } else
264     pRet = GetPDFWindow(pPageView, TRUE);
265
266   m_pWidget->UpdateField();
267
268   return pRet;
269 }
270
271 void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
272   ASSERT(m_pApp != NULL);
273
274   ASSERT(pWnd != NULL);
275
276   if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
277     CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
278     pEdit->SetCharSet(134);
279     pEdit->SetCodePage(936);
280
281     pEdit->SetReadyToInput();
282     CFX_WideString wsText = pEdit->GetText();
283     int nCharacters = wsText.GetLength();
284     CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
285     unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
286     m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
287                                      nCharacters, TRUE);
288
289     pEdit->SetEditNotify(this);
290   }
291 }
292
293 void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd) {}
294
295 void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit) {}