• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CXFA_FFDocView(CXFA_FFDoc * pDoc)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 
~CXFA_FFDocView()67 CXFA_FFDocView::~CXFA_FFDocView() {
68   DestroyDocView();
69 }
70 
InitLayout(CXFA_Node * pNode)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 }
StartLayout(int32_t iStartPage)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 }
DoLayout(IFX_Pause * pPause)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 }
StopLayout()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 }
GetLayoutStatus()146 int32_t CXFA_FFDocView::GetLayoutStatus() {
147   return m_iStatus;
148 }
ShowNullTestMsg()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 
UpdateDocView()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 
CountPageViews()198 int32_t CXFA_FFDocView::CountPageViews() {
199   if (!m_pXFADocLayout) {
200     return 0;
201   }
202   return m_pXFADocLayout->CountPages();
203 }
GetPageView(int32_t nIndex)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 
GetXFALayout() const211 CXFA_LayoutProcessor* CXFA_FFDocView::GetXFALayout() const {
212   return m_pDoc->GetXFADoc()->GetDocLayout();
213 }
ResetSingleWidgetAccData(CXFA_WidgetAcc * pWidgetAcc)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 }
ResetWidgetData(CXFA_WidgetAcc * pWidgetAcc)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 }
ProcessWidgetEvent(CXFA_EventParam * pParam,CXFA_WidgetAcc * pWidgetAcc)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 }
GetWidgetHandler()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 
CreateWidgetAccIterator(XFA_WIDGETORDER eOrder)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 }
GetFocusWidget()325 CXFA_FFWidget* CXFA_FFDocView::GetFocusWidget() {
326   return m_pFocusWidget;
327 }
KillFocus()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 }
SetFocus(CXFA_FFWidget * hWidget)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 }
GetFocusWidgetAcc()380 CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc() {
381   return m_pFocusAcc;
382 }
SetFocusWidgetAcc(CXFA_WidgetAcc * pWidgetAcc)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 }
DeleteLayoutItem(CXFA_FFWidget * pWidget)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 }
XFA_ProcessEvent(CXFA_FFDocView * pDocView,CXFA_WidgetAcc * pWidgetAcc,CXFA_EventParam * pParam)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 }
ExecEventActivityByDeepFirst(CXFA_Node * pFormNode,XFA_EVENTTYPE eEventType,bool bIsFormReady,bool bRecursive,CXFA_Node * pExclude)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 
GetWidgetByName(const CFX_WideString & wsName,CXFA_FFWidget * pRefWidget)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 
GetWidgetAccByName(const CFX_WideString & wsName,CXFA_WidgetAcc * pRefWidgetAcc)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 
OnPageEvent(CXFA_ContainerLayoutItem * pSender,uint32_t dwEvent)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 
LockUpdate()531 void CXFA_FFDocView::LockUpdate() {
532   m_iLock++;
533 }
UnlockUpdate()534 void CXFA_FFDocView::UnlockUpdate() {
535   m_iLock--;
536 }
IsUpdateLocked()537 bool CXFA_FFDocView::IsUpdateLocked() {
538   return m_iLock > 0;
539 }
ClearInvalidateList()540 void CXFA_FFDocView::ClearInvalidateList() {
541   m_mapPageInvalidate.clear();
542 }
AddInvalidateRect(CXFA_FFWidget * pWidget,const CFX_RectF & rtInvalidate)543 void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget,
544                                        const CFX_RectF& rtInvalidate) {
545   AddInvalidateRect(pWidget->GetPageView(), rtInvalidate);
546 }
547 
AddInvalidateRect(CXFA_FFPageView * pPageView,const CFX_RectF & rtInvalidate)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 
RunInvalidate()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 
RunLayout()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 
RunSubformIndexChange()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 
AddNewFormNode(CXFA_Node * pNode)597 void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) {
598   m_NewAddedNodes.push_back(pNode);
599   InitLayout(pNode);
600 }
601 
AddIndexChangedSubform(CXFA_Node * pNode)602 void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
603   ASSERT(pNode->GetElementType() == XFA_Element::Subform);
604   m_IndexChangedSubforms.push_back(pNode);
605 }
606 
RunDocClose()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 }
DestroyDocView()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 }
IsStaticNotify()624 bool CXFA_FFDocView::IsStaticNotify() {
625   return m_pDoc->GetDocType() == XFA_DOCTYPE_Static;
626 }
627 
AddCalculateWidgetAcc(CXFA_WidgetAcc * pWidgetAcc)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 
AddCalculateNodeNotify(CXFA_Node * pNodeChange)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 
RunCalculateRecursive(int32_t & iIndex)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 
RunCalculateWidgets()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 
AddValidateWidget(CXFA_WidgetAcc * pWidget)683 void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget) {
684   if (!pdfium::ContainsValue(m_ValidateAccs, pWidget))
685     m_ValidateAccs.push_back(pWidget);
686 }
687 
InitCalculate(CXFA_Node * pNode)688 bool CXFA_FFDocView::InitCalculate(CXFA_Node* pNode) {
689   ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate, false, true,
690                                nullptr);
691   return true;
692 }
693 
InitValidate(CXFA_Node * pNode)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 
RunValidate()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 }
RunEventLayoutReady()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 }
RunBindItems()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 }
SetChangeMark()788 void CXFA_FFDocView::SetChangeMark() {
789   if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) {
790     return;
791   }
792   m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc);
793 }
GetRootSubform()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 
CXFA_WidgetAccIterator(CXFA_FFDocView * pDocView,CXFA_Node * pTravelRoot)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 
~CXFA_WidgetAccIterator()809 CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator() {}
Reset()810 void CXFA_WidgetAccIterator::Reset() {
811   m_pCurWidgetAcc = nullptr;
812   m_ContentIterator.Reset();
813 }
814 
MoveToFirst()815 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst() {
816   return nullptr;
817 }
818 
MoveToLast()819 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast() {
820   return nullptr;
821 }
822 
MoveToNext()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 
MoveToPrevious()835 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious() {
836   return nullptr;
837 }
838 
GetCurrentWidgetAcc()839 CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc() {
840   return nullptr;
841 }
842 
SetCurrentWidgetAcc(CXFA_WidgetAcc * hWidget)843 bool CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) {
844   return false;
845 }
846 
SkipTree()847 void CXFA_WidgetAccIterator::SkipTree() {
848   m_ContentIterator.SkipChildrenAndMoveToNext();
849   m_pCurWidgetAcc = nullptr;
850 }
851