blob: 76f4b7414d136c2315190b5ddb21faa3af252258 [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"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080010#include "fpdfsdk/include/fsdk_common.h"
11#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070012
Nico Weber9d8ec5a2015-08-04 13:00:21 -070013CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
weili2d5b0202016-08-03 11:06:49 -070014 : CFFL_FormFiller(pApp, pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015
Nico Weber9d8ec5a2015-08-04 13:00:21 -070016CFFL_TextField::~CFFL_TextField() {
Lei Zhangab5537d2016-01-06 14:58:14 -080017 for (const auto& it : m_Maps)
18 it.second->InvalidateFocusHandler(this);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019}
20
Nico Weber9d8ec5a2015-08-04 13:00:21 -070021PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
22 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070025
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026 if (nFlags & FIELDFLAG_PASSWORD) {
27 cp.dwFlags |= PES_PASSWORD;
28 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030 if (nFlags & FIELDFLAG_MULTILINE) {
31 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
32
33 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
34 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070035 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070036 } else {
37 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
40 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070041 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 if (nFlags & FIELDFLAG_COMB) {
45 cp.dwFlags |= PES_CHARARRAY;
46 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 if (nFlags & FIELDFLAG_RICHTEXT) {
49 cp.dwFlags |= PES_RICH;
50 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070055 default:
56 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070057 cp.dwFlags |= PES_LEFT;
58 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070059 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 cp.dwFlags |= PES_MIDDLE;
61 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070062 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 cp.dwFlags |= PES_RIGHT;
64 break;
65 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066
Lei Zhangfcfa3b82015-12-24 21:07:28 -080067 if (!m_pFontMap)
weili2d5b0202016-08-03 11:06:49 -070068 m_pFontMap.reset(new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler()));
69 cp.pFontMap = m_pFontMap.get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070071
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073}
74
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
76 CPDFSDK_PageView* pPageView) {
77 CPWL_Edit* pWnd = new CPWL_Edit();
78 pWnd->AttachFFLData(this);
79 pWnd->Create(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
82 pWnd->SetFillerNotify(pIFormFiller);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084 int32_t nMaxLen = m_pWidget->GetMaxLen();
85 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070086
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 if (nMaxLen > 0) {
88 if (pWnd->HasFlag(PES_CHARARRAY)) {
89 pWnd->SetCharArray(nMaxLen);
90 pWnd->SetAlignFormatV(PEAV_CENTER);
91 } else {
92 pWnd->SetLimitChar(nMaxLen);
93 }
94 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 pWnd->SetText(swValue.c_str());
97 return pWnd;
98}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070099
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
101 FX_UINT nChar,
102 FX_UINT nFlags) {
103 switch (nChar) {
104 case FWL_VKEY_Return:
105 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700106 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800107 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800109 CFX_FloatRect rcAnnot = pAnnot->GetRect();
Tom Sepez1b246282015-11-25 15:15:31 -0800110 m_pApp->FFI_Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
112
113 if (m_bValid) {
114 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
115 pWnd->SetFocus();
116 } else {
117 if (CommitData(pPageView, nFlags)) {
118 DestroyPDFWindow(pPageView);
119 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 }
Tom Sepez468e5892015-10-13 15:49:36 -0700121 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700122 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 }
124 break;
125 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700126 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800127 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 EscapeFiller(pPageView, TRUE);
129 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700130 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700132
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700134}
135
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
138 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700141}
142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
145 CFX_WideString sOldValue = m_pWidget->GetValue();
146 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700147
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148 m_pWidget->SetValue(sNewValue, FALSE);
149 m_pWidget->ResetFieldAppearance(TRUE);
150 m_pWidget->UpdateField();
151 SetChangeMark();
152 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153}
154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
156 CPDF_AAction::AActionType type,
157 PDFSDK_FieldAction& fa) {
158 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700159 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
161 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700164
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 if (fa.bFieldFull) {
166 fa.sChange = L"";
167 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700168 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 }
170 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700171 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
173 fa.sValue = pWnd->GetText();
174 }
175 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700176 case CPDF_AAction::LoseFocus:
177 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 fa.sValue = m_pWidget->GetValue();
179 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700180 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 break;
182 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700183}
184
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
186 CPDF_AAction::AActionType type,
187 const PDFSDK_FieldAction& fa) {
188 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700189 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
191 pEdit->SetFocus();
192 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
193 pEdit->ReplaceSel(fa.sChange.c_str());
194 }
195 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700196 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 break;
198 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199}
200
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
202 const PDFSDK_FieldAction& faOld,
203 const PDFSDK_FieldAction& faNew) {
204 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700205 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
207 faOld.nSelStart != faNew.nSelStart ||
208 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700209 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 break;
211 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700212
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700214}
215
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800217 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
220 pWnd->GetSel(m_State.nStart, m_State.nEnd);
221 m_State.sValue = pWnd->GetText();
222 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800226 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
229 pWnd->SetText(m_State.sValue.c_str());
230 pWnd->SetSel(m_State.nStart, m_State.nEnd);
231 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700232}
233
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
235 FX_BOOL bRestoreValue) {
236 if (bRestoreValue)
237 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240
thestig1cd352e2016-06-07 17:53:06 -0700241 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 if (bRestoreValue) {
244 RestoreState(pPageView);
245 pRet = GetPDFWindow(pPageView, FALSE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800246 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 pRet = GetPDFWindow(pPageView, TRUE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800248 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700249
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700251
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253}
254
Tom Sepez51da0932015-11-25 16:05:49 -0800255#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
257 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
258 return pWnd->IsTextFull();
259 }
Bo Xufdc00a72014-10-28 23:03:33 -0700260
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 return FALSE;
Bo Xufdc00a72014-10-28 23:03:33 -0700262}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800263#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
Lei Zhang96660d62015-12-14 18:27:25 -0800266 ASSERT(m_pApp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
268 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700269 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700271
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 pEdit->SetReadyToInput();
273 CFX_WideString wsText = pEdit->GetText();
274 int nCharacters = wsText.GetLength();
275 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
276 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
277 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
278 nCharacters, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700280}