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 #include "xfa_ffnotify.h"
     33 
     34 static void XFA_FFDeleteWidgetAcc(void* pData) {
     35   delete static_cast<CXFA_WidgetAcc*>(pData);
     36 }
     37 static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {
     38     XFA_FFDeleteWidgetAcc, NULL};
     39 CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
     40 CXFA_FFNotify::~CXFA_FFNotify() {}
     41 void CXFA_FFNotify::OnPageEvent(IXFA_LayoutPage* pSender,
     42                                 XFA_PAGEEVENT eEvent,
     43                                 void* pParam) {
     44   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
     45   if (!pDocView) {
     46     return;
     47   }
     48   pDocView->OnPageEvent(pSender, eEvent, (int32_t)(uintptr_t)pParam);
     49 }
     50 void CXFA_FFNotify::OnNodeEvent(CXFA_Node* pSender,
     51                                 XFA_NODEEVENT eEvent,
     52                                 void* pParam,
     53                                 void* pParam2,
     54                                 void* pParam3,
     55                                 void* pParam4) {
     56   switch (eEvent) {
     57     case XFA_NODEEVENT_Ready:
     58       OnNodeReady(pSender);
     59       break;
     60     case XFA_NODEEVENT_ValueChanging:
     61       OnValueChanging(pSender, pParam, pParam2);
     62       break;
     63     case XFA_NODEEVENT_ValueChanged:
     64       OnValueChanged(pSender, pParam, pParam2, pParam3, pParam4);
     65       break;
     66     case XFA_NODEEVENT_ChildAdded:
     67       OnChildAdded(pSender, pParam, pParam2);
     68       break;
     69     case XFA_NODEEVENT_ChildRemoved:
     70       OnChildRemoved(pSender, pParam, pParam2);
     71       break;
     72   }
     73 }
     74 void CXFA_FFNotify::OnWidgetDataEvent(CXFA_WidgetData* pSender,
     75                                       FX_DWORD dwEvent,
     76                                       void* pParam,
     77                                       void* pAdditional,
     78                                       void* pAdditional2) {
     79   CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender);
     80   switch (dwEvent) {
     81     case XFA_WIDGETEVENT_ListItemAdded: {
     82       if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
     83         return;
     84       }
     85       FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
     86       CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
     87       if (!pWidget) {
     88         if (bStaticNotify) {
     89           pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
     90               pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam,
     91               pAdditional);
     92         }
     93         return;
     94       }
     95       while (pWidget) {
     96         if (pWidget->IsLoaded()) {
     97           if (pWidgetAcc->IsListBox()) {
     98             static_cast<CXFA_FFListBox*>(pWidget)
     99                 ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam,
    100                              (int32_t)(uintptr_t)pAdditional2);
    101           } else {
    102             static_cast<CXFA_FFComboBox*>(pWidget)
    103                 ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam,
    104                              (int32_t)(uintptr_t)pAdditional2);
    105           }
    106         }
    107         if (bStaticNotify) {
    108           pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
    109               pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam,
    110               pAdditional);
    111         }
    112         pWidget = pWidgetAcc->GetNextWidget(pWidget);
    113       }
    114     } break;
    115     case XFA_WIDGETEVENT_ListItemRemoved: {
    116       if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
    117         return;
    118       }
    119       FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
    120       CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
    121       if (!pWidget) {
    122         if (bStaticNotify) {
    123           pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
    124               pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam,
    125               pAdditional);
    126         }
    127         return;
    128       }
    129       while (pWidget) {
    130         if (pWidget->IsLoaded()) {
    131           if (pWidgetAcc->IsListBox()) {
    132             static_cast<CXFA_FFListBox*>(pWidget)
    133                 ->DeleteItem((int32_t)(uintptr_t)pParam);
    134           } else {
    135             static_cast<CXFA_FFComboBox*>(pWidget)
    136                 ->DeleteItem((int32_t)(uintptr_t)pParam);
    137           }
    138         }
    139         if (bStaticNotify) {
    140           pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
    141               pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam,
    142               pAdditional);
    143         }
    144         pWidget = pWidgetAcc->GetNextWidget(pWidget);
    145       }
    146     } break;
    147   }
    148 }
    149 CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode) {
    150   IXFA_DocLayout* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
    151   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
    152   XFA_ELEMENT eType = pNode->GetClassID();
    153   if (eType == XFA_ELEMENT_PageArea) {
    154     return new CXFA_FFPageView(pDocView, pNode);
    155   }
    156   if (eType == XFA_ELEMENT_ContentArea) {
    157     return new CXFA_ContainerLayoutItem(pNode);
    158   }
    159   CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
    160   if (!pAcc) {
    161     return new CXFA_ContentLayoutItem(pNode);
    162   }
    163   CXFA_FFPageView* pPageView = NULL;
    164   CXFA_FFWidget* pWidget = NULL;
    165   switch (pAcc->GetUIType()) {
    166     case XFA_ELEMENT_Barcode:
    167       pWidget = new CXFA_FFBarcode(pPageView, pAcc);
    168       break;
    169     case XFA_ELEMENT_Button:
    170       pWidget = new CXFA_FFPushButton(pPageView, pAcc);
    171       break;
    172     case XFA_ELEMENT_CheckButton:
    173       pWidget = new CXFA_FFCheckButton(pPageView, pAcc);
    174       break;
    175     case XFA_ELEMENT_ChoiceList: {
    176       if (pAcc->IsListBox()) {
    177         pWidget = new CXFA_FFListBox(pPageView, pAcc);
    178       } else {
    179         pWidget = new CXFA_FFComboBox(pPageView, pAcc);
    180       }
    181     } break;
    182     case XFA_ELEMENT_DateTimeEdit:
    183       pWidget = new CXFA_FFDateTimeEdit(pPageView, pAcc);
    184       break;
    185     case XFA_ELEMENT_ImageEdit:
    186       pWidget = new CXFA_FFImageEdit(pPageView, pAcc);
    187       break;
    188     case XFA_ELEMENT_NumericEdit:
    189       pWidget = new CXFA_FFNumericEdit(pPageView, pAcc);
    190       break;
    191     case XFA_ELEMENT_PasswordEdit:
    192       pWidget = new CXFA_FFPasswordEdit(pPageView, pAcc);
    193       break;
    194     case XFA_ELEMENT_Signature:
    195       pWidget = new CXFA_FFSignature(pPageView, pAcc);
    196       break;
    197     case XFA_ELEMENT_TextEdit:
    198       pWidget = new CXFA_FFTextEdit(pPageView, pAcc);
    199       break;
    200     case XFA_ELEMENT_Arc:
    201       pWidget = new CXFA_FFArc(pPageView, pAcc);
    202       break;
    203     case XFA_ELEMENT_Line:
    204       pWidget = new CXFA_FFLine(pPageView, pAcc);
    205       break;
    206     case XFA_ELEMENT_Rectangle:
    207       pWidget = new CXFA_FFRectangle(pPageView, pAcc);
    208       break;
    209     case XFA_ELEMENT_Text:
    210       pWidget = new CXFA_FFText(pPageView, pAcc);
    211       break;
    212     case XFA_ELEMENT_Image:
    213       pWidget = new CXFA_FFImage(pPageView, pAcc);
    214       break;
    215     case XFA_ELEMENT_Draw:
    216       pWidget = new CXFA_FFDraw(pPageView, pAcc);
    217       break;
    218     case XFA_ELEMENT_Subform:
    219       pWidget = new CXFA_FFSubForm(pPageView, pAcc);
    220       break;
    221     case XFA_ELEMENT_ExclGroup:
    222       pWidget = new CXFA_FFExclGroup(pPageView, pAcc);
    223       break;
    224     case XFA_ELEMENT_DefaultUi:
    225     default:
    226       pWidget = NULL;
    227       break;
    228   }
    229   if (!pWidget) {
    230     return NULL;
    231   }
    232   pWidget->SetDocView(pDocView);
    233   return pWidget;
    234 }
    235 void CXFA_FFNotify::OnLayoutEvent(IXFA_DocLayout* pLayout,
    236                                   CXFA_LayoutItem* pSender,
    237                                   XFA_LAYOUTEVENT eEvent,
    238                                   void* pParam,
    239                                   void* pParam2) {
    240   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
    241   if (!pDocView || !XFA_GetWidgetFromLayoutItem(pSender)) {
    242     return;
    243   }
    244   switch (eEvent) {
    245     case XFA_LAYOUTEVENT_ItemAdded:
    246       OnLayoutItemAdd(pDocView, pLayout, pSender, pParam, pParam2);
    247       break;
    248     case XFA_LAYOUTEVENT_ItemRemoving:
    249       OnLayoutItemRemoving(pDocView, pLayout, pSender, pParam, pParam2);
    250       break;
    251     case XFA_LAYOUTEVENT_RectChanged:
    252       OnLayoutItemRectChanged(pDocView, pLayout, pSender, pParam, pParam2);
    253       break;
    254     case XFA_LAYOUTEVENT_StatusChanged:
    255       OnLayoutItemStatustChanged(pDocView, pLayout, pSender, pParam, pParam2);
    256       break;
    257   }
    258 }
    259 void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
    260                                          FX_FLOAT& fCalcWidth,
    261                                          FX_FLOAT& fCalcHeight) {
    262   CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
    263   if (!pAcc) {
    264     return;
    265   }
    266   pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight);
    267 }
    268 FX_BOOL CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem,
    269                                     int32_t iBlockIndex,
    270                                     FX_FLOAT& fCalcHeightPos) {
    271   CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
    272   if (!pAcc) {
    273     return FALSE;
    274   }
    275   return (XFA_LAYOUTRESULT)pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos);
    276 }
    277 FX_BOOL CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) {
    278   FX_BOOL bRet = FALSE;
    279   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    280   if (!pDocView) {
    281     return bRet;
    282   }
    283   CXFA_WidgetAcc* pWidgetAcc =
    284       static_cast<CXFA_WidgetAcc*>(pFormItem->GetWidgetData());
    285   if (!pWidgetAcc) {
    286     return bRet;
    287   }
    288   CXFA_EventParam EventParam;
    289   EventParam.m_eType = XFA_EVENT_Unknown;
    290   FXJSE_HVALUE pRetValue = NULL;
    291   int32_t iRet =
    292       pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue);
    293   if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
    294     bRet = FXJSE_Value_ToBoolean(pRetValue);
    295     FXJSE_Value_Release(pRetValue);
    296   }
    297   return bRet;
    298 }
    299 int32_t CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
    300                                             XFA_EVENTTYPE eEventType,
    301                                             FX_BOOL bIsFormReady,
    302                                             FX_BOOL bRecursive,
    303                                             CXFA_WidgetAcc* pExclude) {
    304   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    305   if (!pDocView) {
    306     return XFA_EVENTERROR_NotExist;
    307   }
    308   return pDocView->ExecEventActivityByDeepFirst(
    309       pFormNode, eEventType, bIsFormReady, bRecursive,
    310       pExclude ? pExclude->GetNode() : NULL);
    311 }
    312 void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) {
    313   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    314   if (!pDocView) {
    315     return;
    316   }
    317   CXFA_WidgetAcc* pWidgetAcc =
    318       static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
    319   if (!pWidgetAcc) {
    320     return;
    321   }
    322   pDocView->AddCalculateWidgetAcc(pWidgetAcc);
    323   pDocView->AddValidateWidget(pWidgetAcc);
    324 }
    325 IXFA_Doc* CXFA_FFNotify::GetHDOC() {
    326   return m_pDoc;
    327 }
    328 IXFA_DocProvider* CXFA_FFNotify::GetDocProvider() {
    329   return m_pDoc->GetDocProvider();
    330 }
    331 IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() {
    332   return m_pDoc->GetApp()->GetAppProvider();
    333 }
    334 IXFA_WidgetHandler* CXFA_FFNotify::GetWidgetHandler() {
    335   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    336   return pDocView ? pDocView->GetWidgetHandler() : NULL;
    337 }
    338 IXFA_Widget* CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem) {
    339   return XFA_GetWidgetFromLayoutItem(pLayoutItem);
    340 }
    341 void CXFA_FFNotify::OpenDropDownList(IXFA_Widget* hWidget) {
    342   CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(hWidget);
    343   if (pWidget->GetDataAcc()->GetUIType() != XFA_ELEMENT_ChoiceList) {
    344     return;
    345   }
    346   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    347   pDocView->LockUpdate();
    348   static_cast<CXFA_FFComboBox*>(pWidget)->OpenDropDownList();
    349   pDocView->UnlockUpdate();
    350   pDocView->UpdateDocView();
    351 }
    352 CFX_WideString CXFA_FFNotify::GetCurrentDateTime() {
    353   CFX_Unitime dataTime;
    354   dataTime.Now();
    355   CFX_WideString wsDateTime;
    356   wsDateTime.Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(),
    357                     dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(),
    358                     dataTime.GetMinute(), dataTime.GetSecond());
    359   return wsDateTime;
    360 }
    361 void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData) {
    362   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    363   if (!pDocView) {
    364     return;
    365   }
    366   pDocView->ResetWidgetData(static_cast<CXFA_WidgetAcc*>(pWidgetData));
    367 }
    368 int32_t CXFA_FFNotify::GetLayoutStatus() {
    369   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    370   return pDocView ? pDocView->GetLayoutStatus() : 0;
    371 }
    372 void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) {
    373   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    374   if (!pDocView) {
    375     return;
    376   }
    377   pDocView->AddNewFormNode(pNode);
    378 }
    379 void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
    380   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    381   if (!pDocView) {
    382     return;
    383   }
    384   pDocView->AddIndexChangedSubform(pSubformNode);
    385 }
    386 CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() {
    387   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    388   if (!pDocView) {
    389     return NULL;
    390   }
    391   CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();
    392   return pAcc ? pAcc->GetNode() : NULL;
    393 }
    394 void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
    395   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    396   if (!pDocView) {
    397     return;
    398   }
    399   CXFA_WidgetAcc* pAcc =
    400       pNode ? static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()) : nullptr;
    401   pDocView->SetFocusWidgetAcc(pAcc);
    402 }
    403 void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
    404   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    405   if (!pDocView) {
    406     return;
    407   }
    408   XFA_ELEMENT iType = pNode->GetClassID();
    409   if (XFA_IsCreateWidget(iType)) {
    410     CXFA_WidgetAcc* pAcc =
    411         new CXFA_WidgetAcc(pDocView, static_cast<CXFA_Node*>(pNode));
    412     pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc);
    413     return;
    414   }
    415   switch (iType) {
    416     case XFA_ELEMENT_BindItems:
    417       pDocView->m_bindItems.Add(pNode);
    418       break;
    419     case XFA_ELEMENT_Validate: {
    420       pNode->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
    421     } break;
    422     default:
    423       break;
    424   }
    425 }
    426 void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender,
    427                                     void* pParam,
    428                                     void* pParam2) {
    429   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    430   if (!pDocView) {
    431     return;
    432   }
    433   if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {
    434     return;
    435   }
    436   FX_DWORD dwPacket = pSender->GetPacketID();
    437   if (dwPacket & XFA_XDPPACKET_Datasets) {
    438   } else if (pSender->IsFormContainer()) {
    439     XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam;
    440     if (eAttr == XFA_ATTRIBUTE_Presence) {
    441       CXFA_WidgetAcc* pWidgetAcc =
    442           static_cast<CXFA_WidgetAcc*>(pSender->GetWidgetData());
    443       if (!pWidgetAcc) {
    444         return;
    445       }
    446       CXFA_FFWidget* pWidget = NULL;
    447       while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {
    448         if (pWidget->IsLoaded()) {
    449           pWidget->AddInvalidateRect();
    450         }
    451       }
    452     }
    453   }
    454 }
    455 void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
    456                                    void* pParam,
    457                                    void* pParam2,
    458                                    void* pParam3,
    459                                    void* pParam4) {
    460   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    461   if (!pDocView) {
    462     return;
    463   }
    464   FX_DWORD dwPacket = pSender->GetPacketID();
    465   XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam;
    466   if (dwPacket & XFA_XDPPACKET_Form) {
    467     CXFA_Node* pParentNode = static_cast<CXFA_Node*>(pParam3);
    468     CXFA_Node* pWidgetNode = static_cast<CXFA_Node*>(pParam4);
    469     XFA_ELEMENT ePType = pParentNode->GetClassID();
    470     FX_BOOL bIsContainerNode = pParentNode->IsContainerNode();
    471     CXFA_WidgetAcc* pWidgetAcc =
    472         static_cast<CXFA_WidgetAcc*>(pWidgetNode->GetWidgetData());
    473     if (!pWidgetAcc) {
    474       return;
    475     }
    476     FX_BOOL bUpdateProperty = FALSE;
    477     pDocView->SetChangeMark();
    478     switch (ePType) {
    479       case XFA_ELEMENT_Caption: {
    480         CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();
    481         if (!pCapOut) {
    482           return;
    483         }
    484         pCapOut->Unload();
    485       } break;
    486       case XFA_ELEMENT_Ui:
    487       case XFA_ELEMENT_Para:
    488         bUpdateProperty = TRUE;
    489         break;
    490       case XFA_ELEMENT_Font:
    491       case XFA_ELEMENT_Margin:
    492       case XFA_ELEMENT_Value:
    493       case XFA_ELEMENT_Items:
    494         break;
    495       default:
    496         break;
    497     }
    498     if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access) {
    499       bUpdateProperty = TRUE;
    500       FX_BOOL bNotify = pDocView->IsStaticNotify();
    501       if (bNotify) {
    502         pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_AccessChanged, NULL, pParam2,
    503                                 NULL);
    504       }
    505     }
    506     if (eAttr == XFA_ATTRIBUTE_Value) {
    507       pDocView->AddCalculateNodeNotify(pSender);
    508       if (ePType == XFA_ELEMENT_Value || bIsContainerNode) {
    509         FX_BOOL bNotify = pDocView->IsStaticNotify();
    510         if (bIsContainerNode) {
    511           pWidgetAcc->UpdateUIDisplay();
    512           pDocView->AddCalculateWidgetAcc(pWidgetAcc);
    513           pDocView->AddValidateWidget(pWidgetAcc);
    514         } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent)
    515                        ->GetClassID() == XFA_ELEMENT_ExclGroup) {
    516           pWidgetAcc->UpdateUIDisplay();
    517         }
    518         if (bNotify) {
    519           pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL,
    520                                   NULL, NULL);
    521         }
    522         return;
    523       }
    524     }
    525     CXFA_FFWidget* pWidget = NULL;
    526     while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {
    527       if (!pWidget->IsLoaded()) {
    528         continue;
    529       }
    530       if (bUpdateProperty) {
    531         pWidget->UpdateWidgetProperty();
    532       }
    533       pWidget->PerformLayout();
    534       pWidget->AddInvalidateRect();
    535     }
    536   } else {
    537     if (eAttr == XFA_ATTRIBUTE_Value) {
    538       pDocView->AddCalculateNodeNotify(pSender);
    539     }
    540   }
    541 }
    542 void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender,
    543                                  void* pParam,
    544                                  void* pParam2) {
    545   if (!pSender->IsFormContainer()) {
    546     return;
    547   }
    548   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
    549   if (!pDocView) {
    550     return;
    551   }
    552   FX_BOOL bLayoutReady =
    553       !(pDocView->m_bInLayoutStatus) &&
    554       (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);
    555   if (bLayoutReady) {
    556     m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
    557   }
    558 }
    559 void CXFA_FFNotify::OnChildRemoved(CXFA_Node* pSender,
    560                                    void* pParam,
    561                                    void* pParam2) {
    562   if (CXFA_FFDocView* pDocView = m_pDoc->GetDocView()) {
    563     FX_BOOL bLayoutReady =
    564         !(pDocView->m_bInLayoutStatus) &&
    565         (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);
    566     if (bLayoutReady) {
    567       m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
    568     }
    569   }
    570 }
    571 void CXFA_FFNotify::OnLayoutItemAdd(CXFA_FFDocView* pDocView,
    572                                     IXFA_DocLayout* pLayout,
    573                                     CXFA_LayoutItem* pSender,
    574                                     void* pParam,
    575                                     void* pParam2) {
    576   CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
    577   int32_t iPageIdx = (int32_t)(uintptr_t)pParam;
    578   IXFA_PageView* pNewPageView = pDocView->GetPageView(iPageIdx);
    579   FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam2;
    580   FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable |
    581                       XFA_WIDGETSTATUS_Printable;
    582   pWidget->ModifyStatus(dwStatus, dwFilter);
    583   if (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End) {
    584     IXFA_PageView* pPrePageView = pWidget->GetPageView();
    585     if (pPrePageView != pNewPageView ||
    586         (dwStatus & (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) ==
    587             (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) {
    588       pWidget->SetPageView(pNewPageView);
    589       m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(),
    590                                             XFA_WIDGETEVENT_PostAdded,
    591                                             pNewPageView, pPrePageView);
    592     }
    593     if ((dwStatus & XFA_WIDGETSTATUS_Visible) == 0) {
    594       return;
    595     }
    596     if (pWidget->IsLoaded()) {
    597       CFX_RectF rtOld;
    598       pWidget->GetWidgetRect(rtOld);
    599       CFX_RectF rtNew = pWidget->ReCacheWidgetRect();
    600       if (rtOld != rtNew) {
    601         pWidget->PerformLayout();
    602       }
    603     } else {
    604       pWidget->LoadWidget();
    605     }
    606     pWidget->AddInvalidateRect(NULL);
    607   } else {
    608     pWidget->SetPageView(pNewPageView);
    609   }
    610 }
    611 void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_FFDocView* pDocView,
    612                                          IXFA_DocLayout* pLayout,
    613                                          CXFA_LayoutItem* pSender,
    614                                          void* pParam,
    615                                          void* pParam2) {
    616   CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
    617   pDocView->DeleteLayoutItem(pWidget);
    618   if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {
    619     return;
    620   }
    621   m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(),
    622                                         XFA_WIDGETEVENT_PreRemoved, NULL, NULL);
    623   pWidget->AddInvalidateRect(NULL);
    624 }
    625 void CXFA_FFNotify::OnLayoutItemRectChanged(CXFA_FFDocView* pDocView,
    626                                             IXFA_DocLayout* pLayout,
    627                                             CXFA_LayoutItem* pSender,
    628                                             void* pParam,
    629                                             void* pParam2) {
    630 }
    631 void CXFA_FFNotify::OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView,
    632                                                IXFA_DocLayout* pLayout,
    633                                                CXFA_LayoutItem* pSender,
    634                                                void* pParam,
    635                                                void* pParam2) {
    636   CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
    637   if (!pWidget) {
    638     return;
    639   }
    640   FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam;
    641   if (dwStatus == 0) {
    642     CXFA_LayoutItem* pPreItem = pSender->GetPrev();
    643     if (pPreItem) {
    644       CXFA_FFWidget* pPreWidget = static_cast<CXFA_FFWidget*>(pPreItem);
    645       if (pPreWidget) {
    646         dwStatus = pPreWidget->GetStatus();
    647       }
    648     }
    649   }
    650   FX_DWORD dwOldStatus = pWidget->GetStatus();
    651   FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable |
    652                       XFA_WIDGETSTATUS_Printable;
    653   if ((dwOldStatus & dwFilter) == dwStatus) {
    654     return;
    655   }
    656   pWidget->ModifyStatus(dwStatus, dwFilter);
    657 }
    658