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