blob: d24452fd45772f9b7baf015590775304636656f6 [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)
thestig1cd352e2016-06-07 17:53:06 -070014 : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(nullptr) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015 m_State.nStart = m_State.nEnd = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016}
17
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);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070021 delete m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022}
23
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
25 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 int nFlags = m_pWidget->GetFieldFlags();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029 if (nFlags & FIELDFLAG_PASSWORD) {
30 cp.dwFlags |= PES_PASSWORD;
31 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070032
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 if (nFlags & FIELDFLAG_MULTILINE) {
34 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
35
36 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
37 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070038 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 } else {
40 cp.dwFlags |= PES_CENTER;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070041
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) {
43 cp.dwFlags |= PES_AUTOSCROLL;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070044 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 if (nFlags & FIELDFLAG_COMB) {
48 cp.dwFlags |= PES_CHARARRAY;
49 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 if (nFlags & FIELDFLAG_RICHTEXT) {
52 cp.dwFlags |= PES_RICH;
53 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 cp.dwFlags |= PES_UNDO;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070056
Nico Weber9d8ec5a2015-08-04 13:00:21 -070057 switch (m_pWidget->GetAlignment()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070058 default:
59 case BF_ALIGN_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 cp.dwFlags |= PES_LEFT;
61 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070062 case BF_ALIGN_MIDDLE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 cp.dwFlags |= PES_MIDDLE;
64 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070065 case BF_ALIGN_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 cp.dwFlags |= PES_RIGHT;
67 break;
68 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
Lei Zhangfcfa3b82015-12-24 21:07:28 -080070 if (!m_pFontMap)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 cp.pFontMap = m_pFontMap;
73 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp,
79 CPDFSDK_PageView* pPageView) {
80 CPWL_Edit* pWnd = new CPWL_Edit();
81 pWnd->AttachFFLData(this);
82 pWnd->Create(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070083
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084 CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
85 pWnd->SetFillerNotify(pIFormFiller);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070086
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 int32_t nMaxLen = m_pWidget->GetMaxLen();
88 CFX_WideString swValue = m_pWidget->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 if (nMaxLen > 0) {
91 if (pWnd->HasFlag(PES_CHARARRAY)) {
92 pWnd->SetCharArray(nMaxLen);
93 pWnd->SetAlignFormatV(PEAV_CENTER);
94 } else {
95 pWnd->SetLimitChar(nMaxLen);
96 }
97 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099 pWnd->SetText(swValue.c_str());
100 return pWnd;
101}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700102
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
104 FX_UINT nChar,
105 FX_UINT nFlags) {
106 switch (nChar) {
107 case FWL_VKEY_Return:
108 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
dsinclair461eeaf2016-07-27 07:40:05 -0700109 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800110 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 m_bValid = !m_bValid;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800112 CFX_FloatRect rcAnnot = pAnnot->GetRect();
Tom Sepez1b246282015-11-25 15:15:31 -0800113 m_pApp->FFI_Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114 rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
115
116 if (m_bValid) {
117 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
118 pWnd->SetFocus();
119 } else {
120 if (CommitData(pPageView, nFlags)) {
121 DestroyPDFWindow(pPageView);
122 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 }
Tom Sepez468e5892015-10-13 15:49:36 -0700124 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700125 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 }
127 break;
128 case FWL_VKEY_Escape: {
dsinclair461eeaf2016-07-27 07:40:05 -0700129 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Lei Zhang96660d62015-12-14 18:27:25 -0800130 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 EscapeFiller(pPageView, TRUE);
132 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700133 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700135
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700137}
138
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
141 return pEdit->GetText() != m_pWidget->GetValue();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700144}
145
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
148 CFX_WideString sOldValue = m_pWidget->GetValue();
149 CFX_WideString sNewValue = pWnd->GetText();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700150
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 m_pWidget->SetValue(sNewValue, FALSE);
152 m_pWidget->ResetFieldAppearance(TRUE);
153 m_pWidget->UpdateField();
154 SetChangeMark();
155 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156}
157
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView,
159 CPDF_AAction::AActionType type,
160 PDFSDK_FieldAction& fa) {
161 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700162 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
164 fa.bFieldFull = pWnd->IsTextFull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 fa.sValue = pWnd->GetText();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700167
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 if (fa.bFieldFull) {
169 fa.sChange = L"";
170 fa.sChangeEx = L"";
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700171 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 }
173 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700174 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
176 fa.sValue = pWnd->GetText();
177 }
178 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700179 case CPDF_AAction::LoseFocus:
180 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 fa.sValue = m_pWidget->GetValue();
182 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700183 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 break;
185 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186}
187
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView,
189 CPDF_AAction::AActionType type,
190 const PDFSDK_FieldAction& fa) {
191 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700192 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
194 pEdit->SetFocus();
195 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
196 pEdit->ReplaceSel(fa.sChange.c_str());
197 }
198 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700199 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 break;
201 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
205 const PDFSDK_FieldAction& faOld,
206 const PDFSDK_FieldAction& faNew) {
207 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700208 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
210 faOld.nSelStart != faNew.nSelStart ||
211 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700212 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 break;
214 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217}
218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800220 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
223 pWnd->GetSel(m_State.nStart, m_State.nEnd);
224 m_State.sValue = pWnd->GetText();
225 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226}
227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800229 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
232 pWnd->SetText(m_State.sValue.c_str());
233 pWnd->SetSel(m_State.nStart, m_State.nEnd);
234 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
238 FX_BOOL bRestoreValue) {
239 if (bRestoreValue)
240 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700241
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 DestroyPDFWindow(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243
thestig1cd352e2016-06-07 17:53:06 -0700244 CPWL_Wnd* pRet = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 if (bRestoreValue) {
247 RestoreState(pPageView);
248 pRet = GetPDFWindow(pPageView, FALSE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800249 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 pRet = GetPDFWindow(pPageView, TRUE);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800251 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 m_pWidget->UpdateField();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700254
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 return pRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256}
257
Tom Sepez51da0932015-11-25 16:05:49 -0800258#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
260 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
261 return pWnd->IsTextFull();
262 }
Bo Xufdc00a72014-10-28 23:03:33 -0700263
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 return FALSE;
Bo Xufdc00a72014-10-28 23:03:33 -0700265}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800266#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700267
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
Lei Zhang96660d62015-12-14 18:27:25 -0800269 ASSERT(m_pApp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
271 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700272 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 pEdit->SetCodePage(936);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 pEdit->SetReadyToInput();
276 CFX_WideString wsText = pEdit->GetText();
277 int nCharacters = wsText.GetLength();
278 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
279 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
280 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
281 nCharacters, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}