blob: ffb3785c3645906c7495e002a2765bcb7e2d13a9 [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
dsinclair114e46a2016-09-29 17:18:21 -07009#include "fpdfsdk/cpdfsdk_environment.h"
10#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
dsinclair79db6092016-09-14 07:27:21 -070015CFFL_TextField::CFFL_TextField(CPDFSDK_Environment* pApp, CPDFSDK_Annot* pAnnot)
weili2d5b0202016-08-03 11:06:49 -070016 : CFFL_FormFiller(pApp, pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018CFFL_TextField::~CFFL_TextField() {
Lei Zhangab5537d2016-01-06 14:58:14 -080019 for (const auto& it : m_Maps)
20 it.second->InvalidateFocusHandler(this);
dsinclair28a4a242016-08-22 13:36:02 -070021
22 // See comment in cffl_formfiller.h.
23 // The font map should be stored somewhere more appropriate so it will live
24 // until the PWL_Edit is done with it. pdfium:566
25 DestroyWindows();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026}
27
Nico Weber9d8ec5a2015-08-04 13:00:21 -070028PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
29 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070032
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 if (nFlags & FIELDFLAG_PASSWORD) {
34 cp.dwFlags |= PES_PASSWORD;
35 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070036
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 if (nFlags & FIELDFLAG_MULTILINE) {
38 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
39
40 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
41 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070042 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 } else {
44 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070045
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
47 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070048 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 if (nFlags & FIELDFLAG_COMB) {
52 cp.dwFlags |= PES_CHARARRAY;
53 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 if (nFlags & FIELDFLAG_RICHTEXT) {
56 cp.dwFlags |= PES_RICH;
57 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070058
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070060
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070062 default:
63 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 cp.dwFlags |= PES_LEFT;
65 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070066 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 cp.dwFlags |= PES_MIDDLE;
68 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070069 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 cp.dwFlags |= PES_RIGHT;
71 break;
72 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073
thestigd4c34f22016-09-28 17:04:51 -070074 if (!m_pFontMap) {
75 m_pFontMap =
tsepez36eb4bd2016-10-03 15:24:27 -070076 pdfium::MakeUnique<CBA_FontMap>(m_pWidget, m_pEnv->GetSysHandler());
thestigd4c34f22016-09-28 17:04:51 -070077 }
weili2d5b0202016-08-03 11:06:49 -070078 cp.pFontMap = m_pFontMap.get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
85 CPDFSDK_PageView* pPageView) {
86 CPWL_Edit* pWnd = new CPWL_Edit();
87 pWnd->AttachFFLData(this);
88 pWnd->Create(cp);
dsinclairb94d7c92016-09-21 12:07:00 -070089 pWnd->SetFillerNotify(m_pEnv->GetInteractiveFormFiller());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 int32_t nMaxLen = m_pWidget->GetMaxLen();
92 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070093
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094 if (nMaxLen > 0) {
95 if (pWnd->HasFlag(PES_CHARARRAY)) {
96 pWnd->SetCharArray(nMaxLen);
97 pWnd->SetAlignFormatV(PEAV_CENTER);
98 } else {
99 pWnd->SetLimitChar(nMaxLen);
100 }
101 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102
tsepez067990c2016-09-13 06:46:40 -0700103 pWnd->SetText(swValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 return pWnd;
105}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
dsinclair72177da2016-09-15 12:07:23 -0700108 uint32_t nChar,
109 uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 switch (nChar) {
111 case FWL_VKEY_Return:
112 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700113 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800114 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800116 CFX_FloatRect rcAnnot = pAnnot->GetRect();
dsinclair5819e4f2016-09-21 10:14:10 -0700117 m_pEnv->Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
dsinclair1f248902016-09-14 10:38:17 -0700118 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119
120 if (m_bValid) {
121 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
122 pWnd->SetFocus();
123 } else {
124 if (CommitData(pPageView, nFlags)) {
125 DestroyPDFWindow(pPageView);
126 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 }
Tom Sepez468e5892015-10-13 15:49:36 -0700128 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700129 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 }
131 break;
132 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700133 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800134 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 EscapeFiller(pPageView, TRUE);
136 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700137 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700141}
142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
145 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700146
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148}
149
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
152 CFX_WideString sOldValue = m_pWidget->GetValue();
153 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 m_pWidget->SetValue(sNewValue, FALSE);
156 m_pWidget->ResetFieldAppearance(TRUE);
157 m_pWidget->UpdateField();
158 SetChangeMark();
159 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700160}
161
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
163 CPDF_AAction::AActionType type,
164 PDFSDK_FieldAction& fa) {
165 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700166 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
168 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700169
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700171
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 if (fa.bFieldFull) {
173 fa.sChange = L"";
174 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700175 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 }
177 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700178 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
180 fa.sValue = pWnd->GetText();
181 }
182 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700183 case CPDF_AAction::LoseFocus:
184 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 fa.sValue = m_pWidget->GetValue();
186 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700187 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 break;
189 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190}
191
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
193 CPDF_AAction::AActionType type,
194 const PDFSDK_FieldAction& fa) {
195 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700196 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
198 pEdit->SetFocus();
199 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
tsepez067990c2016-09-13 06:46:40 -0700200 pEdit->ReplaceSel(fa.sChange);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 }
202 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700203 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 break;
205 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700206}
207
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
209 const PDFSDK_FieldAction& faOld,
210 const PDFSDK_FieldAction& faNew) {
211 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700212 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
214 faOld.nSelStart != faNew.nSelStart ||
215 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700216 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 break;
218 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221}
222
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800224 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
227 pWnd->GetSel(m_State.nStart, m_State.nEnd);
228 m_State.sValue = pWnd->GetText();
229 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230}
231
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800233 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
tsepez067990c2016-09-13 06:46:40 -0700236 pWnd->SetText(m_State.sValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237 pWnd->SetSel(m_State.nStart, m_State.nEnd);
238 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239}
240
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
242 FX_BOOL bRestoreValue) {
243 if (bRestoreValue)
244 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247
thestig1cd352e2016-06-07 17:53:06 -0700248 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700249
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 if (bRestoreValue) {
251 RestoreState(pPageView);
252 pRet = GetPDFWindow(pPageView, FALSE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800253 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 pRet = GetPDFWindow(pPageView, TRUE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800255 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700258
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}
261
Tom Sepez51da0932015-11-25 16:05:49 -0800262#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
264 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
265 return pWnd->IsTextFull();
266 }
Bo Xufdc00a72014-10-28 23:03:33 -0700267
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 return FALSE;
Bo Xufdc00a72014-10-28 23:03:33 -0700269}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800270#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700271
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
dsinclair5819e4f2016-09-21 10:14:10 -0700273 ASSERT(m_pEnv);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
275 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700276 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700278
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279 pEdit->SetReadyToInput();
280 CFX_WideString wsText = pEdit->GetText();
281 int nCharacters = wsText.GetLength();
282 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
283 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
dsinclair577ad2c2016-09-22 10:20:43 -0700284 m_pEnv->OnSetFieldInputFocus(pBuffer, nCharacters, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700286}