// Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "xfa/fxfa/app/xfa_ffnotify.h" #include "xfa/fxfa/app/xfa_ffapp.h" #include "xfa/fxfa/app/xfa_ffbarcode.h" #include "xfa/fxfa/app/xfa_ffcheckbutton.h" #include "xfa/fxfa/app/xfa_ffchoicelist.h" #include "xfa/fxfa/app/xfa_ffdoc.h" #include "xfa/fxfa/app/xfa_ffdocview.h" #include "xfa/fxfa/app/xfa_ffdraw.h" #include "xfa/fxfa/app/xfa_ffexclgroup.h" #include "xfa/fxfa/app/xfa_fffield.h" #include "xfa/fxfa/app/xfa_ffimage.h" #include "xfa/fxfa/app/xfa_ffimageedit.h" #include "xfa/fxfa/app/xfa_ffpageview.h" #include "xfa/fxfa/app/xfa_ffpath.h" #include "xfa/fxfa/app/xfa_ffpushbutton.h" #include "xfa/fxfa/app/xfa_ffsignature.h" #include "xfa/fxfa/app/xfa_ffsubform.h" #include "xfa/fxfa/app/xfa_fftext.h" #include "xfa/fxfa/app/xfa_fftextedit.h" #include "xfa/fxfa/app/xfa_ffwidget.h" #include "xfa/fxfa/app/xfa_ffwidgetacc.h" #include "xfa/fxfa/app/xfa_ffwidgethandler.h" #include "xfa/fxfa/app/xfa_fwladapter.h" #include "xfa/fxfa/app/xfa_textlayout.h" static void XFA_FFDeleteWidgetAcc(void* pData) { delete static_cast<CXFA_WidgetAcc*>(pData); } static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = { XFA_FFDeleteWidgetAcc, NULL}; CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {} CXFA_FFNotify::~CXFA_FFNotify() {} void CXFA_FFNotify::OnPageEvent(IXFA_LayoutPage* pSender, XFA_PAGEEVENT eEvent, void* pParam) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout()); if (!pDocView) { return; } pDocView->OnPageEvent(pSender, eEvent, (int32_t)(uintptr_t)pParam); } void CXFA_FFNotify::OnNodeEvent(CXFA_Node* pSender, XFA_NODEEVENT eEvent, void* pParam, void* pParam2, void* pParam3, void* pParam4) { switch (eEvent) { case XFA_NODEEVENT_Ready: OnNodeReady(pSender); break; case XFA_NODEEVENT_ValueChanging: OnValueChanging(pSender, pParam, pParam2); break; case XFA_NODEEVENT_ValueChanged: OnValueChanged(pSender, pParam, pParam2, pParam3, pParam4); break; case XFA_NODEEVENT_ChildAdded: OnChildAdded(pSender, pParam, pParam2); break; case XFA_NODEEVENT_ChildRemoved: OnChildRemoved(pSender, pParam, pParam2); break; } } void CXFA_FFNotify::OnWidgetDataEvent(CXFA_WidgetData* pSender, FX_DWORD dwEvent, void* pParam, void* pAdditional, void* pAdditional2) { CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender); switch (dwEvent) { case XFA_WIDGETEVENT_ListItemAdded: { if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) { return; } FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify(); CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL); if (!pWidget) { if (bStaticNotify) { pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent( pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional); } return; } while (pWidget) { if (pWidget->IsLoaded()) { if (pWidgetAcc->IsListBox()) { static_cast<CXFA_FFListBox*>(pWidget) ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam, (int32_t)(uintptr_t)pAdditional2); } else { static_cast<CXFA_FFComboBox*>(pWidget) ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam, (int32_t)(uintptr_t)pAdditional2); } } if (bStaticNotify) { pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent( pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional); } pWidget = pWidgetAcc->GetNextWidget(pWidget); } } break; case XFA_WIDGETEVENT_ListItemRemoved: { if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) { return; } FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify(); CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL); if (!pWidget) { if (bStaticNotify) { pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent( pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional); } return; } while (pWidget) { if (pWidget->IsLoaded()) { if (pWidgetAcc->IsListBox()) { static_cast<CXFA_FFListBox*>(pWidget) ->DeleteItem((int32_t)(uintptr_t)pParam); } else { static_cast<CXFA_FFComboBox*>(pWidget) ->DeleteItem((int32_t)(uintptr_t)pParam); } } if (bStaticNotify) { pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent( pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional); } pWidget = pWidgetAcc->GetNextWidget(pWidget); } } break; } } CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode) { IXFA_DocLayout* pLayout = m_pDoc->GetXFADoc()->GetDocLayout(); CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout); XFA_ELEMENT eType = pNode->GetClassID(); if (eType == XFA_ELEMENT_PageArea) { return new CXFA_FFPageView(pDocView, pNode); } if (eType == XFA_ELEMENT_ContentArea) { return new CXFA_ContainerLayoutItem(pNode); } CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()); if (!pAcc) { return new CXFA_ContentLayoutItem(pNode); } CXFA_FFPageView* pPageView = NULL; CXFA_FFWidget* pWidget = NULL; switch (pAcc->GetUIType()) { case XFA_ELEMENT_Barcode: pWidget = new CXFA_FFBarcode(pPageView, pAcc); break; case XFA_ELEMENT_Button: pWidget = new CXFA_FFPushButton(pPageView, pAcc); break; case XFA_ELEMENT_CheckButton: pWidget = new CXFA_FFCheckButton(pPageView, pAcc); break; case XFA_ELEMENT_ChoiceList: { if (pAcc->IsListBox()) { pWidget = new CXFA_FFListBox(pPageView, pAcc); } else { pWidget = new CXFA_FFComboBox(pPageView, pAcc); } } break; case XFA_ELEMENT_DateTimeEdit: pWidget = new CXFA_FFDateTimeEdit(pPageView, pAcc); break; case XFA_ELEMENT_ImageEdit: pWidget = new CXFA_FFImageEdit(pPageView, pAcc); break; case XFA_ELEMENT_NumericEdit: pWidget = new CXFA_FFNumericEdit(pPageView, pAcc); break; case XFA_ELEMENT_PasswordEdit: pWidget = new CXFA_FFPasswordEdit(pPageView, pAcc); break; case XFA_ELEMENT_Signature: pWidget = new CXFA_FFSignature(pPageView, pAcc); break; case XFA_ELEMENT_TextEdit: pWidget = new CXFA_FFTextEdit(pPageView, pAcc); break; case XFA_ELEMENT_Arc: pWidget = new CXFA_FFArc(pPageView, pAcc); break; case XFA_ELEMENT_Line: pWidget = new CXFA_FFLine(pPageView, pAcc); break; case XFA_ELEMENT_Rectangle: pWidget = new CXFA_FFRectangle(pPageView, pAcc); break; case XFA_ELEMENT_Text: pWidget = new CXFA_FFText(pPageView, pAcc); break; case XFA_ELEMENT_Image: pWidget = new CXFA_FFImage(pPageView, pAcc); break; case XFA_ELEMENT_Draw: pWidget = new CXFA_FFDraw(pPageView, pAcc); break; case XFA_ELEMENT_Subform: pWidget = new CXFA_FFSubForm(pPageView, pAcc); break; case XFA_ELEMENT_ExclGroup: pWidget = new CXFA_FFExclGroup(pPageView, pAcc); break; case XFA_ELEMENT_DefaultUi: default: pWidget = NULL; break; } if (!pWidget) { return NULL; } pWidget->SetDocView(pDocView); return pWidget; } void CXFA_FFNotify::OnLayoutEvent(IXFA_DocLayout* pLayout, CXFA_LayoutItem* pSender, XFA_LAYOUTEVENT eEvent, void* pParam, void* pParam2) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout); if (!pDocView || !XFA_GetWidgetFromLayoutItem(pSender)) { return; } switch (eEvent) { case XFA_LAYOUTEVENT_ItemAdded: OnLayoutItemAdd(pDocView, pLayout, pSender, pParam, pParam2); break; case XFA_LAYOUTEVENT_ItemRemoving: OnLayoutItemRemoving(pDocView, pLayout, pSender, pParam, pParam2); break; case XFA_LAYOUTEVENT_RectChanged: OnLayoutItemRectChanged(pDocView, pLayout, pSender, pParam, pParam2); break; case XFA_LAYOUTEVENT_StatusChanged: OnLayoutItemStatustChanged(pDocView, pLayout, pSender, pParam, pParam2); break; } } void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem, FX_FLOAT& fCalcWidth, FX_FLOAT& fCalcHeight) { CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData()); if (!pAcc) { return; } pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight); } FX_BOOL CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem, int32_t iBlockIndex, FX_FLOAT& fCalcHeightPos) { CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData()); if (!pAcc) { return FALSE; } return (XFA_LAYOUTRESULT)pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos); } FX_BOOL CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) { FX_BOOL bRet = FALSE; CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return bRet; } CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pFormItem->GetWidgetData()); if (!pWidgetAcc) { return bRet; } CXFA_EventParam EventParam; EventParam.m_eType = XFA_EVENT_Unknown; FXJSE_HVALUE pRetValue = NULL; int32_t iRet = pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue); if (iRet == XFA_EVENTERROR_Success && pRetValue) { bRet = FXJSE_Value_ToBoolean(pRetValue); FXJSE_Value_Release(pRetValue); } return bRet; } int32_t CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady, FX_BOOL bRecursive, CXFA_WidgetAcc* pExclude) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return XFA_EVENTERROR_NotExist; } return pDocView->ExecEventActivityByDeepFirst( pFormNode, eEventType, bIsFormReady, bRecursive, pExclude ? pExclude->GetNode() : NULL); } void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()); if (!pWidgetAcc) { return; } pDocView->AddCalculateWidgetAcc(pWidgetAcc); pDocView->AddValidateWidget(pWidgetAcc); } IXFA_Doc* CXFA_FFNotify::GetHDOC() { return m_pDoc; } IXFA_DocProvider* CXFA_FFNotify::GetDocProvider() { return m_pDoc->GetDocProvider(); } IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() { return m_pDoc->GetApp()->GetAppProvider(); } IXFA_WidgetHandler* CXFA_FFNotify::GetWidgetHandler() { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); return pDocView ? pDocView->GetWidgetHandler() : NULL; } IXFA_Widget* CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem) { return XFA_GetWidgetFromLayoutItem(pLayoutItem); } void CXFA_FFNotify::OpenDropDownList(IXFA_Widget* hWidget) { CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(hWidget); if (pWidget->GetDataAcc()->GetUIType() != XFA_ELEMENT_ChoiceList) { return; } CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); pDocView->LockUpdate(); static_cast<CXFA_FFComboBox*>(pWidget)->OpenDropDownList(); pDocView->UnlockUpdate(); pDocView->UpdateDocView(); } CFX_WideString CXFA_FFNotify::GetCurrentDateTime() { CFX_Unitime dataTime; dataTime.Now(); CFX_WideString wsDateTime; wsDateTime.Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(), dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(), dataTime.GetMinute(), dataTime.GetSecond()); return wsDateTime; } void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } pDocView->ResetWidgetData(static_cast<CXFA_WidgetAcc*>(pWidgetData)); } int32_t CXFA_FFNotify::GetLayoutStatus() { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); return pDocView ? pDocView->GetLayoutStatus() : 0; } void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } pDocView->AddNewFormNode(pNode); } void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } pDocView->AddIndexChangedSubform(pSubformNode); } CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return NULL; } CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc(); return pAcc ? pAcc->GetNode() : NULL; } void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } CXFA_WidgetAcc* pAcc = pNode ? static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()) : nullptr; pDocView->SetFocusWidgetAcc(pAcc); } void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } XFA_ELEMENT iType = pNode->GetClassID(); if (XFA_IsCreateWidget(iType)) { CXFA_WidgetAcc* pAcc = new CXFA_WidgetAcc(pDocView, static_cast<CXFA_Node*>(pNode)); pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc); return; } switch (iType) { case XFA_ELEMENT_BindItems: pDocView->m_bindItems.Add(pNode); break; case XFA_ELEMENT_Validate: { pNode->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE); } break; default: break; } } void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender, void* pParam, void* pParam2) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) { return; } FX_DWORD dwPacket = pSender->GetPacketID(); if (dwPacket & XFA_XDPPACKET_Datasets) { } else if (pSender->IsFormContainer()) { XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam; if (eAttr == XFA_ATTRIBUTE_Presence) { CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender->GetWidgetData()); if (!pWidgetAcc) { return; } CXFA_FFWidget* pWidget = NULL; while ((pWidget = pWidgetAcc->GetNextWidget(pWidget))) { if (pWidget->IsLoaded()) { pWidget->AddInvalidateRect(); } } } } } void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender, void* pParam, void* pParam2, void* pParam3, void* pParam4) { CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } FX_DWORD dwPacket = pSender->GetPacketID(); XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam; if (dwPacket & XFA_XDPPACKET_Form) { CXFA_Node* pParentNode = static_cast<CXFA_Node*>(pParam3); CXFA_Node* pWidgetNode = static_cast<CXFA_Node*>(pParam4); XFA_ELEMENT ePType = pParentNode->GetClassID(); FX_BOOL bIsContainerNode = pParentNode->IsContainerNode(); CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pWidgetNode->GetWidgetData()); if (!pWidgetAcc) { return; } FX_BOOL bUpdateProperty = FALSE; pDocView->SetChangeMark(); switch (ePType) { case XFA_ELEMENT_Caption: { CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout(); if (!pCapOut) { return; } pCapOut->Unload(); } break; case XFA_ELEMENT_Ui: case XFA_ELEMENT_Para: bUpdateProperty = TRUE; break; case XFA_ELEMENT_Font: case XFA_ELEMENT_Margin: case XFA_ELEMENT_Value: case XFA_ELEMENT_Items: break; default: break; } if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access) { bUpdateProperty = TRUE; FX_BOOL bNotify = pDocView->IsStaticNotify(); if (bNotify) { pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_AccessChanged, NULL, pParam2, NULL); } } if (eAttr == XFA_ATTRIBUTE_Value) { pDocView->AddCalculateNodeNotify(pSender); if (ePType == XFA_ELEMENT_Value || bIsContainerNode) { FX_BOOL bNotify = pDocView->IsStaticNotify(); if (bIsContainerNode) { pWidgetAcc->UpdateUIDisplay(); pDocView->AddCalculateWidgetAcc(pWidgetAcc); pDocView->AddValidateWidget(pWidgetAcc); } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent) ->GetClassID() == XFA_ELEMENT_ExclGroup) { pWidgetAcc->UpdateUIDisplay(); } if (bNotify) { pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL); } return; } } CXFA_FFWidget* pWidget = NULL; while ((pWidget = pWidgetAcc->GetNextWidget(pWidget))) { if (!pWidget->IsLoaded()) { continue; } if (bUpdateProperty) { pWidget->UpdateWidgetProperty(); } pWidget->PerformLayout(); pWidget->AddInvalidateRect(); } } else { if (eAttr == XFA_ATTRIBUTE_Value) { pDocView->AddCalculateNodeNotify(pSender); } } } void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender, void* pParam, void* pParam2) { if (!pSender->IsFormContainer()) { return; } CXFA_FFDocView* pDocView = m_pDoc->GetDocView(); if (!pDocView) { return; } FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End); if (bLayoutReady) { m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc); } } void CXFA_FFNotify::OnChildRemoved(CXFA_Node* pSender, void* pParam, void* pParam2) { if (CXFA_FFDocView* pDocView = m_pDoc->GetDocView()) { FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End); if (bLayoutReady) { m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc); } } } void CXFA_FFNotify::OnLayoutItemAdd(CXFA_FFDocView* pDocView, IXFA_DocLayout* pLayout, CXFA_LayoutItem* pSender, void* pParam, void* pParam2) { CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender); int32_t iPageIdx = (int32_t)(uintptr_t)pParam; IXFA_PageView* pNewPageView = pDocView->GetPageView(iPageIdx); FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam2; FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable; pWidget->ModifyStatus(dwStatus, dwFilter); IXFA_PageView* pPrePageView = pWidget->GetPageView(); if (pPrePageView != pNewPageView || (dwStatus & (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) == (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) { pWidget->SetPageView(pNewPageView); m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PostAdded, pNewPageView, pPrePageView); } if (pDocView->GetLayoutStatus() != XFA_DOCVIEW_LAYOUTSTATUS_End || !(dwStatus & XFA_WIDGETSTATUS_Visible)) { return; } if (pWidget->IsLoaded()) { CFX_RectF rtOld; pWidget->GetWidgetRect(rtOld); if (rtOld != pWidget->ReCacheWidgetRect()) pWidget->PerformLayout(); } else { pWidget->LoadWidget(); } pWidget->AddInvalidateRect(nullptr); } void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_FFDocView* pDocView, IXFA_DocLayout* pLayout, CXFA_LayoutItem* pSender, void* pParam, void* pParam2) { CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender); pDocView->DeleteLayoutItem(pWidget); m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PreRemoved, nullptr, pWidget->GetPageView()); pWidget->AddInvalidateRect(nullptr); } void CXFA_FFNotify::OnLayoutItemRectChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout* pLayout, CXFA_LayoutItem* pSender, void* pParam, void* pParam2) {} void CXFA_FFNotify::OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout* pLayout, CXFA_LayoutItem* pSender, void* pParam, void* pParam2) { CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender); if (!pWidget) { return; } FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam; if (dwStatus == 0) { CXFA_LayoutItem* pPreItem = pSender->GetPrev(); if (pPreItem) { CXFA_FFWidget* pPreWidget = static_cast<CXFA_FFWidget*>(pPreItem); if (pPreWidget) { dwStatus = pPreWidget->GetStatus(); } } } FX_DWORD dwOldStatus = pWidget->GetStatus(); FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable; if ((dwOldStatus & dwFilter) == dwStatus) { return; } pWidget->ModifyStatus(dwStatus, dwFilter); }