• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/cpdfsdk_annothandlermgr.h"
8 
9 #include "core/fpdfapi/parser/cpdf_number.h"
10 #include "core/fpdfapi/parser/cpdf_string.h"
11 #include "core/fpdfdoc/cpdf_annot.h"
12 #include "fpdfsdk/cba_annotiterator.h"
13 #include "fpdfsdk/cpdfsdk_annot.h"
14 #include "fpdfsdk/cpdfsdk_baannot.h"
15 #include "fpdfsdk/cpdfsdk_baannothandler.h"
16 #include "fpdfsdk/cpdfsdk_datetime.h"
17 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
18 #include "fpdfsdk/cpdfsdk_pageview.h"
19 #include "fpdfsdk/cpdfsdk_widgethandler.h"
20 #include "third_party/base/ptr_util.h"
21 
22 #ifdef PDF_ENABLE_XFA
23 #include "fpdfsdk/cpdfsdk_xfawidgethandler.h"
24 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
25 #include "xfa/fxfa/cxfa_ffpageview.h"
26 #include "xfa/fxfa/cxfa_ffwidget.h"
27 #endif  // PDF_ENABLE_XFA
28 
CPDFSDK_AnnotHandlerMgr(CPDFSDK_FormFillEnvironment * pFormFillEnv)29 CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
30     CPDFSDK_FormFillEnvironment* pFormFillEnv)
31     : m_pBAAnnotHandler(pdfium::MakeUnique<CPDFSDK_BAAnnotHandler>()),
32       m_pWidgetHandler(pdfium::MakeUnique<CPDFSDK_WidgetHandler>(pFormFillEnv))
33 #ifdef PDF_ENABLE_XFA
34       ,
35       m_pXFAWidgetHandler(
36           pdfium::MakeUnique<CPDFSDK_XFAWidgetHandler>(pFormFillEnv))
37 #endif  // PDF_ENABLE_XFA
38 {
39 }
40 
~CPDFSDK_AnnotHandlerMgr()41 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {}
42 
NewAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)43 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
44                                                  CPDFSDK_PageView* pPageView) {
45   ASSERT(pPageView);
46   return GetAnnotHandler(pAnnot->GetSubtype())->NewAnnot(pAnnot, pPageView);
47 }
48 
49 #ifdef PDF_ENABLE_XFA
NewAnnot(CXFA_FFWidget * pAnnot,CPDFSDK_PageView * pPageView)50 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CXFA_FFWidget* pAnnot,
51                                                  CPDFSDK_PageView* pPageView) {
52   ASSERT(pAnnot);
53   ASSERT(pPageView);
54 
55   return GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET)
56       ->NewAnnot(pAnnot, pPageView);
57 }
58 #endif  // PDF_ENABLE_XFA
59 
ReleaseAnnot(CPDFSDK_Annot * pAnnot)60 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
61   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
62   pAnnotHandler->ReleaseAnnot(pAnnot);
63 }
64 
Annot_OnCreate(CPDFSDK_Annot * pAnnot)65 void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) {
66   CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
67 
68   CPDFSDK_DateTime curTime;
69   pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
70       "M", curTime.ToPDFDateTimeString(), false);
71   pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0);
72 }
73 
Annot_OnLoad(CPDFSDK_Annot * pAnnot)74 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
75   ASSERT(pAnnot);
76   GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
77 }
78 
Annot_GetSelectedText(CPDFSDK_Annot * pAnnot)79 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText(
80     CPDFSDK_Annot* pAnnot) {
81   return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot);
82 }
83 
Annot_ReplaceSelection(CPDFSDK_Annot * pAnnot,const WideString & text)84 void CPDFSDK_AnnotHandlerMgr::Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot,
85                                                      const WideString& text) {
86   GetAnnotHandler(pAnnot)->ReplaceSelection(pAnnot, text);
87 }
88 
GetAnnotHandler(CPDFSDK_Annot * pAnnot) const89 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
90     CPDFSDK_Annot* pAnnot) const {
91   return GetAnnotHandler(pAnnot->GetAnnotSubtype());
92 }
93 
GetAnnotHandler(CPDF_Annot::Subtype nAnnotSubtype) const94 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
95     CPDF_Annot::Subtype nAnnotSubtype) const {
96   if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
97     return m_pWidgetHandler.get();
98 
99 #ifdef PDF_ENABLE_XFA
100   if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
101     return m_pXFAWidgetHandler.get();
102 #endif  // PDF_ENABLE_XFA
103 
104   return m_pBAAnnotHandler.get();
105 }
106 
Annot_OnDraw(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,bool bDrawAnnots)107 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
108                                            CPDFSDK_Annot* pAnnot,
109                                            CFX_RenderDevice* pDevice,
110                                            CFX_Matrix* pUser2Device,
111                                            bool bDrawAnnots) {
112   ASSERT(pAnnot);
113   GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, pUser2Device,
114                                   bDrawAnnots);
115 }
116 
Annot_OnLButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)117 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
118     CPDFSDK_PageView* pPageView,
119     CPDFSDK_Annot::ObservedPtr* pAnnot,
120     uint32_t nFlags,
121     const CFX_PointF& point) {
122   ASSERT(*pAnnot);
123   return GetAnnotHandler(pAnnot->Get())
124       ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
125 }
126 
Annot_OnLButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)127 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
128     CPDFSDK_PageView* pPageView,
129     CPDFSDK_Annot::ObservedPtr* pAnnot,
130     uint32_t nFlags,
131     const CFX_PointF& point) {
132   ASSERT(*pAnnot);
133   return GetAnnotHandler(pAnnot->Get())
134       ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
135 }
136 
Annot_OnLButtonDblClk(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)137 bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
138     CPDFSDK_PageView* pPageView,
139     CPDFSDK_Annot::ObservedPtr* pAnnot,
140     uint32_t nFlags,
141     const CFX_PointF& point) {
142   ASSERT(*pAnnot);
143   return GetAnnotHandler(pAnnot->Get())
144       ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
145 }
146 
Annot_OnMouseMove(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)147 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
148     CPDFSDK_PageView* pPageView,
149     CPDFSDK_Annot::ObservedPtr* pAnnot,
150     uint32_t nFlags,
151     const CFX_PointF& point) {
152   ASSERT(*pAnnot);
153   return GetAnnotHandler(pAnnot->Get())
154       ->OnMouseMove(pPageView, pAnnot, nFlags, point);
155 }
156 
Annot_OnMouseWheel(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,short zDelta,const CFX_PointF & point)157 bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
158     CPDFSDK_PageView* pPageView,
159     CPDFSDK_Annot::ObservedPtr* pAnnot,
160     uint32_t nFlags,
161     short zDelta,
162     const CFX_PointF& point) {
163   ASSERT(*pAnnot);
164   return GetAnnotHandler(pAnnot->Get())
165       ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
166 }
167 
Annot_OnRButtonDown(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)168 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
169     CPDFSDK_PageView* pPageView,
170     CPDFSDK_Annot::ObservedPtr* pAnnot,
171     uint32_t nFlags,
172     const CFX_PointF& point) {
173   ASSERT(*pAnnot);
174   return GetAnnotHandler(pAnnot->Get())
175       ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
176 }
177 
Annot_OnRButtonUp(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlags,const CFX_PointF & point)178 bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
179     CPDFSDK_PageView* pPageView,
180     CPDFSDK_Annot::ObservedPtr* pAnnot,
181     uint32_t nFlags,
182     const CFX_PointF& point) {
183   ASSERT(*pAnnot);
184   return GetAnnotHandler(pAnnot->Get())
185       ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
186 }
187 
Annot_OnMouseEnter(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)188 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
189     CPDFSDK_PageView* pPageView,
190     CPDFSDK_Annot::ObservedPtr* pAnnot,
191     uint32_t nFlag) {
192   ASSERT(*pAnnot);
193   GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
194 }
195 
Annot_OnMouseExit(CPDFSDK_PageView * pPageView,CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)196 void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
197     CPDFSDK_PageView* pPageView,
198     CPDFSDK_Annot::ObservedPtr* pAnnot,
199     uint32_t nFlag) {
200   ASSERT(*pAnnot);
201   GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
202 }
203 
Annot_OnChar(CPDFSDK_Annot * pAnnot,uint32_t nChar,uint32_t nFlags)204 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
205                                            uint32_t nChar,
206                                            uint32_t nFlags) {
207   return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
208 }
209 
Annot_OnKeyDown(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)210 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
211                                               int nKeyCode,
212                                               int nFlag) {
213   if (CPDFSDK_FormFillEnvironment::IsCTRLKeyDown(nFlag) ||
214       CPDFSDK_FormFillEnvironment::IsALTKeyDown(nFlag)) {
215     return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
216   }
217 
218   CPDFSDK_PageView* pPage = pAnnot->GetPageView();
219   CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
220   if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
221     CPDFSDK_Annot::ObservedPtr pNext(GetNextAnnot(
222         pFocusAnnot, !CPDFSDK_FormFillEnvironment::IsSHIFTKeyDown(nFlag)));
223     if (pNext && pNext.Get() != pFocusAnnot) {
224       pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
225       return true;
226     }
227   }
228 
229   return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
230 }
231 
Annot_OnKeyUp(CPDFSDK_Annot * pAnnot,int nKeyCode,int nFlag)232 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot,
233                                             int nKeyCode,
234                                             int nFlag) {
235   return false;
236 }
237 
Annot_OnSetFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)238 bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
239     CPDFSDK_Annot::ObservedPtr* pAnnot,
240     uint32_t nFlag) {
241   ASSERT(*pAnnot);
242   return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
243 }
244 
Annot_OnKillFocus(CPDFSDK_Annot::ObservedPtr * pAnnot,uint32_t nFlag)245 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
246     CPDFSDK_Annot::ObservedPtr* pAnnot,
247     uint32_t nFlag) {
248   ASSERT(*pAnnot);
249   return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
250 }
251 
252 #ifdef PDF_ENABLE_XFA
Annot_OnChangeFocus(CPDFSDK_Annot::ObservedPtr * pSetAnnot,CPDFSDK_Annot::ObservedPtr * pKillAnnot)253 bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
254     CPDFSDK_Annot::ObservedPtr* pSetAnnot,
255     CPDFSDK_Annot::ObservedPtr* pKillAnnot) {
256   bool bXFA = (*pSetAnnot && (*pSetAnnot)->GetXFAWidget()) ||
257               (*pKillAnnot && (*pKillAnnot)->GetXFAWidget());
258 
259   if (bXFA) {
260     if (IPDFSDK_AnnotHandler* pXFAAnnotHandler =
261             GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET))
262       return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
263   }
264 
265   return true;
266 }
267 #endif  // PDF_ENABLE_XFA
268 
Annot_OnGetViewBBox(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot)269 CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
270     CPDFSDK_PageView* pPageView,
271     CPDFSDK_Annot* pAnnot) {
272   ASSERT(pAnnot);
273   return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
274 }
275 
Annot_OnHitTest(CPDFSDK_PageView * pPageView,CPDFSDK_Annot * pAnnot,const CFX_PointF & point)276 bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
277                                               CPDFSDK_Annot* pAnnot,
278                                               const CFX_PointF& point) {
279   ASSERT(pAnnot);
280   IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
281   if (pAnnotHandler->CanAnswer(pAnnot))
282     return pAnnotHandler->HitTest(pPageView, pAnnot, point);
283 
284   return false;
285 }
286 
GetNextAnnot(CPDFSDK_Annot * pSDKAnnot,bool bNext)287 CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
288                                                      bool bNext) {
289 #ifdef PDF_ENABLE_XFA
290   CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
291   CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
292   if (!pPage)
293     return nullptr;
294   if (pPage->GetPDFPage()) {  // for pdf annots.
295     CBA_AnnotIterator ai(pSDKAnnot->GetPageView(),
296                          pSDKAnnot->GetAnnotSubtype());
297     CPDFSDK_Annot* pNext =
298         bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
299     return pNext;
300   }
301   // for xfa annots
302   std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
303       pPage->GetXFAPageView()->CreateWidgetIterator(
304           XFA_TRAVERSEWAY_Tranvalse, XFA_WidgetStatus_Visible |
305                                          XFA_WidgetStatus_Viewable |
306                                          XFA_WidgetStatus_Focused));
307   if (!pWidgetIterator)
308     return nullptr;
309   if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
310     pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
311   CXFA_FFWidget* hNextFocus =
312       bNext ? pWidgetIterator->MoveToNext() : pWidgetIterator->MoveToPrevious();
313   if (!hNextFocus && pSDKAnnot)
314     hNextFocus = pWidgetIterator->MoveToFirst();
315 
316   return pPageView->GetAnnotByXFAWidget(hNextFocus);
317 #else   // PDF_ENABLE_XFA
318   CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), CPDF_Annot::Subtype::WIDGET);
319   return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
320 #endif  // PDF_ENABLE_XFA
321 }
322