blob: c1cd7868c8c2e413274a8c32340362d0c3f911f8 [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
dsinclair735606d2016-10-05 15:47:02 -07009#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
dsinclair114e46a2016-09-29 17:18:21 -070010#include "fpdfsdk/cpdfsdk_widget.h"
Dan Sinclairedbb3192016-03-21 09:08:24 -040011#include "fpdfsdk/formfiller/cba_fontmap.h"
dsinclair114e46a2016-09-29 17:18:21 -070012#include "fpdfsdk/fsdk_common.h"
tsepez36eb4bd2016-10-03 15:24:27 -070013#include "third_party/base/ptr_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
dsinclair735606d2016-10-05 15:47:02 -070015CFFL_TextField::CFFL_TextField(CPDFSDK_FormFillEnvironment* pApp,
16 CPDFSDK_Annot* pAnnot)
weili2d5b0202016-08-03 11:06:49 -070017 : CFFL_FormFiller(pApp, pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070018
Nico Weber9d8ec5a2015-08-04 13:00:21 -070019CFFL_TextField::~CFFL_TextField() {
Lei Zhangab5537d2016-01-06 14:58:14 -080020 for (const auto& it : m_Maps)
21 it.second->InvalidateFocusHandler(this);
dsinclair28a4a242016-08-22 13:36:02 -070022
23 // See comment in cffl_formfiller.h.
24 // The font map should be stored somewhere more appropriate so it will live
25 // until the PWL_Edit is done with it. pdfium:566
26 DestroyWindows();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027}
28
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
30 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033
Nico Weber9d8ec5a2015-08-04 13:00:21 -070034 if (nFlags & FIELDFLAG_PASSWORD) {
35 cp.dwFlags |= PES_PASSWORD;
36 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070037
Nico Weber9d8ec5a2015-08-04 13:00:21 -070038 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;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070043 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 } else {
45 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
48 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070049 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052 if (nFlags & FIELDFLAG_COMB) {
53 cp.dwFlags |= PES_CHARARRAY;
54 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070055
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 if (nFlags & FIELDFLAG_RICHTEXT) {
57 cp.dwFlags |= PES_RICH;
58 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070063 default:
64 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 cp.dwFlags |= PES_LEFT;
66 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070067 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068 cp.dwFlags |= PES_MIDDLE;
69 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070070 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 cp.dwFlags |= PES_RIGHT;
72 break;
73 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
thestigd4c34f22016-09-28 17:04:51 -070075 if (!m_pFontMap) {
dsinclair8779fa82016-10-12 12:05:44 -070076 m_pFontMap = pdfium::MakeUnique<CBA_FontMap>(
77 m_pWidget, m_pFormFillEnv->GetSysHandler());
thestigd4c34f22016-09-28 17:04:51 -070078 }
weili2d5b0202016-08-03 11:06:49 -070079 cp.pFontMap = m_pFontMap.get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083}
84
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085CPWL_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);
dsinclair8779fa82016-10-12 12:05:44 -070090 pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070091
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 int32_t nMaxLen = m_pWidget->GetMaxLen();
93 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070094
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 if (nMaxLen > 0) {
96 if (pWnd->HasFlag(PES_CHARARRAY)) {
97 pWnd->SetCharArray(nMaxLen);
98 pWnd->SetAlignFormatV(PEAV_CENTER);
99 } else {
100 pWnd->SetLimitChar(nMaxLen);
101 }
102 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700103
tsepez067990c2016-09-13 06:46:40 -0700104 pWnd->SetText(swValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 return pWnd;
106}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700107
tsepez4cf55152016-11-02 14:37:54 -0700108bool CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
109 uint32_t nChar,
110 uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 switch (nChar) {
112 case FWL_VKEY_Return:
113 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700114 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800115 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800117 CFX_FloatRect rcAnnot = pAnnot->GetRect();
dsinclair8779fa82016-10-12 12:05:44 -0700118 m_pFormFillEnv->Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
119 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120
121 if (m_bValid) {
tsepez4cf55152016-11-02 14:37:54 -0700122 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 pWnd->SetFocus();
124 } else {
125 if (CommitData(pPageView, nFlags)) {
126 DestroyPDFWindow(pPageView);
tsepez4cf55152016-11-02 14:37:54 -0700127 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 }
tsepez4cf55152016-11-02 14:37:54 -0700129 return false;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700130 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 }
132 break;
133 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700134 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800135 ASSERT(pPageView);
tsepez4cf55152016-11-02 14:37:54 -0700136 EscapeFiller(pPageView, true);
137 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700138 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700140
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142}
143
tsepez4cf55152016-11-02 14:37:54 -0700144bool CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
145 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, false))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700147
tsepez4cf55152016-11-02 14:37:54 -0700148 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700149}
150
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
tsepez4cf55152016-11-02 14:37:54 -0700152 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 CFX_WideString sOldValue = m_pWidget->GetValue();
154 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700155
tsepez4cf55152016-11-02 14:37:54 -0700156 m_pWidget->SetValue(sNewValue, false);
157 m_pWidget->ResetFieldAppearance(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 m_pWidget->UpdateField();
159 SetChangeMark();
160 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700161}
162
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
164 CPDF_AAction::AActionType type,
165 PDFSDK_FieldAction& fa) {
166 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700167 case CPDF_AAction::KeyStroke:
tsepez4cf55152016-11-02 14:37:54 -0700168 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700172
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (fa.bFieldFull) {
174 fa.sChange = L"";
175 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700176 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 }
178 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700179 case CPDF_AAction::Validate:
tsepez4cf55152016-11-02 14:37:54 -0700180 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 fa.sValue = pWnd->GetText();
182 }
183 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700184 case CPDF_AAction::LoseFocus:
185 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 fa.sValue = m_pWidget->GetValue();
187 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700188 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189 break;
190 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700191}
192
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
194 CPDF_AAction::AActionType type,
195 const PDFSDK_FieldAction& fa) {
196 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700197 case CPDF_AAction::KeyStroke:
tsepez4cf55152016-11-02 14:37:54 -0700198 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199 pEdit->SetFocus();
200 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
tsepez067990c2016-09-13 06:46:40 -0700201 pEdit->ReplaceSel(fa.sChange);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 }
203 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700204 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 break;
206 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700207}
208
tsepez4cf55152016-11-02 14:37:54 -0700209bool CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
210 const PDFSDK_FieldAction& faOld,
211 const PDFSDK_FieldAction& faNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700213 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
215 faOld.nSelStart != faNew.nSelStart ||
216 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700217 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 break;
219 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700220
tsepez4cf55152016-11-02 14:37:54 -0700221 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222}
223
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800225 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226
tsepez4cf55152016-11-02 14:37:54 -0700227 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 pWnd->GetSel(m_State.nStart, m_State.nEnd);
229 m_State.sValue = pWnd->GetText();
230 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231}
232
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800234 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235
tsepez4cf55152016-11-02 14:37:54 -0700236 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, true)) {
tsepez067990c2016-09-13 06:46:40 -0700237 pWnd->SetText(m_State.sValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700238 pWnd->SetSel(m_State.nStart, m_State.nEnd);
239 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240}
241
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
tsepez4cf55152016-11-02 14:37:54 -0700243 bool bRestoreValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 if (bRestoreValue)
245 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700246
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700248
thestig1cd352e2016-06-07 17:53:06 -0700249 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 if (bRestoreValue) {
252 RestoreState(pPageView);
tsepez4cf55152016-11-02 14:37:54 -0700253 pRet = GetPDFWindow(pPageView, false);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800254 } else {
tsepez4cf55152016-11-02 14:37:54 -0700255 pRet = GetPDFWindow(pPageView, true);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800256 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700257
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700259
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261}
262
Tom Sepez51da0932015-11-25 16:05:49 -0800263#ifdef PDF_ENABLE_XFA
tsepez4cf55152016-11-02 14:37:54 -0700264bool CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
265 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 return pWnd->IsTextFull();
267 }
Bo Xufdc00a72014-10-28 23:03:33 -0700268
tsepez4cf55152016-11-02 14:37:54 -0700269 return false;
Bo Xufdc00a72014-10-28 23:03:33 -0700270}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800271#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700272
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
dsinclair8779fa82016-10-12 12:05:44 -0700274 ASSERT(m_pFormFillEnv);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
276 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700277 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700279
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 pEdit->SetReadyToInput();
281 CFX_WideString wsText = pEdit->GetText();
282 int nCharacters = wsText.GetLength();
283 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
284 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
tsepez4cf55152016-11-02 14:37:54 -0700285 m_pFormFillEnv->OnSetFieldInputFocus(pBuffer, nCharacters, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700287}