blob: aaa096a26173d3c77df2689ec18865509c106c7e [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"
jaepark611adb82016-08-17 11:34:36 -070010#include "fpdfsdk/include/cpdfsdk_widget.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080011#include "fpdfsdk/include/fsdk_common.h"
12#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
Nico Weber9d8ec5a2015-08-04 13:00:21 -070014CFFL_TextField::CFFL_TextField(CPDFDoc_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);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020}
21
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
23 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 if (nFlags & FIELDFLAG_PASSWORD) {
28 cp.dwFlags |= PES_PASSWORD;
29 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031 if (nFlags & FIELDFLAG_MULTILINE) {
32 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
33
34 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
35 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070036 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 } else {
38 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070039
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
41 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070042 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 if (nFlags & FIELDFLAG_COMB) {
46 cp.dwFlags |= PES_CHARARRAY;
47 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 if (nFlags & FIELDFLAG_RICHTEXT) {
50 cp.dwFlags |= PES_RICH;
51 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070056 default:
57 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 cp.dwFlags |= PES_LEFT;
59 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070060 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 cp.dwFlags |= PES_MIDDLE;
62 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070063 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 cp.dwFlags |= PES_RIGHT;
65 break;
66 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070067
Lei Zhangfcfa3b82015-12-24 21:07:28 -080068 if (!m_pFontMap)
weili2d5b0202016-08-03 11:06:49 -070069 m_pFontMap.reset(new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler()));
70 cp.pFontMap = m_pFontMap.get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074}
75
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
77 CPDFSDK_PageView* pPageView) {
78 CPWL_Edit* pWnd = new CPWL_Edit();
79 pWnd->AttachFFLData(this);
80 pWnd->Create(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
83 pWnd->SetFillerNotify(pIFormFiller);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 int32_t nMaxLen = m_pWidget->GetMaxLen();
86 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 if (nMaxLen > 0) {
89 if (pWnd->HasFlag(PES_CHARARRAY)) {
90 pWnd->SetCharArray(nMaxLen);
91 pWnd->SetAlignFormatV(PEAV_CENTER);
92 } else {
93 pWnd->SetLimitChar(nMaxLen);
94 }
95 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070096
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097 pWnd->SetText(swValue.c_str());
98 return pWnd;
99}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700100
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
102 FX_UINT nChar,
103 FX_UINT nFlags) {
104 switch (nChar) {
105 case FWL_VKEY_Return:
106 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700107 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800108 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800110 CFX_FloatRect rcAnnot = pAnnot->GetRect();
Tom Sepez1b246282015-11-25 15:15:31 -0800111 m_pApp->FFI_Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
113
114 if (m_bValid) {
115 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
116 pWnd->SetFocus();
117 } else {
118 if (CommitData(pPageView, nFlags)) {
119 DestroyPDFWindow(pPageView);
120 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 }
Tom Sepez468e5892015-10-13 15:49:36 -0700122 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700123 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 }
125 break;
126 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700127 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800128 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 EscapeFiller(pPageView, TRUE);
130 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700131 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700133
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135}
136
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
139 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700140
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142}
143
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
146 CFX_WideString sOldValue = m_pWidget->GetValue();
147 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 m_pWidget->SetValue(sNewValue, FALSE);
150 m_pWidget->ResetFieldAppearance(TRUE);
151 m_pWidget->UpdateField();
152 SetChangeMark();
153 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154}
155
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
157 CPDF_AAction::AActionType type,
158 PDFSDK_FieldAction& fa) {
159 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700160 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
162 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700163
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700165
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 if (fa.bFieldFull) {
167 fa.sChange = L"";
168 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700169 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 }
171 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700172 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
174 fa.sValue = pWnd->GetText();
175 }
176 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700177 case CPDF_AAction::LoseFocus:
178 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 fa.sValue = m_pWidget->GetValue();
180 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700181 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 break;
183 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184}
185
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
187 CPDF_AAction::AActionType type,
188 const PDFSDK_FieldAction& fa) {
189 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700190 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
192 pEdit->SetFocus();
193 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
194 pEdit->ReplaceSel(fa.sChange.c_str());
195 }
196 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700197 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 break;
199 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
203 const PDFSDK_FieldAction& faOld,
204 const PDFSDK_FieldAction& faNew) {
205 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700206 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
208 faOld.nSelStart != faNew.nSelStart ||
209 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700210 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 break;
212 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215}
216
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800218 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
221 pWnd->GetSel(m_State.nStart, m_State.nEnd);
222 m_State.sValue = pWnd->GetText();
223 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700224}
225
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800227 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
230 pWnd->SetText(m_State.sValue.c_str());
231 pWnd->SetSel(m_State.nStart, m_State.nEnd);
232 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
236 FX_BOOL bRestoreValue) {
237 if (bRestoreValue)
238 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700241
thestig1cd352e2016-06-07 17:53:06 -0700242 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 if (bRestoreValue) {
245 RestoreState(pPageView);
246 pRet = GetPDFWindow(pPageView, FALSE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800247 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 pRet = GetPDFWindow(pPageView, TRUE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800249 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254}
255
Tom Sepez51da0932015-11-25 16:05:49 -0800256#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
258 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
259 return pWnd->IsTextFull();
260 }
Bo Xufdc00a72014-10-28 23:03:33 -0700261
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 return FALSE;
Bo Xufdc00a72014-10-28 23:03:33 -0700263}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800264#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700265
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
Lei Zhang96660d62015-12-14 18:27:25 -0800267 ASSERT(m_pApp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
269 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700270 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700272
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 pEdit->SetReadyToInput();
274 CFX_WideString wsText = pEdit->GetText();
275 int nCharacters = wsText.GetLength();
276 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
277 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
278 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
279 nCharacters, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700281}