blob: 611da7438a5d39eb29bcaffd695720731a861071 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairedbb3192016-03-21 09:08:24 -04007#include "fpdfsdk/formfiller/cffl_textfield.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07008
Dan Sinclairedbb3192016-03-21 09:08:24 -04009#include "fpdfsdk/formfiller/cba_fontmap.h"
dsinclair79db6092016-09-14 07:27:21 -070010#include "fpdfsdk/include/cpdfsdk_environment.h"
jaepark611adb82016-08-17 11:34:36 -070011#include "fpdfsdk/include/cpdfsdk_widget.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080012#include "fpdfsdk/include/fsdk_common.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
dsinclair79db6092016-09-14 07:27:21 -070014CFFL_TextField::CFFL_TextField(CPDFSDK_Environment* pApp, CPDFSDK_Annot* pAnnot)
weili2d5b0202016-08-03 11:06:49 -070015 : CFFL_FormFiller(pApp, pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017CFFL_TextField::~CFFL_TextField() {
Lei Zhangab5537d2016-01-06 14:58:14 -080018 for (const auto& it : m_Maps)
19 it.second->InvalidateFocusHandler(this);
dsinclair28a4a242016-08-22 13:36:02 -070020
21 // See comment in cffl_formfiller.h.
22 // The font map should be stored somewhere more appropriate so it will live
23 // until the PWL_Edit is done with it. pdfium:566
24 DestroyWindows();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070025}
26
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
28 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032 if (nFlags & FIELDFLAG_PASSWORD) {
33 cp.dwFlags |= PES_PASSWORD;
34 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070035
Nico Weber9d8ec5a2015-08-04 13:00:21 -070036 if (nFlags & FIELDFLAG_MULTILINE) {
37 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
38
39 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
40 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070041 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 } else {
43 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
46 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070047 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050 if (nFlags & FIELDFLAG_COMB) {
51 cp.dwFlags |= PES_CHARARRAY;
52 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054 if (nFlags & FIELDFLAG_RICHTEXT) {
55 cp.dwFlags |= PES_RICH;
56 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070061 default:
62 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 cp.dwFlags |= PES_LEFT;
64 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070065 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 cp.dwFlags |= PES_MIDDLE;
67 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070068 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069 cp.dwFlags |= PES_RIGHT;
70 break;
71 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072
Lei Zhangfcfa3b82015-12-24 21:07:28 -080073 if (!m_pFontMap)
dsinclair5819e4f2016-09-21 10:14:10 -070074 m_pFontMap.reset(new CBA_FontMap(m_pWidget, m_pEnv->GetSysHandler()));
weili2d5b0202016-08-03 11:06:49 -070075 cp.pFontMap = m_pFontMap.get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070077
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070079}
80
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
82 CPDFSDK_PageView* pPageView) {
83 CPWL_Edit* pWnd = new CPWL_Edit();
84 pWnd->AttachFFLData(this);
85 pWnd->Create(cp);
dsinclairb94d7c92016-09-21 12:07:00 -070086 pWnd->SetFillerNotify(m_pEnv->GetInteractiveFormFiller());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 int32_t nMaxLen = m_pWidget->GetMaxLen();
89 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 if (nMaxLen > 0) {
92 if (pWnd->HasFlag(PES_CHARARRAY)) {
93 pWnd->SetCharArray(nMaxLen);
94 pWnd->SetAlignFormatV(PEAV_CENTER);
95 } else {
96 pWnd->SetLimitChar(nMaxLen);
97 }
98 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099
tsepez067990c2016-09-13 06:46:40 -0700100 pWnd->SetText(swValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101 return pWnd;
102}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
dsinclair72177da2016-09-15 12:07:23 -0700105 uint32_t nChar,
106 uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 switch (nChar) {
108 case FWL_VKEY_Return:
109 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700110 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800111 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800113 CFX_FloatRect rcAnnot = pAnnot->GetRect();
dsinclair5819e4f2016-09-21 10:14:10 -0700114 m_pEnv->Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
dsinclair1f248902016-09-14 10:38:17 -0700115 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116
117 if (m_bValid) {
118 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
119 pWnd->SetFocus();
120 } else {
121 if (CommitData(pPageView, nFlags)) {
122 DestroyPDFWindow(pPageView);
123 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 }
Tom Sepez468e5892015-10-13 15:49:36 -0700125 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700126 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 }
128 break;
129 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700130 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800131 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 EscapeFiller(pPageView, TRUE);
133 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700134 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700136
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138}
139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
142 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700143
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145}
146
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
149 CFX_WideString sOldValue = m_pWidget->GetValue();
150 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700151
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 m_pWidget->SetValue(sNewValue, FALSE);
153 m_pWidget->ResetFieldAppearance(TRUE);
154 m_pWidget->UpdateField();
155 SetChangeMark();
156 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700157}
158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
160 CPDF_AAction::AActionType type,
161 PDFSDK_FieldAction& fa) {
162 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700163 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
165 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700168
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 if (fa.bFieldFull) {
170 fa.sChange = L"";
171 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700172 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 }
174 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700175 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
177 fa.sValue = pWnd->GetText();
178 }
179 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700180 case CPDF_AAction::LoseFocus:
181 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 fa.sValue = m_pWidget->GetValue();
183 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700184 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 break;
186 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700187}
188
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
190 CPDF_AAction::AActionType type,
191 const PDFSDK_FieldAction& fa) {
192 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700193 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
195 pEdit->SetFocus();
196 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
tsepez067990c2016-09-13 06:46:40 -0700197 pEdit->ReplaceSel(fa.sChange);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 }
199 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700200 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 break;
202 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700203}
204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
206 const PDFSDK_FieldAction& faOld,
207 const PDFSDK_FieldAction& faNew) {
208 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700209 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
211 faOld.nSelStart != faNew.nSelStart ||
212 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700213 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 break;
215 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700216
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218}
219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800221 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
224 pWnd->GetSel(m_State.nStart, m_State.nEnd);
225 m_State.sValue = pWnd->GetText();
226 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227}
228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800230 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
tsepez067990c2016-09-13 06:46:40 -0700233 pWnd->SetText(m_State.sValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 pWnd->SetSel(m_State.nStart, m_State.nEnd);
235 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236}
237
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700238CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
239 FX_BOOL bRestoreValue) {
240 if (bRestoreValue)
241 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700244
thestig1cd352e2016-06-07 17:53:06 -0700245 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700246
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 if (bRestoreValue) {
248 RestoreState(pPageView);
249 pRet = GetPDFWindow(pPageView, FALSE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800250 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 pRet = GetPDFWindow(pPageView, TRUE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800252 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700255
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700257}
258
Tom Sepez51da0932015-11-25 16:05:49 -0800259#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
261 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
262 return pWnd->IsTextFull();
263 }
Bo Xufdc00a72014-10-28 23:03:33 -0700264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265 return FALSE;
Bo Xufdc00a72014-10-28 23:03:33 -0700266}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800267#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700268
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
dsinclair5819e4f2016-09-21 10:14:10 -0700270 ASSERT(m_pEnv);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
272 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700273 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700275
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 pEdit->SetReadyToInput();
277 CFX_WideString wsText = pEdit->GetText();
278 int nCharacters = wsText.GetLength();
279 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
280 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
dsinclair577ad2c2016-09-22 10:20:43 -0700281 m_pEnv->OnSetFieldInputFocus(pBuffer, nCharacters, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}