33fb751ff1b6e37bebd0fd7d9665a53bf8f1d4b0
[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 CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :
13         CFFL_FormFiller(pApp, pAnnot),
14         m_pFontMap(NULL)//,
15         //m_pSpellCheck(NULL)
16 {
17         m_State.nStart = m_State.nEnd = 0;
18 }
19
20 CFFL_TextField::~CFFL_TextField()
21 {
22         if (m_pFontMap)
23         {
24                 delete m_pFontMap;
25                 m_pFontMap = NULL;
26         }
27
28 }
29
30 PWL_CREATEPARAM CFFL_TextField::GetCreateParam()
31 {
32         PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
33
34         ASSERT(m_pWidget != NULL);
35         int nFlags = m_pWidget->GetFieldFlags();
36
37
38         if (nFlags & FIELDFLAG_PASSWORD)
39         {               
40                 cp.dwFlags |= PES_PASSWORD;
41         }
42
43         if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK))
44         {               
45         }
46
47         if (nFlags & FIELDFLAG_MULTILINE)
48         {               
49                 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
50
51                 if (!(nFlags & FIELDFLAG_DONOTSCROLL))
52                 {
53                         cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
54                 }
55         }
56         else
57         {
58                 cp.dwFlags |= PES_CENTER;
59
60                 if (!(nFlags & FIELDFLAG_DONOTSCROLL))
61                 {
62                         cp.dwFlags |= PES_AUTOSCROLL;
63                 }
64         }
65
66         if (nFlags & FIELDFLAG_COMB)
67         {               
68                 cp.dwFlags |= PES_CHARARRAY;
69         }
70
71         if (nFlags & FIELDFLAG_RICHTEXT)
72         {               
73                 cp.dwFlags |= PES_RICH;
74         }
75
76         cp.dwFlags |= PES_UNDO;
77         
78         switch (m_pWidget->GetAlignment())
79         {
80         default:
81         case BF_ALIGN_LEFT:
82                 cp.dwFlags |= PES_LEFT;
83                 break;
84         case BF_ALIGN_MIDDLE:
85                 cp.dwFlags |= PES_MIDDLE;
86                 break;
87         case BF_ALIGN_RIGHT:
88                 cp.dwFlags |= PES_RIGHT;
89                 break;
90         }
91
92         if (!m_pFontMap)
93         {
94                 m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
95                 m_pFontMap->Initial();
96         }
97         cp.pFontMap = m_pFontMap;
98         cp.pFocusHandler = this;
99
100         return cp;
101 }
102
103 CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
104 {
105         CPWL_Edit * pWnd = new CPWL_Edit();
106                 pWnd->AttachFFLData(this);
107         pWnd->Create(cp);
108
109
110
111         ASSERT(m_pApp != NULL);
112         CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
113         pWnd->SetFillerNotify(pIFormFiller);
114
115         ASSERT(m_pWidget != NULL);
116         int32_t nMaxLen = m_pWidget->GetMaxLen();
117         CFX_WideString swValue = m_pWidget->GetValue();
118         
119         if (nMaxLen > 0)
120         {
121                 if (pWnd->HasFlag(PES_CHARARRAY))
122                 {
123                         pWnd->SetCharArray(nMaxLen);
124                         pWnd->SetAlignFormatV(PEAV_CENTER);
125                 }
126                 else
127                 {
128                         pWnd->SetLimitChar(nMaxLen);
129                 }
130         }
131
132         pWnd->SetText(swValue.c_str());
133         return pWnd;
134 }
135
136
137 FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
138 {
139         switch (nChar)
140         {
141         case FWL_VKEY_Return:
142                 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE))
143                 {
144                         CPDFSDK_PageView* pPageView = GetCurPageView();
145                         ASSERT(pPageView != NULL);
146                         m_bValid = !m_bValid;
147                         CPDF_Rect rcAnnot = pAnnot->GetRect();
148                         m_pApp->FFI_Invalidate(pAnnot->GetPDFPage(), rcAnnot.left, rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
149  
150                         if (m_bValid)
151                         {
152                                 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
153                                         pWnd->SetFocus();
154                         }
155                         else
156                         {
157                                 if (CommitData(pPageView, nFlags))
158                                 {
159                                         DestroyPDFWindow(pPageView);
160                                         return TRUE;
161                                 }
162                                 else
163                                 {
164                                         return FALSE;
165                                 }
166                         }
167                 }
168                 break;
169         case FWL_VKEY_Escape:
170                 {
171                         CPDFSDK_PageView* pPageView = GetCurPageView();
172                         ASSERT(pPageView != NULL);
173                         EscapeFiller(pPageView,TRUE);
174                         return TRUE;
175                 }
176         }
177
178         return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
179 }
180
181 FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView)
182 {
183         ASSERT(m_pWidget != NULL);
184
185         if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
186                 return pEdit->GetText() != m_pWidget->GetValue();
187
188         return FALSE;
189 }
190
191 void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView)
192 {
193         ASSERT(m_pWidget != NULL);
194
195         if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
196         {
197                 CFX_WideString sOldValue = m_pWidget->GetValue();
198                 CFX_WideString sNewValue = pWnd->GetText();
199
200                 m_pWidget->SetValue(sNewValue, FALSE);  
201                 m_pWidget->ResetFieldAppearance(TRUE);
202                 m_pWidget->UpdateField();
203                 SetChangeMark();
204         }
205 }
206
207 void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
208                                                                         PDFSDK_FieldAction& fa)
209 {
210         switch (type)
211         {
212         case CPDF_AAction::KeyStroke:
213                 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
214                 {
215                         fa.bFieldFull = pWnd->IsTextFull();     
216
217                         fa.sValue = pWnd->GetText();
218                         
219                         if (fa.bFieldFull)
220                         {
221                                 fa.sChange = L"";
222                                 fa.sChangeEx = L"";
223                         }
224                 }
225                 break;
226         case CPDF_AAction::Validate:
227                 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
228                 {
229                         fa.sValue = pWnd->GetText();
230                 }
231                 break;
232         case CPDF_AAction::LoseFocus:
233         case CPDF_AAction::GetFocus:
234                 ASSERT(m_pWidget != NULL);
235                 fa.sValue = m_pWidget->GetValue();
236                 break;
237         default:
238                 break;
239         }
240 }
241
242 void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
243                                                                         const PDFSDK_FieldAction& fa)
244 {
245         switch (type)
246         {
247         case CPDF_AAction::KeyStroke:
248                 if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
249                 {
250                         pEdit->SetFocus();
251                         pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
252                         pEdit->ReplaceSel(fa.sChange.c_str());
253                 }
254                 break;
255         default:
256                 break;
257         }
258 }
259
260
261 FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
262                                                                         const PDFSDK_FieldAction& faNew)
263 {
264         switch (type)
265         {
266         case CPDF_AAction::KeyStroke:
267                 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
268                         faOld.sChange != faNew.sChange;
269         default:
270                 break;
271         }
272
273         return FALSE;
274 }
275
276 void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView)
277 {
278         ASSERT(pPageView != NULL);
279
280         if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
281         {
282                 pWnd->GetSel(m_State.nStart, m_State.nEnd);
283                 m_State.sValue = pWnd->GetText();
284         }
285 }
286
287 void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView)
288 {
289         ASSERT(pPageView != NULL);
290
291         if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE))
292         {
293                 pWnd->SetText(m_State.sValue.c_str());
294                 pWnd->SetSel(m_State.nStart, m_State.nEnd);
295         }
296 }
297
298 CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
299 {
300         if (bRestoreValue)
301                 SaveState(pPageView);
302
303         DestroyPDFWindow(pPageView);
304
305         CPWL_Wnd* pRet = NULL;
306
307         if (bRestoreValue)
308         {
309                 RestoreState(pPageView);
310                 pRet = GetPDFWindow(pPageView, FALSE);
311         }
312         else
313                 pRet = GetPDFWindow(pPageView, TRUE);
314
315         m_pWidget->UpdateField();
316         
317         return pRet;
318 }
319
320 void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd)
321 {
322         ASSERT(m_pApp != NULL);
323         
324         ASSERT(pWnd != NULL);
325  
326         if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
327         {
328                 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
329                 pEdit->SetCharSet(134);
330                 pEdit->SetCodePage(936);
331  
332                 pEdit->SetReadyToInput();
333                 CFX_WideString wsText = pEdit->GetText();
334                 int nCharacters = wsText.GetLength();
335                 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
336                 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
337                 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
338  
339                 pEdit->SetEditNotify(this);
340                 //pUndo->BeginEdit(pDocument);
341         }
342 }
343
344 void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd)
345 {
346
347 }
348
349 FX_BOOL CFFL_TextField::CanCopy(CPDFSDK_Document* pDocument)
350 {
351         return FALSE;
352 }
353
354 FX_BOOL CFFL_TextField::CanCut(CPDFSDK_Document* pDocument)
355 {
356         return FALSE;
357 }
358
359 FX_BOOL CFFL_TextField::CanPaste(CPDFSDK_Document* pDocument)
360 {
361         return FALSE;
362 }
363
364 void CFFL_TextField::DoCopy(CPDFSDK_Document* pDocument)
365 {
366
367 }
368
369 void CFFL_TextField::DoCut(CPDFSDK_Document* pDocument)
370 {
371 }
372
373 void CFFL_TextField::DoPaste(CPDFSDK_Document* pDocument)
374 {
375
376 }
377
378 void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit)
379 {
380 }
381