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