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_xfawidgethandler.h" 8 9 #include "core/fpdfdoc/cpdf_interform.h" 10 #include "fpdfsdk/cpdfsdk_annot.h" 11 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" 12 #include "fpdfsdk/cpdfsdk_interform.h" 13 #include "fpdfsdk/cpdfsdk_pageview.h" 14 #include "fpdfsdk/cpdfsdk_xfawidget.h" 15 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" 16 #include "xfa/fwl/cfwl_app.h" 17 #include "xfa/fwl/fwl_widgethit.h" 18 #include "xfa/fxfa/fxfa_basic.h" 19 #include "xfa/fxfa/xfa_ffdocview.h" 20 #include "xfa/fxfa/xfa_ffpageview.h" 21 #include "xfa/fxfa/xfa_ffwidget.h" 22 #include "xfa/fxfa/xfa_ffwidgethandler.h" 23 #include "xfa/fxgraphics/cfx_graphics.h" 24 25 CPDFSDK_XFAWidgetHandler::CPDFSDK_XFAWidgetHandler( 26 CPDFSDK_FormFillEnvironment* pFormFillEnv) 27 : m_pFormFillEnv(pFormFillEnv) {} 28 29 CPDFSDK_XFAWidgetHandler::~CPDFSDK_XFAWidgetHandler() {} 30 31 bool CPDFSDK_XFAWidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) { 32 return !!pAnnot->GetXFAWidget(); 33 } 34 35 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CPDF_Annot* pAnnot, 36 CPDFSDK_PageView* pPage) { 37 return nullptr; 38 } 39 40 CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CXFA_FFWidget* pAnnot, 41 CPDFSDK_PageView* pPage) { 42 CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); 43 CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm); 44 pInterForm->AddXFAMap(pAnnot, pWidget); 45 return pWidget; 46 } 47 48 void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView, 49 CPDFSDK_Annot* pAnnot, 50 CFX_RenderDevice* pDevice, 51 CFX_Matrix* pUser2Device, 52 bool bDrawAnnots) { 53 ASSERT(pPageView); 54 ASSERT(pAnnot); 55 56 CFX_Graphics gs(pDevice); 57 58 CFX_Matrix mt = *pUser2Device; 59 bool bIsHighlight = false; 60 if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot) 61 bIsHighlight = true; 62 63 GetXFAWidgetHandler(pAnnot)->RenderWidget(pAnnot->GetXFAWidget(), &gs, &mt, 64 bIsHighlight); 65 66 // to do highlight and shadow 67 } 68 69 void CPDFSDK_XFAWidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {} 70 71 void CPDFSDK_XFAWidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) { 72 CPDFSDK_XFAWidget* pWidget = reinterpret_cast<CPDFSDK_XFAWidget*>(pAnnot); 73 CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm(); 74 pInterForm->RemoveXFAMap(pWidget->GetXFAWidget()); 75 76 delete pWidget; 77 } 78 79 CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, 80 CPDFSDK_Annot* pAnnot) { 81 ASSERT(pAnnot); 82 83 CFX_RectF rcBBox; 84 XFA_Element eType = pAnnot->GetXFAWidget()->GetDataAcc()->GetUIType(); 85 if (eType == XFA_Element::Signature) 86 rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_Visible, true); 87 else 88 rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_None); 89 90 CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, 91 rcBBox.top + rcBBox.height); 92 rcWidget.left -= 1.0f; 93 rcWidget.right += 1.0f; 94 rcWidget.bottom -= 1.0f; 95 rcWidget.top += 1.0f; 96 97 return rcWidget; 98 } 99 100 bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView, 101 CPDFSDK_Annot* pAnnot, 102 const CFX_PointF& point) { 103 if (!pPageView || !pAnnot) 104 return false; 105 106 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv(); 107 if (!pFormFillEnv) 108 return false; 109 110 CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext(); 111 if (!pContext) 112 return false; 113 114 CXFA_FFDocView* pDocView = pContext->GetXFADocView(); 115 if (!pDocView) 116 return false; 117 118 CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler(); 119 if (!pWidgetHandler) 120 return false; 121 122 FWL_WidgetHit dwHitTest = 123 pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point); 124 return dwHitTest != FWL_WidgetHit::Unknown; 125 } 126 127 void CPDFSDK_XFAWidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView, 128 CPDFSDK_Annot::ObservedPtr* pAnnot, 129 uint32_t nFlag) { 130 if (!pPageView || !(*pAnnot)) 131 return; 132 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 133 pWidgetHandler->OnMouseEnter((*pAnnot)->GetXFAWidget()); 134 } 135 136 void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView, 137 CPDFSDK_Annot::ObservedPtr* pAnnot, 138 uint32_t nFlag) { 139 if (!pPageView || !(*pAnnot)) 140 return; 141 142 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 143 pWidgetHandler->OnMouseExit((*pAnnot)->GetXFAWidget()); 144 } 145 146 bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, 147 CPDFSDK_Annot::ObservedPtr* pAnnot, 148 uint32_t nFlags, 149 const CFX_PointF& point) { 150 if (!pPageView || !(*pAnnot)) 151 return false; 152 153 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 154 return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(), 155 GetFWLFlags(nFlags), point); 156 } 157 158 bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, 159 CPDFSDK_Annot::ObservedPtr* pAnnot, 160 uint32_t nFlags, 161 const CFX_PointF& point) { 162 if (!pPageView || !(*pAnnot)) 163 return false; 164 165 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 166 return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(), 167 GetFWLFlags(nFlags), point); 168 } 169 170 bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk( 171 CPDFSDK_PageView* pPageView, 172 CPDFSDK_Annot::ObservedPtr* pAnnot, 173 uint32_t nFlags, 174 const CFX_PointF& point) { 175 if (!pPageView || !(*pAnnot)) 176 return false; 177 178 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 179 return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(), 180 GetFWLFlags(nFlags), point); 181 } 182 183 bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView, 184 CPDFSDK_Annot::ObservedPtr* pAnnot, 185 uint32_t nFlags, 186 const CFX_PointF& point) { 187 if (!pPageView || !(*pAnnot)) 188 return false; 189 190 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 191 return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(), 192 GetFWLFlags(nFlags), point); 193 } 194 195 bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, 196 CPDFSDK_Annot::ObservedPtr* pAnnot, 197 uint32_t nFlags, 198 short zDelta, 199 const CFX_PointF& point) { 200 if (!pPageView || !(*pAnnot)) 201 return false; 202 203 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 204 return pWidgetHandler->OnMouseWheel((*pAnnot)->GetXFAWidget(), 205 GetFWLFlags(nFlags), zDelta, point); 206 } 207 208 bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, 209 CPDFSDK_Annot::ObservedPtr* pAnnot, 210 uint32_t nFlags, 211 const CFX_PointF& point) { 212 if (!pPageView || !(*pAnnot)) 213 return false; 214 215 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 216 return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(), 217 GetFWLFlags(nFlags), point); 218 } 219 220 bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, 221 CPDFSDK_Annot::ObservedPtr* pAnnot, 222 uint32_t nFlags, 223 const CFX_PointF& point) { 224 if (!pPageView || !(*pAnnot)) 225 return false; 226 227 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 228 return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(), 229 GetFWLFlags(nFlags), point); 230 } 231 232 bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk( 233 CPDFSDK_PageView* pPageView, 234 CPDFSDK_Annot::ObservedPtr* pAnnot, 235 uint32_t nFlags, 236 const CFX_PointF& point) { 237 if (!pPageView || !(*pAnnot)) 238 return false; 239 240 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); 241 return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(), 242 GetFWLFlags(nFlags), point); 243 } 244 245 bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot, 246 uint32_t nChar, 247 uint32_t nFlags) { 248 if (!pAnnot) 249 return false; 250 251 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot); 252 return pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar, 253 GetFWLFlags(nFlags)); 254 } 255 256 bool CPDFSDK_XFAWidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot, 257 int nKeyCode, 258 int nFlag) { 259 if (!pAnnot) 260 return false; 261 262 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot); 263 return pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode, 264 GetFWLFlags(nFlag)); 265 } 266 267 bool CPDFSDK_XFAWidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot, 268 int nKeyCode, 269 int nFlag) { 270 if (!pAnnot) 271 return false; 272 273 CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot); 274 return pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode, 275 GetFWLFlags(nFlag)); 276 } 277 278 bool CPDFSDK_XFAWidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, 279 uint32_t nFlag) { 280 return true; 281 } 282 283 bool CPDFSDK_XFAWidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, 284 uint32_t nFlag) { 285 return true; 286 } 287 288 bool CPDFSDK_XFAWidgetHandler::OnXFAChangedFocus( 289 CPDFSDK_Annot::ObservedPtr* pOldAnnot, 290 CPDFSDK_Annot::ObservedPtr* pNewAnnot) { 291 CXFA_FFWidgetHandler* pWidgetHandler = nullptr; 292 if (*pOldAnnot) 293 pWidgetHandler = GetXFAWidgetHandler(pOldAnnot->Get()); 294 else if (*pNewAnnot) 295 pWidgetHandler = GetXFAWidgetHandler(pNewAnnot->Get()); 296 297 if (!pWidgetHandler) 298 return true; 299 300 CXFA_FFWidget* hWidget = *pNewAnnot ? (*pNewAnnot)->GetXFAWidget() : nullptr; 301 if (!hWidget) 302 return true; 303 304 CXFA_FFPageView* pXFAPageView = hWidget->GetPageView(); 305 if (!pXFAPageView) 306 return true; 307 308 bool bRet = pXFAPageView->GetDocView()->SetFocus(hWidget); 309 if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget) 310 bRet = true; 311 312 return bRet; 313 } 314 315 CXFA_FFWidgetHandler* CPDFSDK_XFAWidgetHandler::GetXFAWidgetHandler( 316 CPDFSDK_Annot* pAnnot) { 317 if (!pAnnot) 318 return nullptr; 319 320 CPDFSDK_PageView* pPageView = pAnnot->GetPageView(); 321 if (!pPageView) 322 return nullptr; 323 324 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv(); 325 if (!pFormFillEnv) 326 return nullptr; 327 328 CPDFXFA_Context* pDoc = pFormFillEnv->GetXFAContext(); 329 if (!pDoc) 330 return nullptr; 331 332 CXFA_FFDocView* pDocView = pDoc->GetXFADocView(); 333 if (!pDocView) 334 return nullptr; 335 336 return pDocView->GetWidgetHandler(); 337 } 338 339 uint32_t CPDFSDK_XFAWidgetHandler::GetFWLFlags(uint32_t dwFlag) { 340 uint32_t dwFWLFlag = 0; 341 342 if (dwFlag & FWL_EVENTFLAG_ControlKey) 343 dwFWLFlag |= FWL_KEYFLAG_Ctrl; 344 if (dwFlag & FWL_EVENTFLAG_LeftButtonDown) 345 dwFWLFlag |= FWL_KEYFLAG_LButton; 346 if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown) 347 dwFWLFlag |= FWL_KEYFLAG_MButton; 348 if (dwFlag & FWL_EVENTFLAG_RightButtonDown) 349 dwFWLFlag |= FWL_KEYFLAG_RButton; 350 if (dwFlag & FWL_EVENTFLAG_ShiftKey) 351 dwFWLFlag |= FWL_KEYFLAG_Shift; 352 if (dwFlag & FWL_EVENTFLAG_AltKey) 353 dwFWLFlag |= FWL_KEYFLAG_Alt; 354 355 return dwFWLFlag; 356 } 357