blob: c8438a3a282f88808338a0cbd0cb2981ab385e2a [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_combobox.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
dsinclair735606d2016-10-05 15:47:02 -07009#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
dsinclair114e46a2016-09-29 17:18:21 -070010#include "fpdfsdk/cpdfsdk_widget.h"
Dan Sinclairedbb3192016-03-21 09:08:24 -040011#include "fpdfsdk/formfiller/cba_fontmap.h"
12#include "fpdfsdk/formfiller/cffl_formfiller.h"
dsinclairb94d7c92016-09-21 12:07:00 -070013#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
dsinclair114e46a2016-09-29 17:18:21 -070014#include "fpdfsdk/fsdk_common.h"
dan sinclair89e904b2016-03-23 19:29:15 -040015#include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
dsinclair735606d2016-10-05 15:47:02 -070017CFFL_ComboBox::CFFL_ComboBox(CPDFSDK_FormFillEnvironment* pApp,
18 CPDFSDK_Annot* pAnnot)
thestig1cd352e2016-06-07 17:53:06 -070019 : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(nullptr) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020 m_State.nIndex = 0;
21 m_State.nStart = 0;
22 m_State.nEnd = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023}
24
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025CFFL_ComboBox::~CFFL_ComboBox() {
Lei Zhangab5537d2016-01-06 14:58:14 -080026 for (const auto& it : m_Maps)
27 it.second->InvalidateFocusHandler(this);
dsinclair28a4a242016-08-22 13:36:02 -070028
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();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 delete m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034}
35
Nico Weber9d8ec5a2015-08-04 13:00:21 -070036PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam() {
37 PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 int nFlags = m_pWidget->GetFieldFlags();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 if (nFlags & FIELDFLAG_EDIT) {
41 cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT;
42 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043
Lei Zhangfcfa3b82015-12-24 21:07:28 -080044 if (!m_pFontMap)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler());
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 cp.pFontMap = m_pFontMap;
47 cp.pFocusHandler = this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 return cp;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050}
51
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052CPWL_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);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057
dsinclair8779fa82016-10-12 12:05:44 -070058 CFFL_InteractiveFormFiller* pFormFiller =
59 m_pFormFillEnv->GetInteractiveFormFiller();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 pWnd->SetFillerNotify(pFormFiller);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 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);
Tom Sepez4f7bc042015-04-27 12:06:58 -070068
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069 for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
tsepez067990c2016-09-13 06:46:40 -070070 pWnd->AddString(m_pWidget->GetOptionLabel(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 }
Tom Sepez4f7bc042015-04-27 12:06:58 -070072
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 pWnd->SetSelect(nCurSel);
tsepez067990c2016-09-13 06:46:40 -070074 pWnd->SetText(swText);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 return pWnd;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
tsepez4cf55152016-11-02 14:37:54 -070078bool CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot,
79 uint32_t nChar,
80 uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
tsepez4cf55152016-11-02 14:37:54 -070084bool CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
85 CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 if (!pWnd)
tsepez4cf55152016-11-02 14:37:54 -070087 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 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) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800100 CPWL_ComboBox* pWnd =
tsepez4cf55152016-11-02 14:37:54 -0700101 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false));
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800102 if (!pWnd)
103 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800105 CFX_WideString swText = pWnd->GetText();
106 int32_t nCurSel = pWnd->GetSelect();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700107
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800108 bool bSetValue = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800110 if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
111 bSetValue = (nCurSel < 0) || (swText != m_pWidget->GetOptionLabel(nCurSel));
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700112
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800113 if (bSetValue) {
tsepez4cf55152016-11-02 14:37:54 -0700114 m_pWidget->SetValue(swText, false);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800115 } else {
116 m_pWidget->GetSelectedIndex(0);
tsepez4cf55152016-11-02 14:37:54 -0700117 m_pWidget->SetOptionSelection(nCurSel, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 }
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800119
tsepez4cf55152016-11-02 14:37:54 -0700120 m_pWidget->ResetFieldAppearance(true);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800121 m_pWidget->UpdateField();
122 SetChangeMark();
123
124 m_pWidget->GetPDFPage();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125}
126
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127void CFFL_ComboBox::GetActionData(CPDFSDK_PageView* pPageView,
128 CPDF_AAction::AActionType type,
129 PDFSDK_FieldAction& fa) {
130 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700131 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700133 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
Tom Sepezb4f00292015-11-23 09:13:33 -0800134 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 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();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (fa.bFieldFull) {
145 fa.sChange = L"";
146 fa.sChangeEx = L"";
147 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700148 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 }
150 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700151 case CPDF_AAction::Validate:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700153 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
Tom Sepezb4f00292015-11-23 09:13:33 -0800154 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 fa.sValue = pEdit->GetText();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700156 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 }
158 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700159 case CPDF_AAction::LoseFocus:
160 case CPDF_AAction::GetFocus:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 fa.sValue = m_pWidget->GetValue();
162 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700163 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 break;
165 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166}
167
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView,
169 CPDF_AAction::AActionType type,
170 const PDFSDK_FieldAction& fa) {
171 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700172 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700174 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
Tom Sepezb4f00292015-11-23 09:13:33 -0800175 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
tsepez067990c2016-09-13 06:46:40 -0700177 pEdit->ReplaceSel(fa.sChange);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700178 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 }
180 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700181 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 break;
183 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184}
185
tsepez4cf55152016-11-02 14:37:54 -0700186bool CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type,
187 const PDFSDK_FieldAction& faOld,
188 const PDFSDK_FieldAction& faNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189 switch (type) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700190 case CPDF_AAction::KeyStroke:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
192 faOld.nSelStart != faNew.nSelStart ||
193 faOld.sChange != faNew.sChange;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700194 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 break;
196 }
197
tsepez4cf55152016-11-02 14:37:54 -0700198 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199}
200
201void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800202 ASSERT(pPageView);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203
204 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700205 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 m_State.nIndex = pComboBox->GetSelect();
207
Tom Sepezb4f00292015-11-23 09:13:33 -0800208 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 pEdit->GetSel(m_State.nStart, m_State.nEnd);
210 m_State.sValue = pEdit->GetText();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700211 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213}
214
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView) {
Lei Zhang96660d62015-12-14 18:27:25 -0800216 ASSERT(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700219 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, true))) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800220 if (m_State.nIndex >= 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 pComboBox->SetSelect(m_State.nIndex);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800222 } else {
Tom Sepezb4f00292015-11-23 09:13:33 -0800223 if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
tsepez067990c2016-09-13 06:46:40 -0700224 pEdit->SetText(m_State.sValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 pEdit->SetSel(m_State.nStart, m_State.nEnd);
226 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700227 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229}
230
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
tsepez4cf55152016-11-02 14:37:54 -0700232 bool bRestoreValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233 if (bRestoreValue)
234 SaveState(pPageView);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 DestroyPDFWindow(pPageView);
237
thestig1cd352e2016-06-07 17:53:06 -0700238 CPWL_Wnd* pRet = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239
240 if (bRestoreValue) {
241 RestoreState(pPageView);
tsepez4cf55152016-11-02 14:37:54 -0700242 pRet = GetPDFWindow(pPageView, false);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800243 } else {
tsepez4cf55152016-11-02 14:37:54 -0700244 pRet = GetPDFWindow(pPageView, true);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800245 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246
247 m_pWidget->UpdateField();
248
249 return pRet;
250}
251
Tom Sepez51da0932015-11-25 16:05:49 -0800252#ifdef PDF_ENABLE_XFA
tsepez4cf55152016-11-02 14:37:54 -0700253bool CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700255 static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
Tom Sepezb4f00292015-11-23 09:13:33 -0800256 if (CPWL_Edit* pEdit = pComboBox->GetEdit())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 return pEdit->IsTextFull();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 }
tsepez4cf55152016-11-02 14:37:54 -0700259 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800261#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700262
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd) {
dsinclair8779fa82016-10-12 12:05:44 -0700264 ASSERT(m_pFormFillEnv);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700265
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
267 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
thestig907a5222016-06-21 14:38:27 -0700268 pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 pEdit->SetCodePage(936);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700270
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 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();
tsepez4cf55152016-11-02 14:37:54 -0700276 m_pFormFillEnv->OnSetFieldInputFocus(pBuffer, nCharacters, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 }
278}
279
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280CFX_WideString CFFL_ComboBox::GetSelectExportText() {
281 CFX_WideString swRet;
282
283 int nExport = -1;
dsinclair461eeaf2016-07-27 07:40:05 -0700284 CPDFSDK_PageView* pPageView = GetCurPageView(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 if (CPWL_ComboBox* pComboBox =
tsepez4cf55152016-11-02 14:37:54 -0700286 (CPWL_ComboBox*)GetPDFWindow(pPageView, false)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 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);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700295 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700298 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700299}