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