1 // Copyright 2014 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 "xfa/fxfa/xfa_ffdocview.h" 8 9 #include "core/fxcrt/fx_ext.h" 10 #include "third_party/base/ptr_util.h" 11 #include "third_party/base/stl_util.h" 12 #include "xfa/fxfa/app/xfa_ffbarcode.h" 13 #include "xfa/fxfa/app/xfa_ffcheckbutton.h" 14 #include "xfa/fxfa/app/xfa_ffchoicelist.h" 15 #include "xfa/fxfa/app/xfa_ffdraw.h" 16 #include "xfa/fxfa/app/xfa_ffexclgroup.h" 17 #include "xfa/fxfa/app/xfa_fffield.h" 18 #include "xfa/fxfa/app/xfa_ffimage.h" 19 #include "xfa/fxfa/app/xfa_ffimageedit.h" 20 #include "xfa/fxfa/app/xfa_ffpath.h" 21 #include "xfa/fxfa/app/xfa_ffpushbutton.h" 22 #include "xfa/fxfa/app/xfa_ffsignature.h" 23 #include "xfa/fxfa/app/xfa_ffsubform.h" 24 #include "xfa/fxfa/app/xfa_fftext.h" 25 #include "xfa/fxfa/app/xfa_fftextedit.h" 26 #include "xfa/fxfa/app/xfa_ffwidgetacc.h" 27 #include "xfa/fxfa/app/xfa_fwladapter.h" 28 #include "xfa/fxfa/parser/cxfa_binditems.h" 29 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" 30 #include "xfa/fxfa/parser/cxfa_scriptcontext.h" 31 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" 32 #include "xfa/fxfa/xfa_ffapp.h" 33 #include "xfa/fxfa/xfa_ffdoc.h" 34 #include "xfa/fxfa/xfa_ffpageview.h" 35 #include "xfa/fxfa/xfa_ffwidget.h" 36 #include "xfa/fxfa/xfa_ffwidgethandler.h" 37 38 const XFA_ATTRIBUTEENUM gs_EventActivity[] = { 39 XFA_ATTRIBUTEENUM_Click, XFA_ATTRIBUTEENUM_Change, 40 XFA_ATTRIBUTEENUM_DocClose, XFA_ATTRIBUTEENUM_DocReady, 41 XFA_ATTRIBUTEENUM_Enter, XFA_ATTRIBUTEENUM_Exit, 42 XFA_ATTRIBUTEENUM_Full, XFA_ATTRIBUTEENUM_IndexChange, 43 XFA_ATTRIBUTEENUM_Initialize, XFA_ATTRIBUTEENUM_MouseDown, 44 XFA_ATTRIBUTEENUM_MouseEnter, XFA_ATTRIBUTEENUM_MouseExit, 45 XFA_ATTRIBUTEENUM_MouseUp, XFA_ATTRIBUTEENUM_PostExecute, 46 XFA_ATTRIBUTEENUM_PostOpen, XFA_ATTRIBUTEENUM_PostPrint, 47 XFA_ATTRIBUTEENUM_PostSave, XFA_ATTRIBUTEENUM_PostSign, 48 XFA_ATTRIBUTEENUM_PostSubmit, XFA_ATTRIBUTEENUM_PreExecute, 49 XFA_ATTRIBUTEENUM_PreOpen, XFA_ATTRIBUTEENUM_PrePrint, 50 XFA_ATTRIBUTEENUM_PreSave, XFA_ATTRIBUTEENUM_PreSign, 51 XFA_ATTRIBUTEENUM_PreSubmit, XFA_ATTRIBUTEENUM_Ready, 52 XFA_ATTRIBUTEENUM_Unknown, 53 }; 54 55 CXFA_FFDocView::CXFA_FFDocView(CXFA_FFDoc* pDoc) 56 : m_bLayoutEvent(false), 57 m_pListFocusWidget(nullptr), 58 m_bInLayoutStatus(false), 59 m_pDoc(pDoc), 60 m_pXFADocLayout(nullptr), 61 m_pFocusAcc(nullptr), 62 m_pFocusWidget(nullptr), 63 m_pOldFocusWidget(nullptr), 64 m_iStatus(XFA_DOCVIEW_LAYOUTSTATUS_None), 65 m_iLock(0) {} 66 67 CXFA_FFDocView::~CXFA_FFDocView() { 68 DestroyDocView(); 69 } 70 71 void CXFA_FFDocView::InitLayout(CXFA_Node* pNode) { 72 RunBindItems(); 73 ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize, false, true, 74 nullptr); 75 ExecEventActivityByDeepFirst(pNode, XFA_EVENT_IndexChange, false, true, 76 nullptr); 77 } 78 int32_t CXFA_FFDocView::StartLayout(int32_t iStartPage) { 79 m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start; 80 m_pDoc->GetXFADoc()->DoProtoMerge(); 81 m_pDoc->GetXFADoc()->DoDataMerge(); 82 m_pXFADocLayout = GetXFALayout(); 83 int32_t iStatus = m_pXFADocLayout->StartLayout(); 84 if (iStatus < 0) { 85 return iStatus; 86 } 87 CXFA_Node* pRootItem = 88 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 89 if (!pRootItem) { 90 return iStatus; 91 } 92 InitLayout(pRootItem); 93 InitCalculate(pRootItem); 94 InitValidate(pRootItem); 95 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, true, true, nullptr); 96 m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start; 97 return iStatus; 98 } 99 int32_t CXFA_FFDocView::DoLayout(IFX_Pause* pPause) { 100 int32_t iStatus = 100; 101 iStatus = m_pXFADocLayout->DoLayout(pPause); 102 if (iStatus != 100) { 103 return iStatus; 104 } 105 m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Doing; 106 return iStatus; 107 } 108 void CXFA_FFDocView::StopLayout() { 109 CXFA_Node* pRootItem = 110 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 111 if (!pRootItem) { 112 return; 113 } 114 CXFA_Node* pSubformNode = pRootItem->GetChild(0, XFA_Element::Subform); 115 if (!pSubformNode) { 116 return; 117 } 118 CXFA_Node* pPageSetNode = 119 pSubformNode->GetFirstChildByClass(XFA_Element::PageSet); 120 if (!pPageSetNode) { 121 return; 122 } 123 RunCalculateWidgets(); 124 RunValidate(); 125 InitLayout(pPageSetNode); 126 InitCalculate(pPageSetNode); 127 InitValidate(pPageSetNode); 128 ExecEventActivityByDeepFirst(pPageSetNode, XFA_EVENT_Ready, true, true, 129 nullptr); 130 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, false, true, 131 nullptr); 132 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocReady, false, true, 133 nullptr); 134 RunCalculateWidgets(); 135 RunValidate(); 136 if (RunLayout()) { 137 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, false, true, 138 nullptr); 139 } 140 m_CalculateAccs.clear(); 141 if (m_pFocusAcc && !m_pFocusWidget) { 142 SetFocusWidgetAcc(m_pFocusAcc); 143 } 144 m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_End; 145 } 146 int32_t CXFA_FFDocView::GetLayoutStatus() { 147 return m_iStatus; 148 } 149 void CXFA_FFDocView::ShowNullTestMsg() { 150 int32_t iCount = pdfium::CollectionSize<int32_t>(m_arrNullTestMsg); 151 CXFA_FFApp* pApp = m_pDoc->GetApp(); 152 IXFA_AppProvider* pAppProvider = pApp->GetAppProvider(); 153 if (pAppProvider && iCount) { 154 int32_t iRemain = iCount > 7 ? iCount - 7 : 0; 155 iCount -= iRemain; 156 CFX_WideString wsMsg; 157 for (int32_t i = 0; i < iCount; i++) { 158 wsMsg += m_arrNullTestMsg[i] + L"\n"; 159 } 160 if (iRemain > 0) { 161 CFX_WideString wsTemp; 162 wsTemp.Format( 163 L"Message limit exceeded. Remaining %d " 164 L"validation errors not reported.", 165 iRemain); 166 wsMsg += L"\n" + wsTemp; 167 } 168 pAppProvider->MsgBox(wsMsg, pAppProvider->GetAppTitle(), XFA_MBICON_Status, 169 XFA_MB_OK); 170 } 171 m_arrNullTestMsg.clear(); 172 } 173 174 void CXFA_FFDocView::UpdateDocView() { 175 if (IsUpdateLocked()) 176 return; 177 178 LockUpdate(); 179 for (CXFA_Node* pNode : m_NewAddedNodes) { 180 InitCalculate(pNode); 181 InitValidate(pNode); 182 ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Ready, true, true, nullptr); 183 } 184 m_NewAddedNodes.clear(); 185 RunSubformIndexChange(); 186 RunCalculateWidgets(); 187 RunValidate(); 188 ShowNullTestMsg(); 189 if (RunLayout() && m_bLayoutEvent) 190 RunEventLayoutReady(); 191 192 m_bLayoutEvent = false; 193 m_CalculateAccs.clear(); 194 RunInvalidate(); 195 UnlockUpdate(); 196 } 197 198 int32_t CXFA_FFDocView::CountPageViews() { 199 if (!m_pXFADocLayout) { 200 return 0; 201 } 202 return m_pXFADocLayout->CountPages(); 203 } 204 CXFA_FFPageView* CXFA_FFDocView::GetPageView(int32_t nIndex) { 205 if (!m_pXFADocLayout) { 206 return nullptr; 207 } 208 return static_cast<CXFA_FFPageView*>(m_pXFADocLayout->GetPage(nIndex)); 209 } 210 211 CXFA_LayoutProcessor* CXFA_FFDocView::GetXFALayout() const { 212 return m_pDoc->GetXFADoc()->GetDocLayout(); 213 } 214 bool CXFA_FFDocView::ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc) { 215 CXFA_Node* pNode = pWidgetAcc->GetNode(); 216 XFA_Element eType = pNode->GetElementType(); 217 if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup) { 218 return false; 219 } 220 pWidgetAcc->ResetData(); 221 pWidgetAcc->UpdateUIDisplay(); 222 if (CXFA_Validate validate = pWidgetAcc->GetValidate()) { 223 AddValidateWidget(pWidgetAcc); 224 validate.GetNode()->SetFlag(XFA_NodeFlag_NeedsInitApp, false); 225 } 226 return true; 227 } 228 void CXFA_FFDocView::ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc) { 229 m_bLayoutEvent = true; 230 bool bChanged = false; 231 CXFA_Node* pFormNode = nullptr; 232 if (pWidgetAcc) { 233 bChanged = ResetSingleWidgetAccData(pWidgetAcc); 234 pFormNode = pWidgetAcc->GetNode(); 235 } else { 236 pFormNode = GetRootSubform(); 237 } 238 if (!pFormNode) { 239 return; 240 } 241 if (pFormNode->GetElementType() != XFA_Element::Field && 242 pFormNode->GetElementType() != XFA_Element::ExclGroup) { 243 CXFA_WidgetAccIterator Iterator(this, pFormNode); 244 while (CXFA_WidgetAcc* pAcc = Iterator.MoveToNext()) { 245 bChanged |= ResetSingleWidgetAccData(pAcc); 246 if (pAcc->GetNode()->GetElementType() == XFA_Element::ExclGroup) { 247 Iterator.SkipTree(); 248 } 249 } 250 } 251 if (bChanged) { 252 m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc); 253 } 254 } 255 int32_t CXFA_FFDocView::ProcessWidgetEvent(CXFA_EventParam* pParam, 256 CXFA_WidgetAcc* pWidgetAcc) { 257 if (!pParam) 258 return XFA_EVENTERROR_Error; 259 260 if (pParam->m_eType == XFA_EVENT_Validate) { 261 CFX_WideString wsValidateStr(L"preSubmit"); 262 CXFA_Node* pConfigItem = 263 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Config)); 264 if (pConfigItem) { 265 CXFA_Node* pValidateNode = nullptr; 266 CXFA_Node* pAcrobatNode = pConfigItem->GetChild(0, XFA_Element::Acrobat); 267 pValidateNode = pAcrobatNode 268 ? pAcrobatNode->GetChild(0, XFA_Element::Validate) 269 : nullptr; 270 if (!pValidateNode) { 271 CXFA_Node* pPresentNode = 272 pConfigItem->GetChild(0, XFA_Element::Present); 273 pValidateNode = pPresentNode 274 ? pPresentNode->GetChild(0, XFA_Element::Validate) 275 : nullptr; 276 } 277 if (pValidateNode) { 278 wsValidateStr = pValidateNode->GetContent(); 279 } 280 } 281 bool bValidate = false; 282 switch (pParam->m_iValidateActivities) { 283 case XFA_VALIDATE_preSubmit: 284 bValidate = wsValidateStr.Find(L"preSubmit") != -1; 285 break; 286 case XFA_VALIDATE_prePrint: 287 bValidate = wsValidateStr.Find(L"prePrint") != -1; 288 break; 289 case XFA_VALIDATE_preExecute: 290 bValidate = wsValidateStr.Find(L"preExecute") != -1; 291 break; 292 case XFA_VALIDATE_preSave: 293 bValidate = wsValidateStr.Find(L"preSave") != -1; 294 break; 295 } 296 if (!bValidate) { 297 return XFA_EVENTERROR_Success; 298 } 299 } 300 CXFA_Node* pNode = pWidgetAcc ? pWidgetAcc->GetNode() : nullptr; 301 if (!pNode) { 302 CXFA_Node* pRootItem = 303 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 304 if (!pRootItem) { 305 return XFA_EVENTERROR_Error; 306 } 307 pNode = pRootItem->GetChild(0, XFA_Element::Subform); 308 } 309 ExecEventActivityByDeepFirst(pNode, pParam->m_eType, pParam->m_bIsFormReady, 310 true, nullptr); 311 return XFA_EVENTERROR_Success; 312 } 313 CXFA_FFWidgetHandler* CXFA_FFDocView::GetWidgetHandler() { 314 if (!m_pWidgetHandler) 315 m_pWidgetHandler = pdfium::MakeUnique<CXFA_FFWidgetHandler>(this); 316 317 return m_pWidgetHandler.get(); 318 } 319 320 CXFA_WidgetAccIterator* CXFA_FFDocView::CreateWidgetAccIterator( 321 XFA_WIDGETORDER eOrder) { 322 CXFA_Node* pFormRoot = GetRootSubform(); 323 return pFormRoot ? new CXFA_WidgetAccIterator(this, pFormRoot) : nullptr; 324 } 325 CXFA_FFWidget* CXFA_FFDocView::GetFocusWidget() { 326 return m_pFocusWidget; 327 } 328 void CXFA_FFDocView::KillFocus() { 329 if (m_pFocusWidget && 330 (m_pFocusWidget->GetStatus() & XFA_WidgetStatus_Focused)) { 331 (m_pFocusWidget)->OnKillFocus(nullptr); 332 } 333 m_pFocusAcc = nullptr; 334 m_pFocusWidget = nullptr; 335 m_pOldFocusWidget = nullptr; 336 } 337 bool CXFA_FFDocView::SetFocus(CXFA_FFWidget* hWidget) { 338 CXFA_FFWidget* pNewFocus = hWidget; 339 if (m_pOldFocusWidget == pNewFocus) { 340 return false; 341 } 342 CXFA_FFWidget* pOldFocus = m_pOldFocusWidget; 343 m_pOldFocusWidget = pNewFocus; 344 if (pOldFocus) { 345 if (m_pFocusWidget != m_pOldFocusWidget && 346 (pOldFocus->GetStatus() & XFA_WidgetStatus_Focused)) { 347 m_pFocusWidget = pOldFocus; 348 pOldFocus->OnKillFocus(pNewFocus); 349 } else if ((pOldFocus->GetStatus() & XFA_WidgetStatus_Visible)) { 350 if (!pOldFocus->IsLoaded()) { 351 pOldFocus->LoadWidget(); 352 } 353 pOldFocus->OnSetFocus(m_pFocusWidget); 354 m_pFocusWidget = pOldFocus; 355 pOldFocus->OnKillFocus(pNewFocus); 356 } 357 } 358 if (m_pFocusWidget == m_pOldFocusWidget) { 359 return false; 360 } 361 pNewFocus = m_pOldFocusWidget; 362 if (m_pListFocusWidget && pNewFocus == m_pListFocusWidget) { 363 m_pFocusAcc = nullptr; 364 m_pFocusWidget = nullptr; 365 m_pListFocusWidget = nullptr; 366 m_pOldFocusWidget = nullptr; 367 return false; 368 } 369 if (pNewFocus && (pNewFocus->GetStatus() & XFA_WidgetStatus_Visible)) { 370 if (!pNewFocus->IsLoaded()) { 371 pNewFocus->LoadWidget(); 372 } 373 pNewFocus->OnSetFocus(m_pFocusWidget); 374 } 375 m_pFocusAcc = pNewFocus ? pNewFocus->GetDataAcc() : nullptr; 376 m_pFocusWidget = pNewFocus; 377 m_pOldFocusWidget = m_pFocusWidget; 378 return true; 379 } 380 CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc() { 381 return m_pFocusAcc; 382 } 383 void CXFA_FFDocView::SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) { 384 CXFA_FFWidget* pNewFocus = 385 pWidgetAcc ? pWidgetAcc->GetNextWidget(nullptr) : nullptr; 386 if (SetFocus(pNewFocus)) { 387 m_pFocusAcc = pWidgetAcc; 388 if (m_iStatus == XFA_DOCVIEW_LAYOUTSTATUS_End) { 389 m_pDoc->GetDocEnvironment()->SetFocusWidget(m_pDoc, m_pFocusWidget); 390 } 391 } 392 } 393 void CXFA_FFDocView::DeleteLayoutItem(CXFA_FFWidget* pWidget) { 394 if (m_pFocusAcc == pWidget->GetDataAcc()) { 395 m_pFocusAcc = nullptr; 396 m_pFocusWidget = nullptr; 397 m_pOldFocusWidget = nullptr; 398 } 399 } 400 static int32_t XFA_ProcessEvent(CXFA_FFDocView* pDocView, 401 CXFA_WidgetAcc* pWidgetAcc, 402 CXFA_EventParam* pParam) { 403 if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) { 404 return XFA_EVENTERROR_NotExist; 405 } 406 if (!pWidgetAcc || pWidgetAcc->GetElementType() == XFA_Element::Draw) { 407 return XFA_EVENTERROR_NotExist; 408 } 409 switch (pParam->m_eType) { 410 case XFA_EVENT_Calculate: 411 return pWidgetAcc->ProcessCalculate(); 412 case XFA_EVENT_Validate: 413 if (((CXFA_FFDoc*)pDocView->GetDoc()) 414 ->GetDocEnvironment() 415 ->IsValidationsEnabled(pDocView->GetDoc())) { 416 return pWidgetAcc->ProcessValidate(0x01); 417 } 418 return XFA_EVENTERROR_Disabled; 419 case XFA_EVENT_InitCalculate: { 420 CXFA_Calculate calc = pWidgetAcc->GetCalculate(); 421 if (!calc) { 422 return XFA_EVENTERROR_NotExist; 423 } 424 if (pWidgetAcc->GetNode()->IsUserInteractive()) 425 return XFA_EVENTERROR_Disabled; 426 427 CXFA_Script script = calc.GetScript(); 428 return pWidgetAcc->ExecuteScript(script, pParam); 429 } 430 default: 431 break; 432 } 433 int32_t iRet = 434 pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam); 435 return iRet; 436 } 437 int32_t CXFA_FFDocView::ExecEventActivityByDeepFirst(CXFA_Node* pFormNode, 438 XFA_EVENTTYPE eEventType, 439 bool bIsFormReady, 440 bool bRecursive, 441 CXFA_Node* pExclude) { 442 int32_t iRet = XFA_EVENTERROR_NotExist; 443 if (pFormNode == pExclude) { 444 return iRet; 445 } 446 XFA_Element elementType = pFormNode->GetElementType(); 447 if (elementType == XFA_Element::Field) { 448 if (eEventType == XFA_EVENT_IndexChange) { 449 return iRet; 450 } 451 CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData(); 452 if (!pWidgetAcc) { 453 return iRet; 454 } 455 CXFA_EventParam eParam; 456 eParam.m_eType = eEventType; 457 eParam.m_pTarget = pWidgetAcc; 458 eParam.m_bIsFormReady = bIsFormReady; 459 return XFA_ProcessEvent(this, pWidgetAcc, &eParam); 460 } 461 if (bRecursive) { 462 for (CXFA_Node* pNode = pFormNode->GetNodeItem( 463 XFA_NODEITEM_FirstChild, XFA_ObjectType::ContainerNode); 464 pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling, 465 XFA_ObjectType::ContainerNode)) { 466 elementType = pNode->GetElementType(); 467 if (elementType != XFA_Element::Variables && 468 elementType != XFA_Element::Draw) { 469 iRet |= ExecEventActivityByDeepFirst(pNode, eEventType, bIsFormReady, 470 bRecursive, pExclude); 471 } 472 } 473 } 474 CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData(); 475 if (!pWidgetAcc) { 476 return iRet; 477 } 478 CXFA_EventParam eParam; 479 eParam.m_eType = eEventType; 480 eParam.m_pTarget = pWidgetAcc; 481 eParam.m_bIsFormReady = bIsFormReady; 482 iRet |= XFA_ProcessEvent(this, pWidgetAcc, &eParam); 483 return iRet; 484 } 485 486 CXFA_FFWidget* CXFA_FFDocView::GetWidgetByName(const CFX_WideString& wsName, 487 CXFA_FFWidget* pRefWidget) { 488 CXFA_WidgetAcc* pRefAcc = pRefWidget ? pRefWidget->GetDataAcc() : nullptr; 489 CXFA_WidgetAcc* pAcc = GetWidgetAccByName(wsName, pRefAcc); 490 return pAcc ? pAcc->GetNextWidget(nullptr) : nullptr; 491 } 492 493 CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName( 494 const CFX_WideString& wsName, 495 CXFA_WidgetAcc* pRefWidgetAcc) { 496 CFX_WideString wsExpression; 497 uint32_t dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | 498 XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent; 499 CXFA_ScriptContext* pScriptContext = m_pDoc->GetXFADoc()->GetScriptContext(); 500 if (!pScriptContext) { 501 return nullptr; 502 } 503 CXFA_Node* refNode = nullptr; 504 if (pRefWidgetAcc) { 505 refNode = pRefWidgetAcc->GetNode(); 506 wsExpression = wsName; 507 } else { 508 wsExpression = L"$form." + wsName; 509 } 510 XFA_RESOLVENODE_RS resoveNodeRS; 511 int32_t iRet = pScriptContext->ResolveObjects( 512 refNode, wsExpression.AsStringC(), resoveNodeRS, dwStyle); 513 if (iRet < 1) { 514 return nullptr; 515 } 516 if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) { 517 CXFA_Node* pNode = resoveNodeRS.nodes[0]->AsNode(); 518 if (pNode) { 519 return (CXFA_WidgetAcc*)pNode->GetWidgetData(); 520 } 521 } 522 return nullptr; 523 } 524 525 void CXFA_FFDocView::OnPageEvent(CXFA_ContainerLayoutItem* pSender, 526 uint32_t dwEvent) { 527 CXFA_FFPageView* pFFPageView = static_cast<CXFA_FFPageView*>(pSender); 528 m_pDoc->GetDocEnvironment()->PageViewEvent(pFFPageView, dwEvent); 529 } 530 531 void CXFA_FFDocView::LockUpdate() { 532 m_iLock++; 533 } 534 void CXFA_FFDocView::UnlockUpdate() { 535 m_iLock--; 536 } 537 bool CXFA_FFDocView::IsUpdateLocked() { 538 return m_iLock > 0; 539 } 540 void CXFA_FFDocView::ClearInvalidateList() { 541 m_mapPageInvalidate.clear(); 542 } 543 void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget, 544 const CFX_RectF& rtInvalidate) { 545 AddInvalidateRect(pWidget->GetPageView(), rtInvalidate); 546 } 547 548 void CXFA_FFDocView::AddInvalidateRect(CXFA_FFPageView* pPageView, 549 const CFX_RectF& rtInvalidate) { 550 if (m_mapPageInvalidate[pPageView]) { 551 m_mapPageInvalidate[pPageView]->Union(rtInvalidate); 552 return; 553 } 554 m_mapPageInvalidate[pPageView] = pdfium::MakeUnique<CFX_RectF>(rtInvalidate); 555 } 556 557 void CXFA_FFDocView::RunInvalidate() { 558 for (const auto& pair : m_mapPageInvalidate) 559 m_pDoc->GetDocEnvironment()->InvalidateRect(pair.first, *pair.second, 0); 560 m_mapPageInvalidate.clear(); 561 } 562 563 bool CXFA_FFDocView::RunLayout() { 564 LockUpdate(); 565 m_bInLayoutStatus = true; 566 if (!m_pXFADocLayout->IncrementLayout() && 567 m_pXFADocLayout->StartLayout() < 100) { 568 m_pXFADocLayout->DoLayout(); 569 UnlockUpdate(); 570 m_bInLayoutStatus = false; 571 m_pDoc->GetDocEnvironment()->PageViewEvent(nullptr, 572 XFA_PAGEVIEWEVENT_StopLayout); 573 return true; 574 } 575 m_bInLayoutStatus = false; 576 m_pDoc->GetDocEnvironment()->PageViewEvent(nullptr, 577 XFA_PAGEVIEWEVENT_StopLayout); 578 UnlockUpdate(); 579 return false; 580 } 581 582 void CXFA_FFDocView::RunSubformIndexChange() { 583 for (CXFA_Node* pSubformNode : m_IndexChangedSubforms) { 584 CXFA_WidgetAcc* pWidgetAcc = 585 static_cast<CXFA_WidgetAcc*>(pSubformNode->GetWidgetData()); 586 if (!pWidgetAcc) 587 continue; 588 589 CXFA_EventParam eParam; 590 eParam.m_eType = XFA_EVENT_IndexChange; 591 eParam.m_pTarget = pWidgetAcc; 592 pWidgetAcc->ProcessEvent(XFA_ATTRIBUTEENUM_IndexChange, &eParam); 593 } 594 m_IndexChangedSubforms.clear(); 595 } 596 597 void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) { 598 m_NewAddedNodes.push_back(pNode); 599 InitLayout(pNode); 600 } 601 602 void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) { 603 ASSERT(pNode->GetElementType() == XFA_Element::Subform); 604 m_IndexChangedSubforms.push_back(pNode); 605 } 606 607 void CXFA_FFDocView::RunDocClose() { 608 CXFA_Node* pRootItem = 609 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 610 if (!pRootItem) { 611 return; 612 } 613 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocClose, false, true, 614 nullptr); 615 } 616 void CXFA_FFDocView::DestroyDocView() { 617 ClearInvalidateList(); 618 m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None; 619 m_iLock = 0; 620 m_ValidateAccs.clear(); 621 m_BindItems.clear(); 622 m_CalculateAccs.clear(); 623 } 624 bool CXFA_FFDocView::IsStaticNotify() { 625 return m_pDoc->GetDocType() == XFA_DOCTYPE_Static; 626 } 627 628 void CXFA_FFDocView::AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) { 629 CXFA_WidgetAcc* pCurrentAcc = 630 !m_CalculateAccs.empty() ? m_CalculateAccs.back() : nullptr; 631 if (pCurrentAcc != pWidgetAcc) 632 m_CalculateAccs.push_back(pWidgetAcc); 633 } 634 635 void CXFA_FFDocView::AddCalculateNodeNotify(CXFA_Node* pNodeChange) { 636 auto pGlobalData = 637 static_cast<CXFA_CalcData*>(pNodeChange->GetUserData(XFA_CalcData)); 638 if (!pGlobalData) 639 return; 640 641 for (const auto& pResultAcc : pGlobalData->m_Globals) { 642 if (!pResultAcc->GetNode()->HasRemovedChildren()) 643 AddCalculateWidgetAcc(pResultAcc); 644 } 645 } 646 647 void CXFA_FFDocView::RunCalculateRecursive(int32_t& iIndex) { 648 while (iIndex < pdfium::CollectionSize<int32_t>(m_CalculateAccs)) { 649 CXFA_WidgetAcc* pCurAcc = m_CalculateAccs[iIndex]; 650 AddCalculateNodeNotify(pCurAcc->GetNode()); 651 int32_t iRefCount = 652 (int32_t)(uintptr_t)pCurAcc->GetNode()->GetUserData(XFA_CalcRefCount); 653 iRefCount++; 654 pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, 655 (void*)(uintptr_t)iRefCount); 656 if (iRefCount > 11) { 657 break; 658 } 659 if ((pCurAcc->ProcessCalculate()) == XFA_EVENTERROR_Success) { 660 AddValidateWidget(pCurAcc); 661 } 662 iIndex++; 663 RunCalculateRecursive(iIndex); 664 } 665 } 666 667 int32_t CXFA_FFDocView::RunCalculateWidgets() { 668 if (!m_pDoc->GetDocEnvironment()->IsCalculationsEnabled(m_pDoc)) { 669 return XFA_EVENTERROR_Disabled; 670 } 671 int32_t iCounts = pdfium::CollectionSize<int32_t>(m_CalculateAccs); 672 int32_t iIndex = 0; 673 if (iCounts > 0) 674 RunCalculateRecursive(iIndex); 675 676 for (CXFA_WidgetAcc* pCurAcc : m_CalculateAccs) 677 pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, (void*)(uintptr_t)0); 678 679 m_CalculateAccs.clear(); 680 return XFA_EVENTERROR_Success; 681 } 682 683 void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget) { 684 if (!pdfium::ContainsValue(m_ValidateAccs, pWidget)) 685 m_ValidateAccs.push_back(pWidget); 686 } 687 688 bool CXFA_FFDocView::InitCalculate(CXFA_Node* pNode) { 689 ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate, false, true, 690 nullptr); 691 return true; 692 } 693 694 bool CXFA_FFDocView::InitValidate(CXFA_Node* pNode) { 695 if (!m_pDoc->GetDocEnvironment()->IsValidationsEnabled(m_pDoc)) 696 return false; 697 698 ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Validate, false, true, nullptr); 699 m_ValidateAccs.clear(); 700 return true; 701 } 702 703 bool CXFA_FFDocView::RunValidate() { 704 if (!m_pDoc->GetDocEnvironment()->IsValidationsEnabled(m_pDoc)) 705 return false; 706 707 for (CXFA_WidgetAcc* pAcc : m_ValidateAccs) { 708 if (!pAcc->GetNode()->HasRemovedChildren()) 709 pAcc->ProcessValidate(); 710 } 711 m_ValidateAccs.clear(); 712 return true; 713 } 714 bool CXFA_FFDocView::RunEventLayoutReady() { 715 CXFA_Node* pRootItem = 716 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 717 if (!pRootItem) { 718 return false; 719 } 720 ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, false, true, 721 nullptr); 722 RunLayout(); 723 return true; 724 } 725 void CXFA_FFDocView::RunBindItems() { 726 for (const auto& item : m_BindItems) { 727 if (item->HasRemovedChildren()) 728 continue; 729 730 CXFA_Node* pWidgetNode = item->GetNodeItem(XFA_NODEITEM_Parent); 731 CXFA_WidgetAcc* pAcc = 732 static_cast<CXFA_WidgetAcc*>(pWidgetNode->GetWidgetData()); 733 if (!pAcc) 734 continue; 735 736 CXFA_BindItems binditems(item); 737 CXFA_ScriptContext* pScriptContext = 738 pWidgetNode->GetDocument()->GetScriptContext(); 739 CFX_WideStringC wsRef; 740 binditems.GetRef(wsRef); 741 uint32_t dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | 742 XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | 743 XFA_RESOLVENODE_ALL; 744 XFA_RESOLVENODE_RS rs; 745 pScriptContext->ResolveObjects(pWidgetNode, wsRef, rs, dwStyle); 746 int32_t iCount = rs.nodes.GetSize(); 747 pAcc->DeleteItem(-1); 748 if (rs.dwFlags != XFA_RESOVENODE_RSTYPE_Nodes || iCount < 1) 749 continue; 750 751 CFX_WideStringC wsValueRef, wsLabelRef; 752 binditems.GetValueRef(wsValueRef); 753 binditems.GetLabelRef(wsLabelRef); 754 const bool bUseValue = wsLabelRef.IsEmpty() || wsLabelRef == wsValueRef; 755 const bool bLabelUseContent = wsLabelRef.IsEmpty() || wsLabelRef == L"$"; 756 const bool bValueUseContent = wsValueRef.IsEmpty() || wsValueRef == L"$"; 757 CFX_WideString wsValue; 758 CFX_WideString wsLabel; 759 uint32_t uValueHash = FX_HashCode_GetW(wsValueRef, false); 760 for (int32_t j = 0; j < iCount; j++) { 761 CXFA_Object* refObj = rs.nodes[j]; 762 if (!refObj->IsNode()) { 763 continue; 764 } 765 CXFA_Node* refNode = refObj->AsNode(); 766 if (bValueUseContent) { 767 wsValue = refNode->GetContent(); 768 } else { 769 CXFA_Node* nodeValue = refNode->GetFirstChildByName(uValueHash); 770 wsValue = nodeValue ? nodeValue->GetContent() : refNode->GetContent(); 771 } 772 if (!bUseValue) { 773 if (bLabelUseContent) { 774 wsLabel = refNode->GetContent(); 775 } else { 776 CXFA_Node* nodeLabel = refNode->GetFirstChildByName(wsLabelRef); 777 if (nodeLabel) 778 wsLabel = nodeLabel->GetContent(); 779 } 780 } else { 781 wsLabel = wsValue; 782 } 783 pAcc->InsertItem(wsLabel, wsValue); 784 } 785 } 786 m_BindItems.clear(); 787 } 788 void CXFA_FFDocView::SetChangeMark() { 789 if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) { 790 return; 791 } 792 m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc); 793 } 794 CXFA_Node* CXFA_FFDocView::GetRootSubform() { 795 CXFA_Node* pFormPacketNode = 796 ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)); 797 if (!pFormPacketNode) { 798 return nullptr; 799 } 800 return pFormPacketNode->GetFirstChildByClass(XFA_Element::Subform); 801 } 802 803 CXFA_WidgetAccIterator::CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView, 804 CXFA_Node* pTravelRoot) 805 : m_ContentIterator(pTravelRoot), 806 m_pDocView(pDocView), 807 m_pCurWidgetAcc(nullptr) {} 808 809 CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator() {} 810 void CXFA_WidgetAccIterator::Reset() { 811 m_pCurWidgetAcc = nullptr; 812 m_ContentIterator.Reset(); 813 } 814 815 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst() { 816 return nullptr; 817 } 818 819 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast() { 820 return nullptr; 821 } 822 823 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToNext() { 824 CXFA_Node* pItem = m_pCurWidgetAcc ? m_ContentIterator.MoveToNext() 825 : m_ContentIterator.GetCurrent(); 826 while (pItem) { 827 m_pCurWidgetAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData()); 828 if (m_pCurWidgetAcc) 829 return m_pCurWidgetAcc; 830 pItem = m_ContentIterator.MoveToNext(); 831 } 832 return nullptr; 833 } 834 835 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious() { 836 return nullptr; 837 } 838 839 CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc() { 840 return nullptr; 841 } 842 843 bool CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) { 844 return false; 845 } 846 847 void CXFA_WidgetAccIterator::SkipTree() { 848 m_ContentIterator.SkipChildrenAndMoveToNext(); 849 m_pCurWidgetAcc = nullptr; 850 } 851