Home | History | Annotate | Download | only in app
      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"
     32 extern 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 };
     48 CXFA_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 }
     61 CXFA_FFDocView::~CXFA_FFDocView() {
     62   DestroyDocView();
     63   if (m_pWidgetHandler) {
     64     delete m_pWidgetHandler;
     65   }
     66   m_pWidgetHandler = NULL;
     67 }
     68 void CXFA_FFDocView::InitLayout(CXFA_Node* pNode) {
     69   RunBindItems();
     70   ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize);
     71   ExecEventActivityByDeepFirst(pNode, XFA_EVENT_IndexChange);
     72 }
     73 int32_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 }
     94 int32_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 }
    103 void 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 }
    137 int32_t CXFA_FFDocView::GetLayoutStatus() {
    138   return m_iStatus;
    139 }
    140 void 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 }
    166 void 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 }
    192 int32_t CXFA_FFDocView::CountPageViews() {
    193   if (!m_pXFADocLayout) {
    194     return 0;
    195   }
    196   return m_pXFADocLayout->CountPages();
    197 }
    198 IXFA_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 }
    204 IXFA_Widget* CXFA_FFDocView::GetWidgetByName(const CFX_WideStringC& wsName) {
    205   return GetWidgetByName(wsName, NULL);
    206 }
    207 CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(
    208     const CFX_WideStringC& wsName) {
    209   return GetWidgetAccByName(wsName, NULL);
    210 }
    211 IXFA_DocLayout* CXFA_FFDocView::GetXFALayout() const {
    212   return m_pDoc->GetXFADoc()->GetDocLayout();
    213 }
    214 FX_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 }
    233 void 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 }
    260 int32_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 }
    315 IXFA_WidgetHandler* CXFA_FFDocView::GetWidgetHandler() {
    316   if (!m_pWidgetHandler) {
    317     m_pWidgetHandler = new CXFA_FFWidgetHandler(this);
    318   }
    319   return m_pWidgetHandler;
    320 }
    321 IXFA_WidgetIterator* CXFA_FFDocView::CreateWidgetIterator() {
    322   CXFA_Node* pFormRoot = GetRootSubform();
    323   if (!pFormRoot) {
    324     return NULL;
    325   }
    326   return new CXFA_FFDocWidgetIterator(this, pFormRoot);
    327 }
    328 IXFA_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 }
    336 IXFA_Widget* CXFA_FFDocView::GetFocusWidget() {
    337   return m_pFocusWidget;
    338 }
    339 void 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 }
    348 FX_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 }
    391 CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc() {
    392   return m_pFocusAcc;
    393 }
    394 void 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 }
    404 void 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 }
    411 static 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 }
    448 int32_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 }
    496 CXFA_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 }
    504 CXFA_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 }
    535 void 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 }
    553 void CXFA_FFDocView::LockUpdate() {
    554   m_iLock++;
    555 }
    556 void CXFA_FFDocView::UnlockUpdate() {
    557   m_iLock--;
    558 }
    559 FX_BOOL CXFA_FFDocView::IsUpdateLocked() {
    560   return m_iLock;
    561 }
    562 void 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 }
    572 void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget,
    573                                        const CFX_RectF& rtInvalidate) {
    574   AddInvalidateRect(pWidget->GetPageView(), rtInvalidate);
    575 }
    576 void 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 }
    588 void 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 }
    599 FX_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 }
    613 void 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 }
    628 void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) {
    629   m_NewAddedNodes.Add(pNode);
    630   this->InitLayout(pNode);
    631 }
    632 void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
    633   FXSYS_assert(pNode->GetClassID() == XFA_ELEMENT_Subform);
    634   m_IndexChangedSubforms.Add(pNode);
    635 }
    636 void 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 }
    644 void 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 }
    652 FX_BOOL CXFA_FFDocView::IsStaticNotify() {
    653   return m_pDoc->GetDocType() == XFA_DOCTYPE_Static;
    654 }
    655 void 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 }
    664 void 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 }
    682 void 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 }
    701 int32_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 }
    717 void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget) {
    718   if (m_ValidateAccs.Find(pWidget) < 0) {
    719     m_ValidateAccs.Add(pWidget);
    720   }
    721 }
    722 FX_BOOL CXFA_FFDocView::InitCalculate(CXFA_Node* pNode) {
    723   ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate);
    724   return TRUE;
    725 }
    726 FX_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 }
    734 FX_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 }
    749 FX_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 }
    759 void 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 }
    830 void CXFA_FFDocView::SetChangeMark() {
    831   if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) {
    832     return;
    833   }
    834   m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
    835 }
    836 CXFA_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 }
    844 CXFA_FFDocWidgetIterator::CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView,
    845                                                    CXFA_Node* pTravelRoot)
    846     : m_ContentIterator(pTravelRoot) {
    847   m_pDocView = pDocView;
    848   m_pCurWidget = NULL;
    849 }
    850 CXFA_FFDocWidgetIterator::~CXFA_FFDocWidgetIterator() {}
    851 void CXFA_FFDocWidgetIterator::Reset() {
    852   m_ContentIterator.Reset();
    853   m_pCurWidget = NULL;
    854 }
    855 IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToFirst() {
    856   return NULL;
    857 }
    858 IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToLast() {
    859   return NULL;
    860 }
    861 IXFA_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 }
    878 IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToPrevious() {
    879   return NULL;
    880 }
    881 IXFA_Widget* CXFA_FFDocWidgetIterator::GetCurrentWidget() {
    882   return NULL;
    883 }
    884 FX_BOOL CXFA_FFDocWidgetIterator::SetCurrentWidget(IXFA_Widget* hWidget) {
    885   return FALSE;
    886 }
    887 IXFA_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 }
    896 CXFA_WidgetAccIterator::CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView,
    897                                                CXFA_Node* pTravelRoot)
    898     : m_ContentIterator(pTravelRoot) {
    899   m_pDocView = pDocView;
    900   m_pCurWidgetAcc = NULL;
    901 }
    902 CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator() {}
    903 void CXFA_WidgetAccIterator::Reset() {
    904   m_pCurWidgetAcc = NULL;
    905   m_ContentIterator.Reset();
    906 }
    907 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst() {
    908   return NULL;
    909 }
    910 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast() {
    911   return NULL;
    912 }
    913 CXFA_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 }
    924 CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious() {
    925   return NULL;
    926 }
    927 CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc() {
    928   return NULL;
    929 }
    930 FX_BOOL CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) {
    931   return FALSE;
    932 }
    933 void CXFA_WidgetAccIterator::SkipTree() {
    934   m_ContentIterator.SkipChildrenAndMoveToNext();
    935   m_pCurWidgetAcc = NULL;
    936 }
    937