• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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