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_interactiveformfiller.h"
8
9 #include "constants/form_flags.h"
10 #include "core/fpdfapi/page/cpdf_page.h"
11 #include "core/fxcrt/autorestorer.h"
12 #include "core/fxge/cfx_graphstatedata.h"
13 #include "core/fxge/cfx_pathdata.h"
14 #include "core/fxge/cfx_renderdevice.h"
15 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
16 #include "fpdfsdk/cpdfsdk_interactiveform.h"
17 #include "fpdfsdk/cpdfsdk_pageview.h"
18 #include "fpdfsdk/cpdfsdk_widget.h"
19 #include "fpdfsdk/formfiller/cffl_checkbox.h"
20 #include "fpdfsdk/formfiller/cffl_combobox.h"
21 #include "fpdfsdk/formfiller/cffl_formfiller.h"
22 #include "fpdfsdk/formfiller/cffl_listbox.h"
23 #include "fpdfsdk/formfiller/cffl_pushbutton.h"
24 #include "fpdfsdk/formfiller/cffl_radiobutton.h"
25 #include "fpdfsdk/formfiller/cffl_textfield.h"
26 #include "public/fpdf_fwlevent.h"
27 #include "third_party/base/ptr_util.h"
28 #include "third_party/base/stl_util.h"
29
CFFL_InteractiveFormFiller(CPDFSDK_FormFillEnvironment * pFormFillEnv)30 CFFL_InteractiveFormFiller::CFFL_InteractiveFormFiller(
31 CPDFSDK_FormFillEnvironment* pFormFillEnv)
32 : m_pFormFillEnv(pFormFillEnv) {}
33
34 CFFL_InteractiveFormFiller::~CFFL_InteractiveFormFiller() = default;
35
Annot_HitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)36 bool CFFL_InteractiveFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,
37 CPDFSDK_Annot* pAnnot,
38 const CFX_PointF& point) {
39 return pAnnot->GetRect().Contains(point);
40 }
41
GetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)42 FX_RECT CFFL_InteractiveFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
43 CPDFSDK_Annot* pAnnot) {
44 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot))
45 return pFormFiller->GetViewBBox(pPageView);
46
47 ASSERT(pPageView);
48
49 CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
50 CFX_FloatRect rcWin = pPDFAnnot->GetRect();
51 if (!rcWin.IsEmpty()) {
52 rcWin.Inflate(1, 1);
53 rcWin.Normalize();
54 }
55 return rcWin.GetOuterRect();
56 }
57
OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device)58 void CFFL_InteractiveFormFiller::OnDraw(CPDFSDK_PageView* pPageView,
59 CPDFSDK_Annot* pAnnot,
60 CFX_RenderDevice* pDevice,
61 const CFX_Matrix& mtUser2Device) {
62 ASSERT(pPageView);
63 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot);
64 if (!IsVisible(pWidget))
65 return;
66
67 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
68 if (pFormFiller && pFormFiller->IsValid()) {
69 pFormFiller->OnDraw(pPageView, pAnnot, pDevice, mtUser2Device);
70 pAnnot->GetPDFPage();
71 if (m_pFormFillEnv->GetFocusAnnot() != pAnnot)
72 return;
73
74 CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView);
75 if (rcFocus.IsEmpty())
76 return;
77
78 CFX_PathData path;
79 path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), FXPT_TYPE::MoveTo,
80 false);
81 path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.bottom),
82 FXPT_TYPE::LineTo, false);
83 path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.bottom),
84 FXPT_TYPE::LineTo, false);
85 path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.top), FXPT_TYPE::LineTo,
86 false);
87 path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), FXPT_TYPE::LineTo,
88 false);
89
90 CFX_GraphStateData gsd;
91 gsd.m_DashArray = {1.0f};
92 gsd.m_DashPhase = 0;
93 gsd.m_LineWidth = 1.0f;
94 pDevice->DrawPath(&path, &mtUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0),
95 FXFILL_ALTERNATE);
96 return;
97 }
98
99 if (pFormFiller) {
100 pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, mtUser2Device);
101 } else {
102 pWidget->DrawAppearance(pDevice, mtUser2Device, CPDF_Annot::Normal,
103 nullptr);
104 }
105
106 if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
107 pWidget->DrawShadow(pDevice, pPageView);
108 }
109
OnDelete(CPDFSDK_Annot * pAnnot)110 void CFFL_InteractiveFormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {
111 UnRegisterFormFiller(pAnnot);
112 }
113
OnMouseEnter(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)114 void CFFL_InteractiveFormFiller::OnMouseEnter(
115 CPDFSDK_PageView* pPageView,
116 ObservedPtr<CPDFSDK_Annot>* pAnnot,
117 uint32_t nFlag) {
118 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
119 if (!m_bNotifying) {
120 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
121 if (pWidget->GetAAction(CPDF_AAction::kCursorEnter).GetDict()) {
122 m_bNotifying = true;
123
124 uint32_t nValueAge = pWidget->GetValueAge();
125 pWidget->ClearAppModified();
126 ASSERT(pPageView);
127
128 CPDFSDK_FieldAction fa;
129 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
130 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
131 pWidget->OnAAction(CPDF_AAction::kCursorEnter, &fa, pPageView);
132 m_bNotifying = false;
133 if (!pAnnot->HasObservable())
134 return;
135
136 if (pWidget->IsAppModified()) {
137 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget)) {
138 pFormFiller->ResetPWLWindow(pPageView,
139 pWidget->GetValueAge() == nValueAge);
140 }
141 }
142 }
143 }
144 if (CFFL_FormFiller* pFormFiller = GetOrCreateFormFiller(pAnnot->Get()))
145 pFormFiller->OnMouseEnter(pPageView);
146 }
147
OnMouseExit(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)148 void CFFL_InteractiveFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
149 ObservedPtr<CPDFSDK_Annot>* pAnnot,
150 uint32_t nFlag) {
151 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
152 if (!m_bNotifying) {
153 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
154 if (pWidget->GetAAction(CPDF_AAction::kCursorExit).GetDict()) {
155 m_bNotifying = true;
156
157 uint32_t nValueAge = pWidget->GetValueAge();
158 pWidget->ClearAppModified();
159 ASSERT(pPageView);
160
161 CPDFSDK_FieldAction fa;
162 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
163 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
164 pWidget->OnAAction(CPDF_AAction::kCursorExit, &fa, pPageView);
165 m_bNotifying = false;
166 if (!pAnnot->HasObservable())
167 return;
168
169 if (pWidget->IsAppModified()) {
170 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget)) {
171 pFormFiller->ResetPWLWindow(pPageView,
172 nValueAge == pWidget->GetValueAge());
173 }
174 }
175 }
176 }
177 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get()))
178 pFormFiller->OnMouseExit(pPageView);
179 }
180
OnLButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)181 bool CFFL_InteractiveFormFiller::OnLButtonDown(
182 CPDFSDK_PageView* pPageView,
183 ObservedPtr<CPDFSDK_Annot>* pAnnot,
184 uint32_t nFlags,
185 const CFX_PointF& point) {
186 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
187 if (!m_bNotifying) {
188 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
189 if (Annot_HitTest(pPageView, pAnnot->Get(), point) &&
190 pWidget->GetAAction(CPDF_AAction::kButtonDown).GetDict()) {
191 m_bNotifying = true;
192
193 uint32_t nValueAge = pWidget->GetValueAge();
194 pWidget->ClearAppModified();
195 ASSERT(pPageView);
196
197 CPDFSDK_FieldAction fa;
198 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlags);
199 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlags);
200 pWidget->OnAAction(CPDF_AAction::kButtonDown, &fa, pPageView);
201 m_bNotifying = false;
202 if (!pAnnot->HasObservable())
203 return true;
204
205 if (!IsValidAnnot(pPageView, pAnnot->Get()))
206 return true;
207
208 if (pWidget->IsAppModified()) {
209 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget)) {
210 pFormFiller->ResetPWLWindow(pPageView,
211 nValueAge == pWidget->GetValueAge());
212 }
213 }
214 }
215 }
216 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
217 return pFormFiller &&
218 pFormFiller->OnLButtonDown(pPageView, pAnnot->Get(), nFlags, point);
219 }
220
OnLButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)221 bool CFFL_InteractiveFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
222 ObservedPtr<CPDFSDK_Annot>* pAnnot,
223 uint32_t nFlags,
224 const CFX_PointF& point) {
225 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
226 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
227
228 bool bSetFocus;
229 switch (pWidget->GetFieldType()) {
230 case FormFieldType::kPushButton:
231 case FormFieldType::kCheckBox:
232 case FormFieldType::kRadioButton: {
233 FX_RECT bbox = GetViewBBox(pPageView, pAnnot->Get());
234 bSetFocus =
235 bbox.Contains(static_cast<int>(point.x), static_cast<int>(point.y));
236 break;
237 }
238 default:
239 bSetFocus = true;
240 break;
241 }
242 if (bSetFocus)
243 m_pFormFillEnv->SetFocusAnnot(pAnnot);
244
245 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
246 bool bRet = pFormFiller &&
247 pFormFiller->OnLButtonUp(pPageView, pAnnot->Get(), nFlags, point);
248 if (m_pFormFillEnv->GetFocusAnnot() != pAnnot->Get())
249 return bRet;
250 if (OnButtonUp(pAnnot, pPageView, nFlags) || !pAnnot)
251 return true;
252 #ifdef PDF_ENABLE_XFA
253 if (OnClick(pAnnot, pPageView, nFlags) || !pAnnot)
254 return true;
255 #endif // PDF_ENABLE_XFA
256 return bRet;
257 }
258
OnButtonUp(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)259 bool CFFL_InteractiveFormFiller::OnButtonUp(ObservedPtr<CPDFSDK_Annot>* pAnnot,
260 CPDFSDK_PageView* pPageView,
261 uint32_t nFlag) {
262 if (m_bNotifying)
263 return false;
264
265 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
266 if (!pWidget->GetAAction(CPDF_AAction::kButtonUp).GetDict())
267 return false;
268
269 m_bNotifying = true;
270
271 uint32_t nAge = pWidget->GetAppearanceAge();
272 uint32_t nValueAge = pWidget->GetValueAge();
273 ASSERT(pPageView);
274
275 CPDFSDK_FieldAction fa;
276 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
277 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
278 pWidget->OnAAction(CPDF_AAction::kButtonUp, &fa, pPageView);
279 m_bNotifying = false;
280 if (!pAnnot->HasObservable() || !IsValidAnnot(pPageView, pWidget))
281 return true;
282 if (nAge == pWidget->GetAppearanceAge())
283 return false;
284
285 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget);
286 if (pFormFiller)
287 pFormFiller->ResetPWLWindow(pPageView, nValueAge == pWidget->GetValueAge());
288 return true;
289 }
290
SetIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index,bool selected)291 bool CFFL_InteractiveFormFiller::SetIndexSelected(
292 ObservedPtr<CPDFSDK_Annot>* pAnnot,
293 int index,
294 bool selected) {
295 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
296
297 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
298 return pFormFiller && pFormFiller->SetIndexSelected(index, selected);
299 }
300
IsIndexSelected(ObservedPtr<CPDFSDK_Annot> * pAnnot,int index)301 bool CFFL_InteractiveFormFiller::IsIndexSelected(
302 ObservedPtr<CPDFSDK_Annot>* pAnnot,
303 int index) {
304 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
305
306 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
307 return pFormFiller && pFormFiller->IsIndexSelected(index);
308 }
309
OnLButtonDblClk(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)310 bool CFFL_InteractiveFormFiller::OnLButtonDblClk(
311 CPDFSDK_PageView* pPageView,
312 ObservedPtr<CPDFSDK_Annot>* pAnnot,
313 uint32_t nFlags,
314 const CFX_PointF& point) {
315 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
316 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
317 return pFormFiller && pFormFiller->OnLButtonDblClk(pPageView, nFlags, point);
318 }
319
OnMouseMove(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)320 bool CFFL_InteractiveFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
321 ObservedPtr<CPDFSDK_Annot>* pAnnot,
322 uint32_t nFlags,
323 const CFX_PointF& point) {
324 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
325 CFFL_FormFiller* pFormFiller = GetOrCreateFormFiller(pAnnot->Get());
326 return pFormFiller && pFormFiller->OnMouseMove(pPageView, nFlags, point);
327 }
328
OnMouseWheel(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)329 bool CFFL_InteractiveFormFiller::OnMouseWheel(
330 CPDFSDK_PageView* pPageView,
331 ObservedPtr<CPDFSDK_Annot>* pAnnot,
332 uint32_t nFlags,
333 short zDelta,
334 const CFX_PointF& point) {
335 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
336 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
337 return pFormFiller &&
338 pFormFiller->OnMouseWheel(pPageView, nFlags, zDelta, point);
339 }
340
OnRButtonDown(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)341 bool CFFL_InteractiveFormFiller::OnRButtonDown(
342 CPDFSDK_PageView* pPageView,
343 ObservedPtr<CPDFSDK_Annot>* pAnnot,
344 uint32_t nFlags,
345 const CFX_PointF& point) {
346 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
347 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
348 return pFormFiller && pFormFiller->OnRButtonDown(pPageView, nFlags, point);
349 }
350
OnRButtonUp(CPDFSDK_PageView * pPageView,ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlags,const CFX_PointF & point)351 bool CFFL_InteractiveFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
352 ObservedPtr<CPDFSDK_Annot>* pAnnot,
353 uint32_t nFlags,
354 const CFX_PointF& point) {
355 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
356 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
357 return pFormFiller && pFormFiller->OnRButtonUp(pPageView, nFlags, point);
358 }
359
OnKeyDown(CPDFSDK_Annot * pAnnot,uint32_t nKeyCode,uint32_t nFlags)360 bool CFFL_InteractiveFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
361 uint32_t nKeyCode,
362 uint32_t nFlags) {
363 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
364
365 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
366 return pFormFiller && pFormFiller->OnKeyDown(nKeyCode, nFlags);
367 }
368
OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)369 bool CFFL_InteractiveFormFiller::OnChar(CPDFSDK_Annot* pAnnot,
370 uint32_t nChar,
371 uint32_t nFlags) {
372 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
373 if (nChar == FWL_VKEY_Tab)
374 return true;
375
376 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
377 return pFormFiller && pFormFiller->OnChar(pAnnot, nChar, nFlags);
378 }
379
OnSetFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)380 bool CFFL_InteractiveFormFiller::OnSetFocus(ObservedPtr<CPDFSDK_Annot>* pAnnot,
381 uint32_t nFlag) {
382 if (!pAnnot->HasObservable())
383 return false;
384
385 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
386 if (!m_bNotifying) {
387 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
388 if (pWidget->GetAAction(CPDF_AAction::kGetFocus).GetDict()) {
389 m_bNotifying = true;
390
391 uint32_t nValueAge = pWidget->GetValueAge();
392 pWidget->ClearAppModified();
393
394 CFFL_FormFiller* pFormFiller = GetOrCreateFormFiller(pWidget);
395 if (!pFormFiller)
396 return false;
397
398 CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
399 ASSERT(pPageView);
400
401 CPDFSDK_FieldAction fa;
402 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
403 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
404 pFormFiller->GetActionData(pPageView, CPDF_AAction::kGetFocus, fa);
405 pWidget->OnAAction(CPDF_AAction::kGetFocus, &fa, pPageView);
406 m_bNotifying = false;
407 if (!pAnnot->HasObservable())
408 return false;
409
410 if (pWidget->IsAppModified()) {
411 if (CFFL_FormFiller* pFiller = GetFormFiller(pWidget)) {
412 pFiller->ResetPWLWindow(pPageView,
413 nValueAge == pWidget->GetValueAge());
414 }
415 }
416 }
417 }
418
419 if (CFFL_FormFiller* pFormFiller = GetOrCreateFormFiller(pAnnot->Get()))
420 pFormFiller->SetFocusForAnnot(pAnnot->Get(), nFlag);
421
422 return true;
423 }
424
OnKillFocus(ObservedPtr<CPDFSDK_Annot> * pAnnot,uint32_t nFlag)425 bool CFFL_InteractiveFormFiller::OnKillFocus(ObservedPtr<CPDFSDK_Annot>* pAnnot,
426 uint32_t nFlag) {
427 if (!pAnnot->HasObservable())
428 return false;
429
430 ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
431 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get());
432 if (!pFormFiller)
433 return true;
434
435 pFormFiller->KillFocusForAnnot(nFlag);
436 if (!pAnnot->HasObservable())
437 return false;
438
439 if (m_bNotifying)
440 return true;
441
442 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
443 if (!pWidget->GetAAction(CPDF_AAction::kLoseFocus).GetDict())
444 return true;
445
446 m_bNotifying = true;
447 pWidget->ClearAppModified();
448
449 CPDFSDK_PageView* pPageView = pWidget->GetPageView();
450 ASSERT(pPageView);
451
452 CPDFSDK_FieldAction fa;
453 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
454 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
455 pFormFiller->GetActionData(pPageView, CPDF_AAction::kLoseFocus, fa);
456 pWidget->OnAAction(CPDF_AAction::kLoseFocus, &fa, pPageView);
457 m_bNotifying = false;
458 return pAnnot->HasObservable();
459 }
460
IsVisible(CPDFSDK_Widget * pWidget)461 bool CFFL_InteractiveFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
462 return pWidget->IsVisible();
463 }
464
IsReadOnly(CPDFSDK_Widget * pWidget)465 bool CFFL_InteractiveFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
466 int nFieldFlags = pWidget->GetFieldFlags();
467 return !!(nFieldFlags & pdfium::form_flags::kReadOnly);
468 }
469
IsFillingAllowed(CPDFSDK_Widget * pWidget) const470 bool CFFL_InteractiveFormFiller::IsFillingAllowed(
471 CPDFSDK_Widget* pWidget) const {
472 if (pWidget->GetFieldType() == FormFieldType::kPushButton)
473 return false;
474
475 return m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM) ||
476 m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
477 m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY);
478 }
479
GetFormFiller(CPDFSDK_Annot * pAnnot)480 CFFL_FormFiller* CFFL_InteractiveFormFiller::GetFormFiller(
481 CPDFSDK_Annot* pAnnot) {
482 auto it = m_Map.find(pAnnot);
483 return it != m_Map.end() ? it->second.get() : nullptr;
484 }
485
GetOrCreateFormFiller(CPDFSDK_Annot * pAnnot)486 CFFL_FormFiller* CFFL_InteractiveFormFiller::GetOrCreateFormFiller(
487 CPDFSDK_Annot* pAnnot) {
488 CFFL_FormFiller* result = GetFormFiller(pAnnot);
489 if (result)
490 return result;
491
492 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot);
493 std::unique_ptr<CFFL_FormFiller> pFormFiller;
494 switch (pWidget->GetFieldType()) {
495 case FormFieldType::kPushButton:
496 pFormFiller =
497 pdfium::MakeUnique<CFFL_PushButton>(m_pFormFillEnv.Get(), pWidget);
498 break;
499 case FormFieldType::kCheckBox:
500 pFormFiller =
501 pdfium::MakeUnique<CFFL_CheckBox>(m_pFormFillEnv.Get(), pWidget);
502 break;
503 case FormFieldType::kRadioButton:
504 pFormFiller =
505 pdfium::MakeUnique<CFFL_RadioButton>(m_pFormFillEnv.Get(), pWidget);
506 break;
507 case FormFieldType::kTextField:
508 pFormFiller =
509 pdfium::MakeUnique<CFFL_TextField>(m_pFormFillEnv.Get(), pWidget);
510 break;
511 case FormFieldType::kListBox:
512 pFormFiller =
513 pdfium::MakeUnique<CFFL_ListBox>(m_pFormFillEnv.Get(), pWidget);
514 break;
515 case FormFieldType::kComboBox:
516 pFormFiller =
517 pdfium::MakeUnique<CFFL_ComboBox>(m_pFormFillEnv.Get(), pWidget);
518 break;
519 case FormFieldType::kUnknown:
520 default:
521 return nullptr;
522 }
523
524 result = pFormFiller.get();
525 m_Map[pAnnot] = std::move(pFormFiller);
526 return result;
527 }
528
GetText(CPDFSDK_Annot * pAnnot)529 WideString CFFL_InteractiveFormFiller::GetText(CPDFSDK_Annot* pAnnot) {
530 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
531 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
532 return pFormFiller ? pFormFiller->GetText() : WideString();
533 }
534
GetSelectedText(CPDFSDK_Annot * pAnnot)535 WideString CFFL_InteractiveFormFiller::GetSelectedText(CPDFSDK_Annot* pAnnot) {
536 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
537 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
538 return pFormFiller ? pFormFiller->GetSelectedText() : WideString();
539 }
540
ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)541 void CFFL_InteractiveFormFiller::ReplaceSelection(CPDFSDK_Annot* pAnnot,
542 const WideString& text) {
543 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
544 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
545 if (!pFormFiller)
546 return;
547
548 pFormFiller->ReplaceSelection(text);
549 }
550
CanUndo(CPDFSDK_Annot * pAnnot)551 bool CFFL_InteractiveFormFiller::CanUndo(CPDFSDK_Annot* pAnnot) {
552 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
553 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
554 return pFormFiller && pFormFiller->CanUndo();
555 }
556
CanRedo(CPDFSDK_Annot * pAnnot)557 bool CFFL_InteractiveFormFiller::CanRedo(CPDFSDK_Annot* pAnnot) {
558 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
559 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
560 return pFormFiller && pFormFiller->CanRedo();
561 }
562
Undo(CPDFSDK_Annot * pAnnot)563 bool CFFL_InteractiveFormFiller::Undo(CPDFSDK_Annot* pAnnot) {
564 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
565 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
566 return pFormFiller && pFormFiller->Undo();
567 }
568
Redo(CPDFSDK_Annot * pAnnot)569 bool CFFL_InteractiveFormFiller::Redo(CPDFSDK_Annot* pAnnot) {
570 ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
571 CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot);
572 return pFormFiller && pFormFiller->Redo();
573 }
574
UnRegisterFormFiller(CPDFSDK_Annot * pAnnot)575 void CFFL_InteractiveFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
576 auto it = m_Map.find(pAnnot);
577 if (it == m_Map.end())
578 return;
579
580 m_Map.erase(it);
581 }
582
QueryWherePopup(const IPWL_SystemHandler::PerWindowData * pAttached,float fPopupMin,float fPopupMax,bool * bBottom,float * fPopupRet)583 void CFFL_InteractiveFormFiller::QueryWherePopup(
584 const IPWL_SystemHandler::PerWindowData* pAttached,
585 float fPopupMin,
586 float fPopupMax,
587 bool* bBottom,
588 float* fPopupRet) {
589 auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
590 CPDFSDK_Widget* pWidget = pData->pWidget.Get();
591 CPDF_Page* pPage = pWidget->GetPDFPage();
592
593 CFX_FloatRect rcPageView(0, pPage->GetPageHeight(), pPage->GetPageWidth(), 0);
594 rcPageView.Normalize();
595
596 CFX_FloatRect rcAnnot = pWidget->GetRect();
597 float fTop = 0.0f;
598 float fBottom = 0.0f;
599 switch (pWidget->GetRotate() / 90) {
600 default:
601 case 0:
602 fTop = rcPageView.top - rcAnnot.top;
603 fBottom = rcAnnot.bottom - rcPageView.bottom;
604 break;
605 case 1:
606 fTop = rcAnnot.left - rcPageView.left;
607 fBottom = rcPageView.right - rcAnnot.right;
608 break;
609 case 2:
610 fTop = rcAnnot.bottom - rcPageView.bottom;
611 fBottom = rcPageView.top - rcAnnot.top;
612 break;
613 case 3:
614 fTop = rcPageView.right - rcAnnot.right;
615 fBottom = rcAnnot.left - rcPageView.left;
616 break;
617 }
618
619 constexpr float kMaxListBoxHeight = 140;
620 const float fMaxListBoxHeight =
621 pdfium::clamp(kMaxListBoxHeight, fPopupMin, fPopupMax);
622
623 if (fBottom > fMaxListBoxHeight) {
624 *fPopupRet = fMaxListBoxHeight;
625 *bBottom = true;
626 return;
627 }
628
629 if (fTop > fMaxListBoxHeight) {
630 *fPopupRet = fMaxListBoxHeight;
631 *bBottom = false;
632 return;
633 }
634
635 if (fTop > fBottom) {
636 *fPopupRet = fTop;
637 *bBottom = false;
638 } else {
639 *fPopupRet = fBottom;
640 *bBottom = true;
641 }
642 }
643
OnKeyStrokeCommit(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)644 bool CFFL_InteractiveFormFiller::OnKeyStrokeCommit(
645 ObservedPtr<CPDFSDK_Annot>* pAnnot,
646 CPDFSDK_PageView* pPageView,
647 uint32_t nFlag) {
648 if (m_bNotifying)
649 return true;
650
651 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
652 if (!pWidget->GetAAction(CPDF_AAction::kKeyStroke).GetDict())
653 return true;
654
655 ASSERT(pPageView);
656 m_bNotifying = true;
657 pWidget->ClearAppModified();
658
659 CPDFSDK_FieldAction fa;
660 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
661 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
662 fa.bWillCommit = true;
663 fa.bKeyDown = true;
664 fa.bRC = true;
665
666 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget);
667 pFormFiller->GetActionData(pPageView, CPDF_AAction::kKeyStroke, fa);
668 pFormFiller->SaveState(pPageView);
669 pWidget->OnAAction(CPDF_AAction::kKeyStroke, &fa, pPageView);
670 if (!pAnnot->HasObservable())
671 return true;
672
673 m_bNotifying = false;
674 return fa.bRC;
675 }
676
OnValidate(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)677 bool CFFL_InteractiveFormFiller::OnValidate(ObservedPtr<CPDFSDK_Annot>* pAnnot,
678 CPDFSDK_PageView* pPageView,
679 uint32_t nFlag) {
680 if (m_bNotifying)
681 return true;
682
683 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
684 if (!pWidget->GetAAction(CPDF_AAction::kValidate).GetDict())
685 return true;
686
687 ASSERT(pPageView);
688 m_bNotifying = true;
689 pWidget->ClearAppModified();
690
691 CPDFSDK_FieldAction fa;
692 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
693 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
694 fa.bKeyDown = true;
695 fa.bRC = true;
696
697 CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget);
698 pFormFiller->GetActionData(pPageView, CPDF_AAction::kValidate, fa);
699 pFormFiller->SaveState(pPageView);
700 pWidget->OnAAction(CPDF_AAction::kValidate, &fa, pPageView);
701 if (!pAnnot->HasObservable())
702 return true;
703
704 m_bNotifying = false;
705 return fa.bRC;
706 }
707
OnCalculate(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)708 void CFFL_InteractiveFormFiller::OnCalculate(ObservedPtr<CPDFSDK_Annot>* pAnnot,
709 CPDFSDK_PageView* pPageView,
710 uint32_t nFlag) {
711 if (m_bNotifying)
712 return;
713
714 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
715 if (pWidget) {
716 CPDFSDK_InteractiveForm* pForm =
717 pPageView->GetFormFillEnv()->GetInteractiveForm();
718 pForm->OnCalculate(pWidget->GetFormField());
719 }
720 m_bNotifying = false;
721 }
722
OnFormat(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)723 void CFFL_InteractiveFormFiller::OnFormat(ObservedPtr<CPDFSDK_Annot>* pAnnot,
724 CPDFSDK_PageView* pPageView,
725 uint32_t nFlag) {
726 if (m_bNotifying)
727 return;
728
729 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
730 ASSERT(pWidget);
731 CPDFSDK_InteractiveForm* pForm =
732 pPageView->GetFormFillEnv()->GetInteractiveForm();
733
734 Optional<WideString> sValue = pForm->OnFormat(pWidget->GetFormField());
735 if (!pAnnot->HasObservable())
736 return;
737
738 if (sValue.has_value()) {
739 pForm->ResetFieldAppearance(pWidget->GetFormField(), sValue);
740 pForm->UpdateField(pWidget->GetFormField());
741 }
742
743 m_bNotifying = false;
744 }
745
746 #ifdef PDF_ENABLE_XFA
OnClick(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)747 bool CFFL_InteractiveFormFiller::OnClick(ObservedPtr<CPDFSDK_Annot>* pAnnot,
748 CPDFSDK_PageView* pPageView,
749 uint32_t nFlag) {
750 if (m_bNotifying)
751 return false;
752
753 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
754 if (!pWidget->HasXFAAAction(PDFSDK_XFA_Click))
755 return false;
756
757 m_bNotifying = true;
758 uint32_t nAge = pWidget->GetAppearanceAge();
759 uint32_t nValueAge = pWidget->GetValueAge();
760
761 CPDFSDK_FieldAction fa;
762 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
763 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
764
765 pWidget->OnXFAAAction(PDFSDK_XFA_Click, &fa, pPageView);
766 m_bNotifying = false;
767 if (!pAnnot->HasObservable() || !IsValidAnnot(pPageView, pWidget))
768 return true;
769 if (nAge == pWidget->GetAppearanceAge())
770 return false;
771
772 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget))
773 pFormFiller->ResetPWLWindow(pPageView, nValueAge == pWidget->GetValueAge());
774 return false;
775 }
776
OnFull(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)777 bool CFFL_InteractiveFormFiller::OnFull(ObservedPtr<CPDFSDK_Annot>* pAnnot,
778 CPDFSDK_PageView* pPageView,
779 uint32_t nFlag) {
780 if (m_bNotifying)
781 return false;
782
783 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
784 if (!pWidget->HasXFAAAction(PDFSDK_XFA_Full))
785 return false;
786
787 m_bNotifying = true;
788 uint32_t nAge = pWidget->GetAppearanceAge();
789 uint32_t nValueAge = pWidget->GetValueAge();
790
791 CPDFSDK_FieldAction fa;
792 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
793 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
794
795 pWidget->OnXFAAAction(PDFSDK_XFA_Full, &fa, pPageView);
796 m_bNotifying = false;
797 if (!pAnnot->HasObservable() || !IsValidAnnot(pPageView, pWidget))
798 return true;
799 if (nAge == pWidget->GetAppearanceAge())
800 return false;
801
802 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget))
803 pFormFiller->ResetPWLWindow(pPageView, nValueAge == pWidget->GetValueAge());
804
805 return true;
806 }
807
OnPreOpen(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)808 bool CFFL_InteractiveFormFiller::OnPreOpen(ObservedPtr<CPDFSDK_Annot>* pAnnot,
809 CPDFSDK_PageView* pPageView,
810 uint32_t nFlag) {
811 if (m_bNotifying)
812 return false;
813
814 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
815 if (!pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen))
816 return false;
817
818 m_bNotifying = true;
819 uint32_t nAge = pWidget->GetAppearanceAge();
820 uint32_t nValueAge = pWidget->GetValueAge();
821
822 CPDFSDK_FieldAction fa;
823 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
824 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
825
826 pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, &fa, pPageView);
827 m_bNotifying = false;
828 if (!pAnnot->HasObservable() || !IsValidAnnot(pPageView, pWidget))
829 return true;
830 if (nAge == pWidget->GetAppearanceAge())
831 return false;
832
833 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget))
834 pFormFiller->ResetPWLWindow(pPageView, nValueAge == pWidget->GetValueAge());
835
836 return true;
837 }
838
OnPostOpen(ObservedPtr<CPDFSDK_Annot> * pAnnot,CPDFSDK_PageView * pPageView,uint32_t nFlag)839 bool CFFL_InteractiveFormFiller::OnPostOpen(ObservedPtr<CPDFSDK_Annot>* pAnnot,
840 CPDFSDK_PageView* pPageView,
841 uint32_t nFlag) {
842 if (m_bNotifying)
843 return false;
844
845 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());
846 if (!pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen))
847 return false;
848
849 m_bNotifying = true;
850 uint32_t nAge = pWidget->GetAppearanceAge();
851 uint32_t nValueAge = pWidget->GetValueAge();
852
853 CPDFSDK_FieldAction fa;
854 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
855 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
856
857 pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, &fa, pPageView);
858 m_bNotifying = false;
859 if (!pAnnot->HasObservable() || !IsValidAnnot(pPageView, pWidget))
860 return true;
861 if (nAge == pWidget->GetAppearanceAge())
862 return false;
863
864 if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget))
865 pFormFiller->ResetPWLWindow(pPageView, nValueAge == pWidget->GetValueAge());
866
867 return true;
868 }
869 #endif // PDF_ENABLE_XFA
870
IsValidAnnot(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)871 bool CFFL_InteractiveFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
872 CPDFSDK_Annot* pAnnot) {
873 return pPageView && pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
874 }
875
OnBeforeKeyStroke(const IPWL_SystemHandler::PerWindowData * pAttached,WideString & strChange,const WideString & strChangeEx,int nSelStart,int nSelEnd,bool bKeyDown,uint32_t nFlag)876 std::pair<bool, bool> CFFL_InteractiveFormFiller::OnBeforeKeyStroke(
877 const IPWL_SystemHandler::PerWindowData* pAttached,
878 WideString& strChange,
879 const WideString& strChangeEx,
880 int nSelStart,
881 int nSelEnd,
882 bool bKeyDown,
883 uint32_t nFlag) {
884 // Copy the private data since the window owning it may not survive.
885 CFFL_PrivateData privateData =
886 *static_cast<const CFFL_PrivateData*>(pAttached);
887 ASSERT(privateData.pWidget);
888
889 CFFL_FormFiller* pFormFiller = GetFormFiller(privateData.GetWidget());
890
891 #ifdef PDF_ENABLE_XFA
892 if (pFormFiller->IsFieldFull(privateData.pPageView)) {
893 ObservedPtr<CPDFSDK_Annot> pObserved(privateData.GetWidget());
894 if (OnFull(&pObserved, privateData.pPageView, nFlag) || !pObserved)
895 return {true, true};
896 }
897 #endif // PDF_ENABLE_XFA
898
899 if (m_bNotifying ||
900 !privateData.pWidget->GetAAction(CPDF_AAction::kKeyStroke).GetDict()) {
901 return {true, false};
902 }
903
904 AutoRestorer<bool> restorer(&m_bNotifying);
905 m_bNotifying = true;
906
907 uint32_t nAge = privateData.pWidget->GetAppearanceAge();
908 uint32_t nValueAge = privateData.pWidget->GetValueAge();
909 CPDFSDK_FormFillEnvironment* pFormFillEnv =
910 privateData.pPageView->GetFormFillEnv();
911
912 CPDFSDK_FieldAction fa;
913 fa.bModifier = CPWL_Wnd::IsCTRLKeyDown(nFlag);
914 fa.bShift = CPWL_Wnd::IsSHIFTKeyDown(nFlag);
915 fa.sChange = strChange;
916 fa.sChangeEx = strChangeEx;
917 fa.bKeyDown = bKeyDown;
918 fa.bWillCommit = false;
919 fa.bRC = true;
920 fa.nSelStart = nSelStart;
921 fa.nSelEnd = nSelEnd;
922 pFormFiller->GetActionData(privateData.pPageView, CPDF_AAction::kKeyStroke,
923 fa);
924 pFormFiller->SaveState(privateData.pPageView);
925
926 ObservedPtr<CPDFSDK_Annot> pObserved(privateData.GetWidget());
927 bool action_status = privateData.pWidget->OnAAction(
928 CPDF_AAction::kKeyStroke, &fa, privateData.pPageView);
929
930 if (!pObserved ||
931 !IsValidAnnot(privateData.pPageView, privateData.GetWidget())) {
932 return {true, true};
933 }
934 if (!action_status)
935 return {true, false};
936
937 bool bExit = false;
938 if (nAge != privateData.pWidget->GetAppearanceAge()) {
939 CPWL_Wnd* pWnd = pFormFiller->ResetPWLWindow(
940 privateData.pPageView, nValueAge == privateData.pWidget->GetValueAge());
941 if (!pWnd)
942 return {true, true};
943 privateData =
944 *static_cast<const CFFL_PrivateData*>(pWnd->GetAttachedData());
945 bExit = true;
946 }
947 if (fa.bRC) {
948 pFormFiller->SetActionData(privateData.pPageView, CPDF_AAction::kKeyStroke,
949 fa);
950 } else {
951 pFormFiller->RestoreState(privateData.pPageView);
952 }
953 if (pFormFillEnv->GetFocusAnnot() == privateData.GetWidget())
954 return {false, bExit};
955
956 pFormFiller->CommitData(privateData.pPageView, nFlag);
957 return {false, true};
958 }
959
OnPopupPreOpen(const IPWL_SystemHandler::PerWindowData * pAttached,uint32_t nFlag)960 bool CFFL_InteractiveFormFiller::OnPopupPreOpen(
961 const IPWL_SystemHandler::PerWindowData* pAttached,
962 uint32_t nFlag) {
963 #ifdef PDF_ENABLE_XFA
964 auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
965 ASSERT(pData->pWidget);
966
967 ObservedPtr<CPDFSDK_Annot> pObserved(pData->GetWidget());
968 return OnPreOpen(&pObserved, pData->pPageView, nFlag) || !pObserved;
969 #else
970 return false;
971 #endif
972 }
973
OnPopupPostOpen(const IPWL_SystemHandler::PerWindowData * pAttached,uint32_t nFlag)974 bool CFFL_InteractiveFormFiller::OnPopupPostOpen(
975 const IPWL_SystemHandler::PerWindowData* pAttached,
976 uint32_t nFlag) {
977 #ifdef PDF_ENABLE_XFA
978 auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
979 ASSERT(pData->pWidget);
980
981 ObservedPtr<CPDFSDK_Annot> pObserved(pData->GetWidget());
982 return OnPostOpen(&pObserved, pData->pPageView, nFlag) || !pObserved;
983 #else
984 return false;
985 #endif
986 }
987
988 CFFL_PrivateData::CFFL_PrivateData() = default;
989
990 CFFL_PrivateData::CFFL_PrivateData(const CFFL_PrivateData& that) = default;
991
992 CFFL_PrivateData::~CFFL_PrivateData() = default;
993
Clone() const994 std::unique_ptr<IPWL_SystemHandler::PerWindowData> CFFL_PrivateData::Clone()
995 const {
996 return pdfium::MakeUnique<CFFL_PrivateData>(*this);
997 }
998