1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_pageview.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
10*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
11*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
12*3ac0a46fSAndroid Build Coastguard Worker
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_document.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/render/cpdf_renderoptions.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_annotlist.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_interactiveform.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/autorestorer.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/stl_util.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_annot.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_annotiteration.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_annotiterator.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_helpers.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_interactiveform.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
28*3ac0a46fSAndroid Build Coastguard Worker
29*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
30*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffpageview.h"
33*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
34*3ac0a46fSAndroid Build Coastguard Worker
CPDFSDK_PageView(CPDFSDK_FormFillEnvironment * pFormFillEnv,IPDF_Page * page)35*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_FormFillEnvironment* pFormFillEnv,
36*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* page)
37*3ac0a46fSAndroid Build Coastguard Worker : m_page(page), m_pFormFillEnv(pFormFillEnv) {
38*3ac0a46fSAndroid Build Coastguard Worker DCHECK(m_page);
39*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPDFPage = ToPDFPage(page);
40*3ac0a46fSAndroid Build Coastguard Worker if (pPDFPage) {
41*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
42*3ac0a46fSAndroid Build Coastguard Worker CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
43*3ac0a46fSAndroid Build Coastguard Worker pPDFForm->FixPageFields(pPDFPage);
44*3ac0a46fSAndroid Build Coastguard Worker if (!page->AsXFAPage())
45*3ac0a46fSAndroid Build Coastguard Worker pPDFPage->SetView(this);
46*3ac0a46fSAndroid Build Coastguard Worker }
47*3ac0a46fSAndroid Build Coastguard Worker }
48*3ac0a46fSAndroid Build Coastguard Worker
~CPDFSDK_PageView()49*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView::~CPDFSDK_PageView() {
50*3ac0a46fSAndroid Build Coastguard Worker if (!m_page->AsXFAPage()) {
51*3ac0a46fSAndroid Build Coastguard Worker // Deleting from `m_SDKAnnotArray` below can cause the page pointed to by
52*3ac0a46fSAndroid Build Coastguard Worker // `m_page` to be freed, which will cause issues if we try to cleanup the
53*3ac0a46fSAndroid Build Coastguard Worker // pageview pointer in `m_page`. So, reset the pageview pointer before doing
54*3ac0a46fSAndroid Build Coastguard Worker // anything else.
55*3ac0a46fSAndroid Build Coastguard Worker m_page->AsPDFPage()->SetView(nullptr);
56*3ac0a46fSAndroid Build Coastguard Worker }
57*3ac0a46fSAndroid Build Coastguard Worker
58*3ac0a46fSAndroid Build Coastguard Worker // Manually reset elements to ensure they are deleted in order.
59*3ac0a46fSAndroid Build Coastguard Worker for (std::unique_ptr<CPDFSDK_Annot>& pAnnot : m_SDKAnnotArray)
60*3ac0a46fSAndroid Build Coastguard Worker pAnnot.reset();
61*3ac0a46fSAndroid Build Coastguard Worker
62*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.clear();
63*3ac0a46fSAndroid Build Coastguard Worker m_pAnnotList.reset();
64*3ac0a46fSAndroid Build Coastguard Worker }
65*3ac0a46fSAndroid Build Coastguard Worker
ClearPage(CPDF_Page * pPage)66*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::ClearPage(CPDF_Page* pPage) {
67*3ac0a46fSAndroid Build Coastguard Worker if (!IsBeingDestroyed())
68*3ac0a46fSAndroid Build Coastguard Worker GetFormFillEnv()->RemovePageView(pPage);
69*3ac0a46fSAndroid Build Coastguard Worker }
70*3ac0a46fSAndroid Build Coastguard Worker
PageView_OnDraw(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,CPDF_RenderOptions * pOptions,const FX_RECT & pClip)71*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice,
72*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& mtUser2Device,
73*3ac0a46fSAndroid Build Coastguard Worker CPDF_RenderOptions* pOptions,
74*3ac0a46fSAndroid Build Coastguard Worker const FX_RECT& pClip) {
75*3ac0a46fSAndroid Build Coastguard Worker m_curMatrix = mtUser2Device;
76*3ac0a46fSAndroid Build Coastguard Worker
77*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
78*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pPage = GetXFAPage();
79*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document::Extension* pContext =
80*3ac0a46fSAndroid Build Coastguard Worker pPage ? pPage->GetDocument()->GetExtension() : nullptr;
81*3ac0a46fSAndroid Build Coastguard Worker if (pContext && pContext->ContainsExtensionFullForm()) {
82*3ac0a46fSAndroid Build Coastguard Worker static_cast<CPDFXFA_Page*>(pPage)->DrawFocusAnnot(pDevice, GetFocusAnnot(),
83*3ac0a46fSAndroid Build Coastguard Worker mtUser2Device, pClip);
84*3ac0a46fSAndroid Build Coastguard Worker return;
85*3ac0a46fSAndroid Build Coastguard Worker }
86*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
87*3ac0a46fSAndroid Build Coastguard Worker
88*3ac0a46fSAndroid Build Coastguard Worker // for pdf/static xfa.
89*3ac0a46fSAndroid Build Coastguard Worker auto annot_iteration = CPDFSDK_AnnotIteration::CreateForDrawing(this);
90*3ac0a46fSAndroid Build Coastguard Worker for (const auto& pSDKAnnot : annot_iteration) {
91*3ac0a46fSAndroid Build Coastguard Worker pSDKAnnot->OnDraw(pDevice, mtUser2Device, pOptions->GetDrawAnnots());
92*3ac0a46fSAndroid Build Coastguard Worker }
93*3ac0a46fSAndroid Build Coastguard Worker }
94*3ac0a46fSAndroid Build Coastguard Worker
NewAnnot(CPDF_Annot * annot)95*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CPDFSDK_Annot> CPDFSDK_PageView::NewAnnot(CPDF_Annot* annot) {
96*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Annot::Subtype sub_type = annot->GetSubtype();
97*3ac0a46fSAndroid Build Coastguard Worker if (sub_type == CPDF_Annot::Subtype::WIDGET) {
98*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* form = m_pFormFillEnv->GetInteractiveForm();
99*3ac0a46fSAndroid Build Coastguard Worker CPDF_InteractiveForm* pdf_form = form->GetInteractiveForm();
100*3ac0a46fSAndroid Build Coastguard Worker CPDF_FormControl* form_control =
101*3ac0a46fSAndroid Build Coastguard Worker pdf_form->GetControlByDict(annot->GetAnnotDict());
102*3ac0a46fSAndroid Build Coastguard Worker if (!form_control)
103*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
104*3ac0a46fSAndroid Build Coastguard Worker
105*3ac0a46fSAndroid Build Coastguard Worker auto ret = std::make_unique<CPDFSDK_Widget>(annot, this, form);
106*3ac0a46fSAndroid Build Coastguard Worker form->AddMap(form_control, ret.get());
107*3ac0a46fSAndroid Build Coastguard Worker if (pdf_form->NeedConstructAP())
108*3ac0a46fSAndroid Build Coastguard Worker ret->ResetAppearance(absl::nullopt, CPDFSDK_Widget::kValueUnchanged);
109*3ac0a46fSAndroid Build Coastguard Worker return ret;
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker
112*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
113*3ac0a46fSAndroid Build Coastguard Worker if (sub_type == CPDF_Annot::Subtype::XFAWIDGET)
114*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
115*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
116*3ac0a46fSAndroid Build Coastguard Worker
117*3ac0a46fSAndroid Build Coastguard Worker return std::make_unique<CPDFSDK_BAAnnot>(annot, this);
118*3ac0a46fSAndroid Build Coastguard Worker }
119*3ac0a46fSAndroid Build Coastguard Worker
GetFXAnnotAtPoint(const CFX_PointF & point)120*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(const CFX_PointF& point) {
121*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIteration annot_iteration(this);
122*3ac0a46fSAndroid Build Coastguard Worker for (const auto& pSDKAnnot : annot_iteration) {
123*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect rc = pSDKAnnot->GetViewBBox();
124*3ac0a46fSAndroid Build Coastguard Worker if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP)
125*3ac0a46fSAndroid Build Coastguard Worker continue;
126*3ac0a46fSAndroid Build Coastguard Worker if (rc.Contains(point))
127*3ac0a46fSAndroid Build Coastguard Worker return pSDKAnnot.Get();
128*3ac0a46fSAndroid Build Coastguard Worker }
129*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
130*3ac0a46fSAndroid Build Coastguard Worker }
131*3ac0a46fSAndroid Build Coastguard Worker
GetFXWidgetAtPoint(const CFX_PointF & point)132*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(const CFX_PointF& point) {
133*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIteration annot_iteration(this);
134*3ac0a46fSAndroid Build Coastguard Worker for (const auto& pSDKAnnot : annot_iteration) {
135*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Annot::Subtype sub_type = pSDKAnnot->GetAnnotSubtype();
136*3ac0a46fSAndroid Build Coastguard Worker bool do_hit_test = sub_type == CPDF_Annot::Subtype::WIDGET;
137*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
138*3ac0a46fSAndroid Build Coastguard Worker do_hit_test = do_hit_test || sub_type == CPDF_Annot::Subtype::XFAWIDGET;
139*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
140*3ac0a46fSAndroid Build Coastguard Worker if (do_hit_test && pSDKAnnot->DoHitTest(point))
141*3ac0a46fSAndroid Build Coastguard Worker return pSDKAnnot.Get();
142*3ac0a46fSAndroid Build Coastguard Worker }
143*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
144*3ac0a46fSAndroid Build Coastguard Worker }
145*3ac0a46fSAndroid Build Coastguard Worker
146*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
AddAnnotForFFWidget(CXFA_FFWidget * pWidget)147*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::AddAnnotForFFWidget(CXFA_FFWidget* pWidget) {
148*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* pSDKAnnot = GetAnnotForFFWidget(pWidget);
149*3ac0a46fSAndroid Build Coastguard Worker if (pSDKAnnot)
150*3ac0a46fSAndroid Build Coastguard Worker return pSDKAnnot;
151*3ac0a46fSAndroid Build Coastguard Worker
152*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.push_back(std::make_unique<CPDFXFA_Widget>(pWidget, this));
153*3ac0a46fSAndroid Build Coastguard Worker return m_SDKAnnotArray.back().get();
154*3ac0a46fSAndroid Build Coastguard Worker }
155*3ac0a46fSAndroid Build Coastguard Worker
DeleteAnnotForFFWidget(CXFA_FFWidget * pWidget)156*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::DeleteAnnotForFFWidget(CXFA_FFWidget* pWidget) {
157*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* pAnnot = GetAnnotForFFWidget(pWidget);
158*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
159*3ac0a46fSAndroid Build Coastguard Worker return;
160*3ac0a46fSAndroid Build Coastguard Worker
161*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* pPage = pAnnot->GetXFAPage();
162*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
163*3ac0a46fSAndroid Build Coastguard Worker return;
164*3ac0a46fSAndroid Build Coastguard Worker
165*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document::Extension* pContext = pPage->GetDocument()->GetExtension();
166*3ac0a46fSAndroid Build Coastguard Worker if (pContext && !pContext->ContainsExtensionForm())
167*3ac0a46fSAndroid Build Coastguard Worker return;
168*3ac0a46fSAndroid Build Coastguard Worker
169*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pObserved(pAnnot);
170*3ac0a46fSAndroid Build Coastguard Worker if (GetFocusAnnot() == pAnnot)
171*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->KillFocusAnnot({}); // May invoke JS, invalidating pAnnot.
172*3ac0a46fSAndroid Build Coastguard Worker
173*3ac0a46fSAndroid Build Coastguard Worker if (pObserved) {
174*3ac0a46fSAndroid Build Coastguard Worker auto it = std::find(m_SDKAnnotArray.begin(), m_SDKAnnotArray.end(),
175*3ac0a46fSAndroid Build Coastguard Worker fxcrt::MakeFakeUniquePtr(pAnnot));
176*3ac0a46fSAndroid Build Coastguard Worker if (it != m_SDKAnnotArray.end())
177*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.erase(it);
178*3ac0a46fSAndroid Build Coastguard Worker }
179*3ac0a46fSAndroid Build Coastguard Worker
180*3ac0a46fSAndroid Build Coastguard Worker if (m_pCaptureWidget.Get() == pAnnot)
181*3ac0a46fSAndroid Build Coastguard Worker m_pCaptureWidget.Reset();
182*3ac0a46fSAndroid Build Coastguard Worker }
183*3ac0a46fSAndroid Build Coastguard Worker
XFAPageIfNotBackedByPDFPage()184*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Page* CPDFSDK_PageView::XFAPageIfNotBackedByPDFPage() {
185*3ac0a46fSAndroid Build Coastguard Worker auto* pPage = static_cast<CPDFXFA_Page*>(GetXFAPage());
186*3ac0a46fSAndroid Build Coastguard Worker return pPage && !pPage->AsPDFPage() ? pPage : nullptr;
187*3ac0a46fSAndroid Build Coastguard Worker }
188*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
189*3ac0a46fSAndroid Build Coastguard Worker
GetPDFDocument()190*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* CPDFSDK_PageView::GetPDFDocument() {
191*3ac0a46fSAndroid Build Coastguard Worker return m_page->GetDocument();
192*3ac0a46fSAndroid Build Coastguard Worker }
193*3ac0a46fSAndroid Build Coastguard Worker
GetPDFPage() const194*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* CPDFSDK_PageView::GetPDFPage() const {
195*3ac0a46fSAndroid Build Coastguard Worker return ToPDFPage(m_page);
196*3ac0a46fSAndroid Build Coastguard Worker }
197*3ac0a46fSAndroid Build Coastguard Worker
GetInteractiveForm() const198*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* CPDFSDK_PageView::GetInteractiveForm() const {
199*3ac0a46fSAndroid Build Coastguard Worker return m_pFormFillEnv->GetInteractiveForm();
200*3ac0a46fSAndroid Build Coastguard Worker }
201*3ac0a46fSAndroid Build Coastguard Worker
GetAnnotList() const202*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDFSDK_Annot*> CPDFSDK_PageView::GetAnnotList() const {
203*3ac0a46fSAndroid Build Coastguard Worker std::vector<CPDFSDK_Annot*> list;
204*3ac0a46fSAndroid Build Coastguard Worker list.reserve(m_SDKAnnotArray.size());
205*3ac0a46fSAndroid Build Coastguard Worker for (const std::unique_ptr<CPDFSDK_Annot>& elem : m_SDKAnnotArray)
206*3ac0a46fSAndroid Build Coastguard Worker list.push_back(elem.get());
207*3ac0a46fSAndroid Build Coastguard Worker return list;
208*3ac0a46fSAndroid Build Coastguard Worker }
209*3ac0a46fSAndroid Build Coastguard Worker
GetAnnotByDict(const CPDF_Dictionary * pDict)210*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(const CPDF_Dictionary* pDict) {
211*3ac0a46fSAndroid Build Coastguard Worker for (std::unique_ptr<CPDFSDK_Annot>& pAnnot : m_SDKAnnotArray) {
212*3ac0a46fSAndroid Build Coastguard Worker CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
213*3ac0a46fSAndroid Build Coastguard Worker if (pPDFAnnot && pPDFAnnot->GetAnnotDict() == pDict)
214*3ac0a46fSAndroid Build Coastguard Worker return pAnnot.get();
215*3ac0a46fSAndroid Build Coastguard Worker }
216*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
217*3ac0a46fSAndroid Build Coastguard Worker }
218*3ac0a46fSAndroid Build Coastguard Worker
219*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
GetAnnotForFFWidget(CXFA_FFWidget * pWidget)220*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotForFFWidget(CXFA_FFWidget* pWidget) {
221*3ac0a46fSAndroid Build Coastguard Worker if (!pWidget)
222*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
223*3ac0a46fSAndroid Build Coastguard Worker
224*3ac0a46fSAndroid Build Coastguard Worker for (std::unique_ptr<CPDFSDK_Annot>& pAnnot : m_SDKAnnotArray) {
225*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Widget* pCurrentWidget = pAnnot->AsXFAWidget();
226*3ac0a46fSAndroid Build Coastguard Worker if (pCurrentWidget && pCurrentWidget->GetXFAFFWidget() == pWidget)
227*3ac0a46fSAndroid Build Coastguard Worker return pAnnot.get();
228*3ac0a46fSAndroid Build Coastguard Worker }
229*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
230*3ac0a46fSAndroid Build Coastguard Worker }
231*3ac0a46fSAndroid Build Coastguard Worker
GetXFAPage()232*3ac0a46fSAndroid Build Coastguard Worker IPDF_Page* CPDFSDK_PageView::GetXFAPage() {
233*3ac0a46fSAndroid Build Coastguard Worker return ToXFAPage(m_page);
234*3ac0a46fSAndroid Build Coastguard Worker }
235*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
236*3ac0a46fSAndroid Build Coastguard Worker
GetFocusedFormText()237*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_PageView::GetFocusedFormText() {
238*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
239*3ac0a46fSAndroid Build Coastguard Worker return annot ? annot->GetText() : WideString();
240*3ac0a46fSAndroid Build Coastguard Worker }
241*3ac0a46fSAndroid Build Coastguard Worker
GetNextAnnot(CPDFSDK_Annot * pAnnot)242*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
243*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
244*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Page* pXFAPage = XFAPageIfNotBackedByPDFPage();
245*3ac0a46fSAndroid Build Coastguard Worker if (pXFAPage)
246*3ac0a46fSAndroid Build Coastguard Worker return pXFAPage->GetNextXFAAnnot(pAnnot);
247*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
248*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIterator ai(this, GetFormFillEnv()->GetFocusableAnnotSubtypes());
249*3ac0a46fSAndroid Build Coastguard Worker return ai.GetNextAnnot(pAnnot);
250*3ac0a46fSAndroid Build Coastguard Worker }
251*3ac0a46fSAndroid Build Coastguard Worker
GetPrevAnnot(CPDFSDK_Annot * pAnnot)252*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
253*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
254*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Page* pXFAPage = XFAPageIfNotBackedByPDFPage();
255*3ac0a46fSAndroid Build Coastguard Worker if (pXFAPage)
256*3ac0a46fSAndroid Build Coastguard Worker return pXFAPage->GetPrevXFAAnnot(pAnnot);
257*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
258*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIterator ai(this, GetFormFillEnv()->GetFocusableAnnotSubtypes());
259*3ac0a46fSAndroid Build Coastguard Worker return ai.GetPrevAnnot(pAnnot);
260*3ac0a46fSAndroid Build Coastguard Worker }
261*3ac0a46fSAndroid Build Coastguard Worker
GetFirstFocusableAnnot()262*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetFirstFocusableAnnot() {
263*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
264*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Page* pXFAPage = XFAPageIfNotBackedByPDFPage();
265*3ac0a46fSAndroid Build Coastguard Worker if (pXFAPage)
266*3ac0a46fSAndroid Build Coastguard Worker return pXFAPage->GetFirstXFAAnnot(this);
267*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
268*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIterator ai(this, GetFormFillEnv()->GetFocusableAnnotSubtypes());
269*3ac0a46fSAndroid Build Coastguard Worker return ai.GetFirstAnnot();
270*3ac0a46fSAndroid Build Coastguard Worker }
271*3ac0a46fSAndroid Build Coastguard Worker
GetLastFocusableAnnot()272*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetLastFocusableAnnot() {
273*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
274*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_Page* pXFAPage = XFAPageIfNotBackedByPDFPage();
275*3ac0a46fSAndroid Build Coastguard Worker if (pXFAPage)
276*3ac0a46fSAndroid Build Coastguard Worker return pXFAPage->GetLastXFAAnnot(this);
277*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
278*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_AnnotIterator ai(this, GetFormFillEnv()->GetFocusableAnnotSubtypes());
279*3ac0a46fSAndroid Build Coastguard Worker return ai.GetLastAnnot();
280*3ac0a46fSAndroid Build Coastguard Worker }
281*3ac0a46fSAndroid Build Coastguard Worker
GetSelectedText()282*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFSDK_PageView::GetSelectedText() {
283*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
284*3ac0a46fSAndroid Build Coastguard Worker if (!annot)
285*3ac0a46fSAndroid Build Coastguard Worker return WideString();
286*3ac0a46fSAndroid Build Coastguard Worker return annot->GetSelectedText();
287*3ac0a46fSAndroid Build Coastguard Worker }
288*3ac0a46fSAndroid Build Coastguard Worker
ReplaceAndKeepSelection(const WideString & text)289*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::ReplaceAndKeepSelection(const WideString& text) {
290*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
291*3ac0a46fSAndroid Build Coastguard Worker if (annot)
292*3ac0a46fSAndroid Build Coastguard Worker annot->ReplaceAndKeepSelection(text);
293*3ac0a46fSAndroid Build Coastguard Worker }
294*3ac0a46fSAndroid Build Coastguard Worker
ReplaceSelection(const WideString & text)295*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::ReplaceSelection(const WideString& text) {
296*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
297*3ac0a46fSAndroid Build Coastguard Worker if (annot)
298*3ac0a46fSAndroid Build Coastguard Worker annot->ReplaceSelection(text);
299*3ac0a46fSAndroid Build Coastguard Worker }
300*3ac0a46fSAndroid Build Coastguard Worker
SelectAllText()301*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::SelectAllText() {
302*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
303*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->SelectAllText();
304*3ac0a46fSAndroid Build Coastguard Worker }
305*3ac0a46fSAndroid Build Coastguard Worker
CanUndo()306*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::CanUndo() {
307*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
308*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->CanUndo();
309*3ac0a46fSAndroid Build Coastguard Worker }
310*3ac0a46fSAndroid Build Coastguard Worker
CanRedo()311*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::CanRedo() {
312*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
313*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->CanRedo();
314*3ac0a46fSAndroid Build Coastguard Worker }
315*3ac0a46fSAndroid Build Coastguard Worker
Undo()316*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::Undo() {
317*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
318*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->Undo();
319*3ac0a46fSAndroid Build Coastguard Worker }
320*3ac0a46fSAndroid Build Coastguard Worker
Redo()321*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::Redo() {
322*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
323*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->Redo();
324*3ac0a46fSAndroid Build Coastguard Worker }
325*3ac0a46fSAndroid Build Coastguard Worker
OnFocus(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)326*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnFocus(Mask<FWL_EVENTFLAG> nFlags,
327*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
328*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
329*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot) {
330*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->KillFocusAnnot(nFlags);
331*3ac0a46fSAndroid Build Coastguard Worker return false;
332*3ac0a46fSAndroid Build Coastguard Worker }
333*3ac0a46fSAndroid Build Coastguard Worker
334*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SetFocusAnnot(pAnnot);
335*3ac0a46fSAndroid Build Coastguard Worker return true;
336*3ac0a46fSAndroid Build Coastguard Worker }
337*3ac0a46fSAndroid Build Coastguard Worker
OnLButtonDown(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)338*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnLButtonDown(Mask<FWL_EVENTFLAG> nFlags,
339*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
340*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
341*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot) {
342*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->KillFocusAnnot(nFlags);
343*3ac0a46fSAndroid Build Coastguard Worker return false;
344*3ac0a46fSAndroid Build Coastguard Worker }
345*3ac0a46fSAndroid Build Coastguard Worker
346*3ac0a46fSAndroid Build Coastguard Worker if (!CPDFSDK_Annot::OnLButtonDown(pAnnot, nFlags, point))
347*3ac0a46fSAndroid Build Coastguard Worker return false;
348*3ac0a46fSAndroid Build Coastguard Worker
349*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
350*3ac0a46fSAndroid Build Coastguard Worker return false;
351*3ac0a46fSAndroid Build Coastguard Worker
352*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SetFocusAnnot(pAnnot);
353*3ac0a46fSAndroid Build Coastguard Worker return true;
354*3ac0a46fSAndroid Build Coastguard Worker }
355*3ac0a46fSAndroid Build Coastguard Worker
OnLButtonUp(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)356*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnLButtonUp(Mask<FWL_EVENTFLAG> nFlags,
357*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
358*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pFXAnnot(GetFXWidgetAtPoint(point));
359*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pFocusAnnot(GetFocusAnnot());
360*3ac0a46fSAndroid Build Coastguard Worker if (pFocusAnnot && pFocusAnnot != pFXAnnot) {
361*3ac0a46fSAndroid Build Coastguard Worker // Last focus Annot gets a chance to handle the event.
362*3ac0a46fSAndroid Build Coastguard Worker if (CPDFSDK_Annot::OnLButtonUp(pFocusAnnot, nFlags, point))
363*3ac0a46fSAndroid Build Coastguard Worker return true;
364*3ac0a46fSAndroid Build Coastguard Worker }
365*3ac0a46fSAndroid Build Coastguard Worker return pFXAnnot && CPDFSDK_Annot::OnLButtonUp(pFXAnnot, nFlags, point);
366*3ac0a46fSAndroid Build Coastguard Worker }
367*3ac0a46fSAndroid Build Coastguard Worker
OnLButtonDblClk(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)368*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnLButtonDblClk(Mask<FWL_EVENTFLAG> nFlags,
369*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
370*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
371*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot) {
372*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->KillFocusAnnot(nFlags);
373*3ac0a46fSAndroid Build Coastguard Worker return false;
374*3ac0a46fSAndroid Build Coastguard Worker }
375*3ac0a46fSAndroid Build Coastguard Worker
376*3ac0a46fSAndroid Build Coastguard Worker if (!CPDFSDK_Annot::OnLButtonDblClk(pAnnot, nFlags, point))
377*3ac0a46fSAndroid Build Coastguard Worker return false;
378*3ac0a46fSAndroid Build Coastguard Worker
379*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
380*3ac0a46fSAndroid Build Coastguard Worker return false;
381*3ac0a46fSAndroid Build Coastguard Worker
382*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SetFocusAnnot(pAnnot);
383*3ac0a46fSAndroid Build Coastguard Worker return true;
384*3ac0a46fSAndroid Build Coastguard Worker }
385*3ac0a46fSAndroid Build Coastguard Worker
OnRButtonDown(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)386*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnRButtonDown(Mask<FWL_EVENTFLAG> nFlags,
387*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
388*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
389*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
390*3ac0a46fSAndroid Build Coastguard Worker return false;
391*3ac0a46fSAndroid Build Coastguard Worker
392*3ac0a46fSAndroid Build Coastguard Worker bool ok = CPDFSDK_Annot::OnRButtonDown(pAnnot, nFlags, point);
393*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
394*3ac0a46fSAndroid Build Coastguard Worker return false;
395*3ac0a46fSAndroid Build Coastguard Worker
396*3ac0a46fSAndroid Build Coastguard Worker if (ok)
397*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SetFocusAnnot(pAnnot);
398*3ac0a46fSAndroid Build Coastguard Worker
399*3ac0a46fSAndroid Build Coastguard Worker return true;
400*3ac0a46fSAndroid Build Coastguard Worker }
401*3ac0a46fSAndroid Build Coastguard Worker
OnRButtonUp(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)402*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnRButtonUp(Mask<FWL_EVENTFLAG> nFlags,
403*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
404*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
405*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
406*3ac0a46fSAndroid Build Coastguard Worker return false;
407*3ac0a46fSAndroid Build Coastguard Worker
408*3ac0a46fSAndroid Build Coastguard Worker bool ok = CPDFSDK_Annot::OnRButtonUp(pAnnot, nFlags, point);
409*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
410*3ac0a46fSAndroid Build Coastguard Worker return false;
411*3ac0a46fSAndroid Build Coastguard Worker
412*3ac0a46fSAndroid Build Coastguard Worker if (ok)
413*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->SetFocusAnnot(pAnnot);
414*3ac0a46fSAndroid Build Coastguard Worker
415*3ac0a46fSAndroid Build Coastguard Worker return true;
416*3ac0a46fSAndroid Build Coastguard Worker }
417*3ac0a46fSAndroid Build Coastguard Worker
OnMouseMove(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point)418*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnMouseMove(Mask<FWL_EVENTFLAG> nFlags,
419*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
420*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pFXAnnot(GetFXAnnotAtPoint(point));
421*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_PageView> pThis(this);
422*3ac0a46fSAndroid Build Coastguard Worker
423*3ac0a46fSAndroid Build Coastguard Worker if (m_bOnWidget && m_pCaptureWidget != pFXAnnot)
424*3ac0a46fSAndroid Build Coastguard Worker ExitWidget(true, nFlags);
425*3ac0a46fSAndroid Build Coastguard Worker
426*3ac0a46fSAndroid Build Coastguard Worker // ExitWidget() may have invalidated objects.
427*3ac0a46fSAndroid Build Coastguard Worker if (!pThis || !pFXAnnot)
428*3ac0a46fSAndroid Build Coastguard Worker return false;
429*3ac0a46fSAndroid Build Coastguard Worker
430*3ac0a46fSAndroid Build Coastguard Worker if (!m_bOnWidget) {
431*3ac0a46fSAndroid Build Coastguard Worker EnterWidget(pFXAnnot, nFlags);
432*3ac0a46fSAndroid Build Coastguard Worker
433*3ac0a46fSAndroid Build Coastguard Worker // EnterWidget() may have invalidated objects.
434*3ac0a46fSAndroid Build Coastguard Worker if (!pThis)
435*3ac0a46fSAndroid Build Coastguard Worker return false;
436*3ac0a46fSAndroid Build Coastguard Worker
437*3ac0a46fSAndroid Build Coastguard Worker if (!pFXAnnot) {
438*3ac0a46fSAndroid Build Coastguard Worker ExitWidget(false, nFlags);
439*3ac0a46fSAndroid Build Coastguard Worker return true;
440*3ac0a46fSAndroid Build Coastguard Worker }
441*3ac0a46fSAndroid Build Coastguard Worker }
442*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot::OnMouseMove(pFXAnnot, nFlags, point);
443*3ac0a46fSAndroid Build Coastguard Worker return true;
444*3ac0a46fSAndroid Build Coastguard Worker }
445*3ac0a46fSAndroid Build Coastguard Worker
EnterWidget(ObservedPtr<CPDFSDK_Annot> & pAnnot,Mask<FWL_EVENTFLAG> nFlags)446*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::EnterWidget(ObservedPtr<CPDFSDK_Annot>& pAnnot,
447*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> nFlags) {
448*3ac0a46fSAndroid Build Coastguard Worker m_bOnWidget = true;
449*3ac0a46fSAndroid Build Coastguard Worker m_pCaptureWidget.Reset(pAnnot.Get());
450*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot::OnMouseEnter(m_pCaptureWidget, nFlags);
451*3ac0a46fSAndroid Build Coastguard Worker }
452*3ac0a46fSAndroid Build Coastguard Worker
ExitWidget(bool callExitCallback,Mask<FWL_EVENTFLAG> nFlags)453*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::ExitWidget(bool callExitCallback,
454*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> nFlags) {
455*3ac0a46fSAndroid Build Coastguard Worker m_bOnWidget = false;
456*3ac0a46fSAndroid Build Coastguard Worker if (!m_pCaptureWidget)
457*3ac0a46fSAndroid Build Coastguard Worker return;
458*3ac0a46fSAndroid Build Coastguard Worker
459*3ac0a46fSAndroid Build Coastguard Worker if (callExitCallback) {
460*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_PageView> pThis(this);
461*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot::OnMouseExit(m_pCaptureWidget, nFlags);
462*3ac0a46fSAndroid Build Coastguard Worker
463*3ac0a46fSAndroid Build Coastguard Worker // OnMouseExit() may have invalidated |this|.
464*3ac0a46fSAndroid Build Coastguard Worker if (!pThis)
465*3ac0a46fSAndroid Build Coastguard Worker return;
466*3ac0a46fSAndroid Build Coastguard Worker }
467*3ac0a46fSAndroid Build Coastguard Worker
468*3ac0a46fSAndroid Build Coastguard Worker m_pCaptureWidget.Reset();
469*3ac0a46fSAndroid Build Coastguard Worker }
470*3ac0a46fSAndroid Build Coastguard Worker
OnMouseWheel(Mask<FWL_EVENTFLAG> nFlags,const CFX_PointF & point,const CFX_Vector & delta)471*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnMouseWheel(Mask<FWL_EVENTFLAG> nFlags,
472*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point,
473*3ac0a46fSAndroid Build Coastguard Worker const CFX_Vector& delta) {
474*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFXWidgetAtPoint(point));
475*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
476*3ac0a46fSAndroid Build Coastguard Worker return false;
477*3ac0a46fSAndroid Build Coastguard Worker
478*3ac0a46fSAndroid Build Coastguard Worker return CPDFSDK_Annot::OnMouseWheel(pAnnot, nFlags, point, delta);
479*3ac0a46fSAndroid Build Coastguard Worker }
480*3ac0a46fSAndroid Build Coastguard Worker
SetIndexSelected(int index,bool selected)481*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::SetIndexSelected(int index, bool selected) {
482*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
483*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->SetIndexSelected(index, selected);
484*3ac0a46fSAndroid Build Coastguard Worker }
485*3ac0a46fSAndroid Build Coastguard Worker
IsIndexSelected(int index)486*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::IsIndexSelected(int index) {
487*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* annot = GetFocusAnnot();
488*3ac0a46fSAndroid Build Coastguard Worker return annot && annot->IsIndexSelected(index);
489*3ac0a46fSAndroid Build Coastguard Worker }
490*3ac0a46fSAndroid Build Coastguard Worker
OnChar(uint32_t nChar,Mask<FWL_EVENTFLAG> nFlags)491*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnChar(uint32_t nChar, Mask<FWL_EVENTFLAG> nFlags) {
492*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFocusAnnot());
493*3ac0a46fSAndroid Build Coastguard Worker return pAnnot && CPDFSDK_Annot::OnChar(pAnnot, nChar, nFlags);
494*3ac0a46fSAndroid Build Coastguard Worker }
495*3ac0a46fSAndroid Build Coastguard Worker
OnKeyDown(FWL_VKEYCODE nKeyCode,Mask<FWL_EVENTFLAG> nFlags)496*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::OnKeyDown(FWL_VKEYCODE nKeyCode,
497*3ac0a46fSAndroid Build Coastguard Worker Mask<FWL_EVENTFLAG> nFlags) {
498*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(GetFocusAnnot());
499*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot) {
500*3ac0a46fSAndroid Build Coastguard Worker // If pressed key is not tab then no action is needed.
501*3ac0a46fSAndroid Build Coastguard Worker if (nKeyCode != FWL_VKEY_Tab)
502*3ac0a46fSAndroid Build Coastguard Worker return false;
503*3ac0a46fSAndroid Build Coastguard Worker
504*3ac0a46fSAndroid Build Coastguard Worker // If ctrl key or alt key is pressed, then no action is needed.
505*3ac0a46fSAndroid Build Coastguard Worker if (CPWL_Wnd::IsCTRLKeyDown(nFlags) || CPWL_Wnd::IsALTKeyDown(nFlags))
506*3ac0a46fSAndroid Build Coastguard Worker return false;
507*3ac0a46fSAndroid Build Coastguard Worker
508*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> end_annot(CPWL_Wnd::IsSHIFTKeyDown(nFlags)
509*3ac0a46fSAndroid Build Coastguard Worker ? GetLastFocusableAnnot()
510*3ac0a46fSAndroid Build Coastguard Worker : GetFirstFocusableAnnot());
511*3ac0a46fSAndroid Build Coastguard Worker return end_annot && m_pFormFillEnv->SetFocusAnnot(end_annot);
512*3ac0a46fSAndroid Build Coastguard Worker }
513*3ac0a46fSAndroid Build Coastguard Worker
514*3ac0a46fSAndroid Build Coastguard Worker if (CPWL_Wnd::IsCTRLKeyDown(nFlags) || CPWL_Wnd::IsALTKeyDown(nFlags))
515*3ac0a46fSAndroid Build Coastguard Worker return CPDFSDK_Annot::OnKeyDown(pAnnot, nKeyCode, nFlags);
516*3ac0a46fSAndroid Build Coastguard Worker
517*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* pFocusAnnot = GetFocusAnnot();
518*3ac0a46fSAndroid Build Coastguard Worker if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
519*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pNext(CPWL_Wnd::IsSHIFTKeyDown(nFlags)
520*3ac0a46fSAndroid Build Coastguard Worker ? GetPrevAnnot(pFocusAnnot)
521*3ac0a46fSAndroid Build Coastguard Worker : GetNextAnnot(pFocusAnnot));
522*3ac0a46fSAndroid Build Coastguard Worker if (!pNext)
523*3ac0a46fSAndroid Build Coastguard Worker return false;
524*3ac0a46fSAndroid Build Coastguard Worker if (pNext.Get() != pFocusAnnot) {
525*3ac0a46fSAndroid Build Coastguard Worker GetFormFillEnv()->SetFocusAnnot(pNext);
526*3ac0a46fSAndroid Build Coastguard Worker return true;
527*3ac0a46fSAndroid Build Coastguard Worker }
528*3ac0a46fSAndroid Build Coastguard Worker }
529*3ac0a46fSAndroid Build Coastguard Worker
530*3ac0a46fSAndroid Build Coastguard Worker // Check |pAnnot| again because JS may have destroyed it in GetNextAnnot().
531*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
532*3ac0a46fSAndroid Build Coastguard Worker return false;
533*3ac0a46fSAndroid Build Coastguard Worker
534*3ac0a46fSAndroid Build Coastguard Worker return CPDFSDK_Annot::OnKeyDown(pAnnot, nKeyCode, nFlags);
535*3ac0a46fSAndroid Build Coastguard Worker }
536*3ac0a46fSAndroid Build Coastguard Worker
LoadFXAnnots()537*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::LoadFXAnnots() {
538*3ac0a46fSAndroid Build Coastguard Worker AutoRestorer<bool> lock(&m_bLocked);
539*3ac0a46fSAndroid Build Coastguard Worker m_bLocked = true;
540*3ac0a46fSAndroid Build Coastguard Worker
541*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
542*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> protector(ToXFAPage(m_page));
543*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document::Extension* pContext = m_pFormFillEnv->GetDocExtension();
544*3ac0a46fSAndroid Build Coastguard Worker if (pContext && pContext->ContainsExtensionFullForm()) {
545*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pageView = protector->GetXFAPageView();
546*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageWidgetIterator pWidgetHandler(
547*3ac0a46fSAndroid Build Coastguard Worker pageView, Mask<XFA_WidgetStatus>{XFA_WidgetStatus::kVisible,
548*3ac0a46fSAndroid Build Coastguard Worker XFA_WidgetStatus::kViewable});
549*3ac0a46fSAndroid Build Coastguard Worker
550*3ac0a46fSAndroid Build Coastguard Worker while (CXFA_FFWidget* pXFAAnnot = pWidgetHandler.MoveToNext()) {
551*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.push_back(
552*3ac0a46fSAndroid Build Coastguard Worker std::make_unique<CPDFXFA_Widget>(pXFAAnnot, this));
553*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.back()->OnLoad();
554*3ac0a46fSAndroid Build Coastguard Worker }
555*3ac0a46fSAndroid Build Coastguard Worker return;
556*3ac0a46fSAndroid Build Coastguard Worker }
557*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
558*3ac0a46fSAndroid Build Coastguard Worker
559*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPage = GetPDFPage();
560*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pPage);
561*3ac0a46fSAndroid Build Coastguard Worker bool bUpdateAP = CPDF_InteractiveForm::IsUpdateAPEnabled();
562*3ac0a46fSAndroid Build Coastguard Worker // Disable the default AP construction.
563*3ac0a46fSAndroid Build Coastguard Worker CPDF_InteractiveForm::SetUpdateAP(false);
564*3ac0a46fSAndroid Build Coastguard Worker m_pAnnotList = std::make_unique<CPDF_AnnotList>(pPage);
565*3ac0a46fSAndroid Build Coastguard Worker CPDF_InteractiveForm::SetUpdateAP(bUpdateAP);
566*3ac0a46fSAndroid Build Coastguard Worker
567*3ac0a46fSAndroid Build Coastguard Worker const size_t nCount = m_pAnnotList->Count();
568*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < nCount; ++i) {
569*3ac0a46fSAndroid Build Coastguard Worker CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
570*3ac0a46fSAndroid Build Coastguard Worker CheckForUnsupportedAnnot(pPDFAnnot);
571*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CPDFSDK_Annot> pAnnot = NewAnnot(pPDFAnnot);
572*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnot)
573*3ac0a46fSAndroid Build Coastguard Worker continue;
574*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.push_back(std::move(pAnnot));
575*3ac0a46fSAndroid Build Coastguard Worker m_SDKAnnotArray.back()->OnLoad();
576*3ac0a46fSAndroid Build Coastguard Worker }
577*3ac0a46fSAndroid Build Coastguard Worker }
578*3ac0a46fSAndroid Build Coastguard Worker
UpdateRects(const std::vector<CFX_FloatRect> & rects)579*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) {
580*3ac0a46fSAndroid Build Coastguard Worker for (const auto& rc : rects)
581*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->Invalidate(m_page, rc.GetOuterRect());
582*3ac0a46fSAndroid Build Coastguard Worker }
583*3ac0a46fSAndroid Build Coastguard Worker
UpdateView(CPDFSDK_Annot * pAnnot)584*3ac0a46fSAndroid Build Coastguard Worker void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) {
585*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect rcWindow = pAnnot->GetRect();
586*3ac0a46fSAndroid Build Coastguard Worker m_pFormFillEnv->Invalidate(m_page, rcWindow.GetOuterRect());
587*3ac0a46fSAndroid Build Coastguard Worker }
588*3ac0a46fSAndroid Build Coastguard Worker
GetPageIndex() const589*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_PageView::GetPageIndex() const {
590*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
591*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document::Extension* pContext = m_page->GetDocument()->GetExtension();
592*3ac0a46fSAndroid Build Coastguard Worker if (pContext && pContext->ContainsExtensionFullForm()) {
593*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pPageView = m_page->AsXFAPage()->GetXFAPageView();
594*3ac0a46fSAndroid Build Coastguard Worker return pPageView ? pPageView->GetLayoutItem()->GetPageIndex() : -1;
595*3ac0a46fSAndroid Build Coastguard Worker }
596*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_ENABLE_XFA
597*3ac0a46fSAndroid Build Coastguard Worker return GetPageIndexForStaticPDF();
598*3ac0a46fSAndroid Build Coastguard Worker }
599*3ac0a46fSAndroid Build Coastguard Worker
IsValidAnnot(const CPDF_Annot * p) const600*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const {
601*3ac0a46fSAndroid Build Coastguard Worker return p && m_pAnnotList->Contains(p);
602*3ac0a46fSAndroid Build Coastguard Worker }
603*3ac0a46fSAndroid Build Coastguard Worker
IsValidSDKAnnot(const CPDFSDK_Annot * p) const604*3ac0a46fSAndroid Build Coastguard Worker bool CPDFSDK_PageView::IsValidSDKAnnot(const CPDFSDK_Annot* p) const {
605*3ac0a46fSAndroid Build Coastguard Worker return p && pdfium::Contains(m_SDKAnnotArray, fxcrt::MakeFakeUniquePtr(p));
606*3ac0a46fSAndroid Build Coastguard Worker }
607*3ac0a46fSAndroid Build Coastguard Worker
GetFocusAnnot()608*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() {
609*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_Annot* pFocusAnnot = m_pFormFillEnv->GetFocusAnnot();
610*3ac0a46fSAndroid Build Coastguard Worker return IsValidSDKAnnot(pFocusAnnot) ? pFocusAnnot : nullptr;
611*3ac0a46fSAndroid Build Coastguard Worker }
612*3ac0a46fSAndroid Build Coastguard Worker
GetPageIndexForStaticPDF() const613*3ac0a46fSAndroid Build Coastguard Worker int CPDFSDK_PageView::GetPageIndexForStaticPDF() const {
614*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = m_pFormFillEnv->GetPDFDocument();
615*3ac0a46fSAndroid Build Coastguard Worker return pDoc->GetPageIndex(GetPDFPage()->GetDict()->GetObjNum());
616*3ac0a46fSAndroid Build Coastguard Worker }
617