cffl_combobox.cpp revision 4d3acf4ec42bf6e838f9060103aff98fbf170794
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/formfiller/cffl_combobox.h" 8 9#include "fpdfsdk/cpdfsdk_formfillenvironment.h" 10#include "fpdfsdk/cpdfsdk_widget.h" 11#include "fpdfsdk/formfiller/cba_fontmap.h" 12#include "fpdfsdk/formfiller/cffl_formfiller.h" 13#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" 14#include "fpdfsdk/fsdk_common.h" 15#include "fpdfsdk/pdfwindow/PWL_ComboBox.h" 16 17CFFL_ComboBox::CFFL_ComboBox(CPDFSDK_FormFillEnvironment* pApp, 18 CPDFSDK_Annot* pAnnot) 19 : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(nullptr) { 20 m_State.nIndex = 0; 21 m_State.nStart = 0; 22 m_State.nEnd = 0; 23} 24 25CFFL_ComboBox::~CFFL_ComboBox() { 26 for (const auto& it : m_Maps) 27 it.second->InvalidateFocusHandler(this); 28 29 // See comment in cffl_formfiller.h. 30 // The font map should be stored somewhere more appropriate so it will live 31 // until the PWL_Edit is done with it. pdfium:566 32 DestroyWindows(); 33 delete m_pFontMap; 34} 35 36PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam() { 37 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam(); 38 39 int nFlags = m_pWidget->GetFieldFlags(); 40 if (nFlags & FIELDFLAG_EDIT) { 41 cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT; 42 } 43 44 if (!m_pFontMap) 45 m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler()); 46 cp.pFontMap = m_pFontMap; 47 cp.pFocusHandler = this; 48 49 return cp; 50} 51 52CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const PWL_CREATEPARAM& cp, 53 CPDFSDK_PageView* pPageView) { 54 CPWL_ComboBox* pWnd = new CPWL_ComboBox(); 55 pWnd->AttachFFLData(this); 56 pWnd->Create(cp); 57 58 CFFL_InteractiveFormFiller* pFormFiller = 59 m_pFormFillEnv->GetInteractiveFormFiller(); 60 pWnd->SetFillerNotify(pFormFiller); 61 62 int32_t nCurSel = m_pWidget->GetSelectedIndex(0); 63 CFX_WideString swText; 64 if (nCurSel < 0) 65 swText = m_pWidget->GetValue(); 66 else 67 swText = m_pWidget->GetOptionLabel(nCurSel); 68 69 for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) { 70 pWnd->AddString(m_pWidget->GetOptionLabel(i)); 71 } 72 73 pWnd->SetSelect(nCurSel); 74 pWnd->SetText(swText); 75 return pWnd; 76} 77 78bool CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot, 79 uint32_t nChar, 80 uint32_t nFlags) { 81 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags); 82} 83 84bool CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView) { 85 CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, false); 86 if (!pWnd) 87 return false; 88 89 int32_t nCurSel = pWnd->GetSelect(); 90 if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)) 91 return nCurSel != m_pWidget->GetSelectedIndex(0); 92 93 if (nCurSel >= 0) 94 return nCurSel != m_pWidget->GetSelectedIndex(0); 95 96 return pWnd->GetText() != m_pWidget->GetValue(); 97} 98 99void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView) { 100 CPWL_ComboBox* pWnd = 101 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false)); 102 if (!pWnd) 103 return; 104 105 CFX_WideString swText = pWnd->GetText(); 106 int32_t nCurSel = pWnd->GetSelect(); 107 108 bool bSetValue = false; 109 110 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT) 111 bSetValue = (nCurSel < 0) || (swText != m_pWidget->GetOptionLabel(nCurSel)); 112 113 if (bSetValue) { 114 m_pWidget->SetValue(swText, false); 115 } else { 116 m_pWidget->GetSelectedIndex(0); 117 m_pWidget->SetOptionSelection(nCurSel, true, false); 118 } 119 120 m_pWidget->ResetFieldAppearance(true); 121 m_pWidget->UpdateField(); 122 SetChangeMark(); 123 124 m_pWidget->GetPDFPage(); 125} 126 127void CFFL_ComboBox::GetActionData(CPDFSDK_PageView* pPageView, 128 CPDF_AAction::AActionType type, 129 PDFSDK_FieldAction& fa) { 130 switch (type) { 131 case CPDF_AAction::KeyStroke: 132 if (CPWL_ComboBox* pComboBox = 133 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) { 134 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) { 135 fa.bFieldFull = pEdit->IsTextFull(); 136 int nSelStart = 0; 137 int nSelEnd = 0; 138 pEdit->GetSel(nSelStart, nSelEnd); 139 fa.nSelEnd = nSelEnd; 140 fa.nSelStart = nSelStart; 141 fa.sValue = pEdit->GetText(); 142 fa.sChangeEx = GetSelectExportText(); 143 144 if (fa.bFieldFull) { 145 fa.sChange = L""; 146 fa.sChangeEx = L""; 147 } 148 } 149 } 150 break; 151 case CPDF_AAction::Validate: 152 if (CPWL_ComboBox* pComboBox = 153 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) { 154 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) { 155 fa.sValue = pEdit->GetText(); 156 } 157 } 158 break; 159 case CPDF_AAction::LoseFocus: 160 case CPDF_AAction::GetFocus: 161 fa.sValue = m_pWidget->GetValue(); 162 break; 163 default: 164 break; 165 } 166} 167 168void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView, 169 CPDF_AAction::AActionType type, 170 const PDFSDK_FieldAction& fa) { 171 switch (type) { 172 case CPDF_AAction::KeyStroke: 173 if (CPWL_ComboBox* pComboBox = 174 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) { 175 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) { 176 pEdit->SetSel(fa.nSelStart, fa.nSelEnd); 177 pEdit->ReplaceSel(fa.sChange); 178 } 179 } 180 break; 181 default: 182 break; 183 } 184} 185 186bool CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type, 187 const PDFSDK_FieldAction& faOld, 188 const PDFSDK_FieldAction& faNew) { 189 switch (type) { 190 case CPDF_AAction::KeyStroke: 191 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || 192 faOld.nSelStart != faNew.nSelStart || 193 faOld.sChange != faNew.sChange; 194 default: 195 break; 196 } 197 198 return false; 199} 200 201void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView) { 202 ASSERT(pPageView); 203 204 if (CPWL_ComboBox* pComboBox = 205 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) { 206 m_State.nIndex = pComboBox->GetSelect(); 207 208 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) { 209 pEdit->GetSel(m_State.nStart, m_State.nEnd); 210 m_State.sValue = pEdit->GetText(); 211 } 212 } 213} 214 215void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView) { 216 ASSERT(pPageView); 217 218 if (CPWL_ComboBox* pComboBox = 219 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, true))) { 220 if (m_State.nIndex >= 0) { 221 pComboBox->SetSelect(m_State.nIndex); 222 } else { 223 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) { 224 pEdit->SetText(m_State.sValue); 225 pEdit->SetSel(m_State.nStart, m_State.nEnd); 226 } 227 } 228 } 229} 230 231CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, 232 bool bRestoreValue) { 233 if (bRestoreValue) 234 SaveState(pPageView); 235 236 DestroyPDFWindow(pPageView); 237 238 CPWL_Wnd* pRet = nullptr; 239 240 if (bRestoreValue) { 241 RestoreState(pPageView); 242 pRet = GetPDFWindow(pPageView, false); 243 } else { 244 pRet = GetPDFWindow(pPageView, true); 245 } 246 247 m_pWidget->UpdateField(); 248 249 return pRet; 250} 251 252#ifdef PDF_ENABLE_XFA 253bool CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView) { 254 if (CPWL_ComboBox* pComboBox = 255 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) { 256 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) 257 return pEdit->IsTextFull(); 258 } 259 return false; 260} 261#endif // PDF_ENABLE_XFA 262 263void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd) { 264 ASSERT(m_pFormFillEnv); 265 266 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) { 267 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd; 268 pEdit->SetCharSet(FXFONT_GB2312_CHARSET); 269 pEdit->SetCodePage(936); 270 271 pEdit->SetReadyToInput(); 272 CFX_WideString wsText = pEdit->GetText(); 273 int nCharacters = wsText.GetLength(); 274 CFX_ByteString bsUTFText = wsText.UTF16LE_Encode(); 275 unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str(); 276 m_pFormFillEnv->OnSetFieldInputFocus(pBuffer, nCharacters, true); 277 } 278} 279 280CFX_WideString CFFL_ComboBox::GetSelectExportText() { 281 CFX_WideString swRet; 282 283 int nExport = -1; 284 CPDFSDK_PageView* pPageView = GetCurPageView(true); 285 if (CPWL_ComboBox* pComboBox = 286 (CPWL_ComboBox*)GetPDFWindow(pPageView, false)) { 287 nExport = pComboBox->GetSelect(); 288 } 289 290 if (nExport >= 0) { 291 if (CPDF_FormField* pFormField = m_pWidget->GetFormField()) { 292 swRet = pFormField->GetOptionValue(nExport); 293 if (swRet.IsEmpty()) 294 swRet = pFormField->GetOptionLabel(nExport); 295 } 296 } 297 298 return swRet; 299} 300