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