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_widgethandler.h" 8 9 #include <memory> 10 #include <vector> 11 12 #include "core/fpdfapi/page/cpdf_page.h" 13 #include "core/fpdfapi/parser/cpdf_document.h" 14 #include "core/fpdfdoc/cpdf_interform.h" 15 #include "fpdfsdk/cpdfsdk_annot.h" 16 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" 17 #include "fpdfsdk/cpdfsdk_interform.h" 18 #include "fpdfsdk/cpdfsdk_pageview.h" 19 #include "fpdfsdk/cpdfsdk_widget.h" 20 #include "fpdfsdk/formfiller/cffl_formfiller.h" 21 22 #ifdef PDF_ENABLE_XFA 23 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" 24 #endif // PDF_ENABLE_XFA 25 26 CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler( 27 CPDFSDK_FormFillEnvironment* pFormFillEnv) 28 : m_pFormFillEnv(pFormFillEnv), 29 m_pFormFiller(pFormFillEnv->GetInteractiveFormFiller()) {} 30 31 CPDFSDK_WidgetHandler::~CPDFSDK_WidgetHandler() {} 32 33 bool CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) { 34 ASSERT(pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET); 35 if (pAnnot->IsSignatureWidget()) 36 return false; 37 38 CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot); 39 if (!pWidget->IsVisible()) 40 return false; 41 42 int nFieldFlags = pWidget->GetFieldFlags(); 43 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) 44 return false; 45 46 if (pWidget->GetFieldType() == FormFieldType::kPushButton) 47 return true; 48 49 CPDF_Page* pPage = pWidget->GetPDFPage(); 50 uint32_t dwPermissions = pPage->m_pDocument->GetUserPermissions(); 51 return (dwPermissions & FPDFPERM_FILL_FORM) || 52 (dwPermissions & FPDFPERM_ANNOT_FORM); 53 } 54 55 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CPDF_Annot* pAnnot, 56 CPDFSDK_PageView* pPage) { 57 CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); 58 CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl( 59 pInterForm->GetInterForm(), pAnnot->GetAnnotDict()); 60 if (!pCtrl) 61 return nullptr; 62 63 CPDFSDK_Widget* pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm); 64 pInterForm->AddMap(pCtrl, pWidget); 65 CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm(); 66 if (pPDFInterForm && pPDFInterForm->NeedConstructAP()) 67 pWidget->ResetAppearance(nullptr, false); 68 69 return pWidget; 70 } 71 72 #ifdef PDF_ENABLE_XFA 73 CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CXFA_FFWidget* hWidget, 74 CPDFSDK_PageView* pPage) { 75 return nullptr; 76 } 77 #endif // PDF_ENABLE_XFA 78 79 void CPDFSDK_WidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) { 80 ASSERT(pAnnot); 81 82 if (m_pFormFiller) 83 m_pFormFiller->OnDelete(pAnnot); 84 85 std::unique_ptr<CPDFSDK_Widget> pWidget(static_cast<CPDFSDK_Widget*>(pAnnot)); 86 CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm(); 87 CPDF_FormControl* pControl = pWidget->GetFormControl(); 88 pInterForm->RemoveMap(pControl); 89 } 90 91 void CPDFSDK_WidgetHandler::OnDraw(CPDFSDK_PageView* pPageView, 92 CPDFSDK_Annot* pAnnot, 93 CFX_RenderDevice* pDevice, 94 CFX_Matrix* pUser2Device, 95 bool bDrawAnnots) { 96 if (pAnnot->IsSignatureWidget()) { 97 static_cast<CPDFSDK_BAAnnot*>(pAnnot)->DrawAppearance( 98 pDevice, *pUser2Device, CPDF_Annot::Normal, nullptr); 99 } else { 100 if (m_pFormFiller) 101 m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device); 102 } 103 } 104 105 void CPDFSDK_WidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView, 106 CPDFSDK_Annot::ObservedPtr* pAnnot, 107 uint32_t nFlag) { 108 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 109 m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag); 110 } 111 112 void CPDFSDK_WidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView, 113 CPDFSDK_Annot::ObservedPtr* pAnnot, 114 uint32_t nFlag) { 115 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 116 m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag); 117 } 118 119 bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, 120 CPDFSDK_Annot::ObservedPtr* pAnnot, 121 uint32_t nFlags, 122 const CFX_PointF& point) { 123 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 124 return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point); 125 126 return false; 127 } 128 129 bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, 130 CPDFSDK_Annot::ObservedPtr* pAnnot, 131 uint32_t nFlags, 132 const CFX_PointF& point) { 133 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 134 return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point); 135 136 return false; 137 } 138 139 bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView, 140 CPDFSDK_Annot::ObservedPtr* pAnnot, 141 uint32_t nFlags, 142 const CFX_PointF& point) { 143 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 144 return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point); 145 146 return false; 147 } 148 149 bool CPDFSDK_WidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView, 150 CPDFSDK_Annot::ObservedPtr* pAnnot, 151 uint32_t nFlags, 152 const CFX_PointF& point) { 153 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 154 return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point); 155 156 return false; 157 } 158 159 bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, 160 CPDFSDK_Annot::ObservedPtr* pAnnot, 161 uint32_t nFlags, 162 short zDelta, 163 const CFX_PointF& point) { 164 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 165 return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, 166 point); 167 168 return false; 169 } 170 171 bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, 172 CPDFSDK_Annot::ObservedPtr* pAnnot, 173 uint32_t nFlags, 174 const CFX_PointF& point) { 175 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 176 return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point); 177 178 return false; 179 } 180 181 bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, 182 CPDFSDK_Annot::ObservedPtr* pAnnot, 183 uint32_t nFlags, 184 const CFX_PointF& point) { 185 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 186 return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point); 187 188 return false; 189 } 190 191 bool CPDFSDK_WidgetHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView, 192 CPDFSDK_Annot::ObservedPtr* pAnnot, 193 uint32_t nFlags, 194 const CFX_PointF& point) { 195 return false; 196 } 197 198 bool CPDFSDK_WidgetHandler::OnChar(CPDFSDK_Annot* pAnnot, 199 uint32_t nChar, 200 uint32_t nFlags) { 201 if (!pAnnot->IsSignatureWidget() && m_pFormFiller) 202 return m_pFormFiller->OnChar(pAnnot, nChar, nFlags); 203 204 return false; 205 } 206 207 bool CPDFSDK_WidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot, 208 int nKeyCode, 209 int nFlag) { 210 if (!pAnnot->IsSignatureWidget() && m_pFormFiller) 211 return m_pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlag); 212 213 return false; 214 } 215 216 bool CPDFSDK_WidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot, 217 int nKeyCode, 218 int nFlag) { 219 return false; 220 } 221 222 void CPDFSDK_WidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) { 223 if (pAnnot->IsSignatureWidget()) 224 return; 225 226 CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot); 227 if (!pWidget->IsAppearanceValid()) 228 pWidget->ResetAppearance(nullptr, false); 229 230 FormFieldType fieldType = pWidget->GetFieldType(); 231 if (fieldType == FormFieldType::kTextField || 232 fieldType == FormFieldType::kComboBox) { 233 bool bFormatted = false; 234 CPDFSDK_Annot::ObservedPtr pObserved(pWidget); 235 WideString sValue = pWidget->OnFormat(bFormatted); 236 if (!pObserved) 237 return; 238 239 if (bFormatted && fieldType == FormFieldType::kComboBox) 240 pWidget->ResetAppearance(&sValue, false); 241 } 242 243 #ifdef PDF_ENABLE_XFA 244 CPDFSDK_PageView* pPageView = pAnnot->GetPageView(); 245 CPDFXFA_Context* pContext = pPageView->GetFormFillEnv()->GetXFAContext(); 246 if (pContext->GetFormType() == FormType::kXFAForeground) { 247 if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty()) 248 pWidget->ResetAppearance(false); 249 } 250 #endif // PDF_ENABLE_XFA 251 } 252 253 bool CPDFSDK_WidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, 254 uint32_t nFlag) { 255 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 256 return m_pFormFiller->OnSetFocus(pAnnot, nFlag); 257 258 return true; 259 } 260 261 bool CPDFSDK_WidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, 262 uint32_t nFlag) { 263 if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) 264 return m_pFormFiller->OnKillFocus(pAnnot, nFlag); 265 266 return true; 267 } 268 269 #ifdef PDF_ENABLE_XFA 270 bool CPDFSDK_WidgetHandler::OnXFAChangedFocus( 271 CPDFSDK_Annot::ObservedPtr* pOldAnnot, 272 CPDFSDK_Annot::ObservedPtr* pNewAnnot) { 273 return true; 274 } 275 #endif // PDF_ENABLE_XFA 276 277 CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, 278 CPDFSDK_Annot* pAnnot) { 279 if (!pAnnot->IsSignatureWidget() && m_pFormFiller) 280 return CFX_FloatRect(m_pFormFiller->GetViewBBox(pPageView, pAnnot)); 281 return CFX_FloatRect(); 282 } 283 284 WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) { 285 if (!pAnnot->IsSignatureWidget() && m_pFormFiller) 286 return m_pFormFiller->GetSelectedText(pAnnot); 287 288 return WideString(); 289 } 290 291 void CPDFSDK_WidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot, 292 const WideString& text) { 293 if (!pAnnot->IsSignatureWidget() && m_pFormFiller) 294 m_pFormFiller->ReplaceSelection(pAnnot, text); 295 } 296 297 bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView, 298 CPDFSDK_Annot* pAnnot, 299 const CFX_PointF& point) { 300 ASSERT(pPageView); 301 ASSERT(pAnnot); 302 return GetViewBBox(pPageView, pAnnot).Contains(point); 303 } 304