1 // 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. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "fpdfsdk/include/formfiller/FFL_TextField.h" 8 9 #include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h" 10 #include "fpdfsdk/include/fsdk_common.h" 11 #include "fpdfsdk/include/fsdk_mgr.h" 12 13 CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) 14 : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(NULL) { 15 m_State.nStart = m_State.nEnd = 0; 16 } 17 18 CFFL_TextField::~CFFL_TextField() { 19 for (const auto& it : m_Maps) 20 it.second->InvalidateFocusHandler(this); 21 delete m_pFontMap; 22 } 23 24 PWL_CREATEPARAM CFFL_TextField::GetCreateParam() { 25 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam(); 26 27 int nFlags = m_pWidget->GetFieldFlags(); 28 29 if (nFlags & FIELDFLAG_PASSWORD) { 30 cp.dwFlags |= PES_PASSWORD; 31 } 32 33 if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK)) { 34 } 35 36 if (nFlags & FIELDFLAG_MULTILINE) { 37 cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP; 38 39 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) { 40 cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL; 41 } 42 } else { 43 cp.dwFlags |= PES_CENTER; 44 45 if (!(nFlags & FIELDFLAG_DONOTSCROLL)) { 46 cp.dwFlags |= PES_AUTOSCROLL; 47 } 48 } 49 50 if (nFlags & FIELDFLAG_COMB) { 51 cp.dwFlags |= PES_CHARARRAY; 52 } 53 54 if (nFlags & FIELDFLAG_RICHTEXT) { 55 cp.dwFlags |= PES_RICH; 56 } 57 58 cp.dwFlags |= PES_UNDO; 59 60 switch (m_pWidget->GetAlignment()) { 61 default: 62 case BF_ALIGN_LEFT: 63 cp.dwFlags |= PES_LEFT; 64 break; 65 case BF_ALIGN_MIDDLE: 66 cp.dwFlags |= PES_MIDDLE; 67 break; 68 case BF_ALIGN_RIGHT: 69 cp.dwFlags |= PES_RIGHT; 70 break; 71 } 72 73 if (!m_pFontMap) 74 m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler()); 75 cp.pFontMap = m_pFontMap; 76 cp.pFocusHandler = this; 77 78 return cp; 79 } 80 81 CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp, 82 CPDFSDK_PageView* pPageView) { 83 CPWL_Edit* pWnd = new CPWL_Edit(); 84 pWnd->AttachFFLData(this); 85 pWnd->Create(cp); 86 87 CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller(); 88 pWnd->SetFillerNotify(pIFormFiller); 89 90 int32_t nMaxLen = m_pWidget->GetMaxLen(); 91 CFX_WideString swValue = m_pWidget->GetValue(); 92 93 if (nMaxLen > 0) { 94 if (pWnd->HasFlag(PES_CHARARRAY)) { 95 pWnd->SetCharArray(nMaxLen); 96 pWnd->SetAlignFormatV(PEAV_CENTER); 97 } else { 98 pWnd->SetLimitChar(nMaxLen); 99 } 100 } 101 102 pWnd->SetText(swValue.c_str()); 103 return pWnd; 104 } 105 106 FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, 107 FX_UINT nChar, 108 FX_UINT nFlags) { 109 switch (nChar) { 110 case FWL_VKEY_Return: 111 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) { 112 CPDFSDK_PageView* pPageView = GetCurPageView(); 113 ASSERT(pPageView); 114 m_bValid = !m_bValid; 115 CPDF_Rect rcAnnot = pAnnot->GetRect(); 116 m_pApp->FFI_Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left, 117 rcAnnot.top, rcAnnot.right, rcAnnot.bottom); 118 119 if (m_bValid) { 120 if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) 121 pWnd->SetFocus(); 122 } else { 123 if (CommitData(pPageView, nFlags)) { 124 DestroyPDFWindow(pPageView); 125 return TRUE; 126 } 127 return FALSE; 128 } 129 } 130 break; 131 case FWL_VKEY_Escape: { 132 CPDFSDK_PageView* pPageView = GetCurPageView(); 133 ASSERT(pPageView); 134 EscapeFiller(pPageView, TRUE); 135 return TRUE; 136 } 137 } 138 139 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags); 140 } 141 142 FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) { 143 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) 144 return pEdit->GetText() != m_pWidget->GetValue(); 145 146 return FALSE; 147 } 148 149 void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) { 150 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 151 CFX_WideString sOldValue = m_pWidget->GetValue(); 152 CFX_WideString sNewValue = pWnd->GetText(); 153 154 m_pWidget->SetValue(sNewValue, FALSE); 155 m_pWidget->ResetFieldAppearance(TRUE); 156 m_pWidget->UpdateField(); 157 SetChangeMark(); 158 } 159 } 160 161 void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView, 162 CPDF_AAction::AActionType type, 163 PDFSDK_FieldAction& fa) { 164 switch (type) { 165 case CPDF_AAction::KeyStroke: 166 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 167 fa.bFieldFull = pWnd->IsTextFull(); 168 169 fa.sValue = pWnd->GetText(); 170 171 if (fa.bFieldFull) { 172 fa.sChange = L""; 173 fa.sChangeEx = L""; 174 } 175 } 176 break; 177 case CPDF_AAction::Validate: 178 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 179 fa.sValue = pWnd->GetText(); 180 } 181 break; 182 case CPDF_AAction::LoseFocus: 183 case CPDF_AAction::GetFocus: 184 fa.sValue = m_pWidget->GetValue(); 185 break; 186 default: 187 break; 188 } 189 } 190 191 void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView, 192 CPDF_AAction::AActionType type, 193 const PDFSDK_FieldAction& fa) { 194 switch (type) { 195 case CPDF_AAction::KeyStroke: 196 if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 197 pEdit->SetFocus(); 198 pEdit->SetSel(fa.nSelStart, fa.nSelEnd); 199 pEdit->ReplaceSel(fa.sChange.c_str()); 200 } 201 break; 202 default: 203 break; 204 } 205 } 206 207 FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type, 208 const PDFSDK_FieldAction& faOld, 209 const PDFSDK_FieldAction& faNew) { 210 switch (type) { 211 case CPDF_AAction::KeyStroke: 212 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || 213 faOld.nSelStart != faNew.nSelStart || 214 faOld.sChange != faNew.sChange; 215 default: 216 break; 217 } 218 219 return FALSE; 220 } 221 222 void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) { 223 ASSERT(pPageView); 224 225 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 226 pWnd->GetSel(m_State.nStart, m_State.nEnd); 227 m_State.sValue = pWnd->GetText(); 228 } 229 } 230 231 void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) { 232 ASSERT(pPageView); 233 234 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) { 235 pWnd->SetText(m_State.sValue.c_str()); 236 pWnd->SetSel(m_State.nStart, m_State.nEnd); 237 } 238 } 239 240 CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView, 241 FX_BOOL bRestoreValue) { 242 if (bRestoreValue) 243 SaveState(pPageView); 244 245 DestroyPDFWindow(pPageView); 246 247 CPWL_Wnd* pRet = NULL; 248 249 if (bRestoreValue) { 250 RestoreState(pPageView); 251 pRet = GetPDFWindow(pPageView, FALSE); 252 } else { 253 pRet = GetPDFWindow(pPageView, TRUE); 254 } 255 256 m_pWidget->UpdateField(); 257 258 return pRet; 259 } 260 261 #ifdef PDF_ENABLE_XFA 262 FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) { 263 if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) { 264 return pWnd->IsTextFull(); 265 } 266 267 return FALSE; 268 } 269 #endif // PDF_ENABLE_XFA 270 271 void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) { 272 ASSERT(m_pApp); 273 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) { 274 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd; 275 pEdit->SetCharSet(134); 276 pEdit->SetCodePage(936); 277 278 pEdit->SetReadyToInput(); 279 CFX_WideString wsText = pEdit->GetText(); 280 int nCharacters = wsText.GetLength(); 281 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode(); 282 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str(); 283 m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, 284 nCharacters, TRUE); 285 286 pEdit->SetEditNotify(this); 287 } 288 } 289 290 void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd) {} 291 292 void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit) {} 293