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 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 41 CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {} 42 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 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 60 void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) { 61 IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot); 62 pAnnotHandler->ReleaseAnnot(pAnnot); 63 } 64 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 74 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) { 75 ASSERT(pAnnot); 76 GetAnnotHandler(pAnnot)->OnLoad(pAnnot); 77 } 78 79 WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText( 80 CPDFSDK_Annot* pAnnot) { 81 return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot); 82 } 83 84 void CPDFSDK_AnnotHandlerMgr::Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot, 85 const WideString& text) { 86 GetAnnotHandler(pAnnot)->ReplaceSelection(pAnnot, text); 87 } 88 89 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler( 90 CPDFSDK_Annot* pAnnot) const { 91 return GetAnnotHandler(pAnnot->GetAnnotSubtype()); 92 } 93 94 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 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 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 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 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 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 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 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 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 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 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 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 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 232 bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot, 233 int nKeyCode, 234 int nFlag) { 235 return false; 236 } 237 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 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 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 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 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 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