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