blob: 9d8e049787a4a2ae96dafe52e1df7405fc640731 [file] [log] [blame]
// 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/src/foxitlib.h"
#include "xfa/src/fxfa/src/common/xfa_common.h"
#include "xfa_fwladapter.h"
#include "xfa_ffdocview.h"
#include "xfa_ffpageview.h"
#include "xfa_ffwidgethandler.h"
#include "xfa_ffdoc.h"
#include "xfa_ffwidget.h"
#include "xfa_fffield.h"
#include "xfa_ffpushbutton.h"
#include "xfa_ffcheckbutton.h"
#include "xfa_ffchoicelist.h"
#include "xfa_ffimageedit.h"
#include "xfa_fftextedit.h"
#include "xfa_ffbarcode.h"
#include "xfa_ffdraw.h"
#include "xfa_fftext.h"
#include "xfa_ffpath.h"
#include "xfa_ffimage.h"
#include "xfa_ffexclgroup.h"
#include "xfa_ffsubform.h"
#include "xfa_ffsignature.h"
#include "xfa_ffapp.h"
#include "xfa_textlayout.h"
#include "xfa_ffwidgetacc.h"
extern const XFA_ATTRIBUTEENUM gs_EventActivity[] = {
XFA_ATTRIBUTEENUM_Click, XFA_ATTRIBUTEENUM_Change,
XFA_ATTRIBUTEENUM_DocClose, XFA_ATTRIBUTEENUM_DocReady,
XFA_ATTRIBUTEENUM_Enter, XFA_ATTRIBUTEENUM_Exit,
XFA_ATTRIBUTEENUM_Full, XFA_ATTRIBUTEENUM_IndexChange,
XFA_ATTRIBUTEENUM_Initialize, XFA_ATTRIBUTEENUM_MouseDown,
XFA_ATTRIBUTEENUM_MouseEnter, XFA_ATTRIBUTEENUM_MouseExit,
XFA_ATTRIBUTEENUM_MouseUp, XFA_ATTRIBUTEENUM_PostExecute,
XFA_ATTRIBUTEENUM_PostOpen, XFA_ATTRIBUTEENUM_PostPrint,
XFA_ATTRIBUTEENUM_PostSave, XFA_ATTRIBUTEENUM_PostSign,
XFA_ATTRIBUTEENUM_PostSubmit, XFA_ATTRIBUTEENUM_PreExecute,
XFA_ATTRIBUTEENUM_PreOpen, XFA_ATTRIBUTEENUM_PrePrint,
XFA_ATTRIBUTEENUM_PreSave, XFA_ATTRIBUTEENUM_PreSign,
XFA_ATTRIBUTEENUM_PreSubmit, XFA_ATTRIBUTEENUM_Ready,
XFA_ATTRIBUTEENUM_Unknown,
};
CXFA_FFDocView::CXFA_FFDocView(CXFA_FFDoc* pDoc)
: m_bLayoutEvent(FALSE),
m_pListFocusWidget(nullptr),
m_bInLayoutStatus(FALSE),
m_pDoc(pDoc),
m_pWidgetHandler(nullptr),
m_pXFADocLayout(nullptr),
m_pFocusAcc(nullptr),
m_pFocusWidget(nullptr),
m_pOldFocusWidget(nullptr),
m_iStatus(XFA_DOCVIEW_LAYOUTSTATUS_None),
m_iLock(0) {
}
CXFA_FFDocView::~CXFA_FFDocView() {
DestroyDocView();
if (m_pWidgetHandler) {
delete m_pWidgetHandler;
}
m_pWidgetHandler = NULL;
}
void CXFA_FFDocView::InitLayout(CXFA_Node* pNode) {
RunBindItems();
ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize);
ExecEventActivityByDeepFirst(pNode, XFA_EVENT_IndexChange);
}
int32_t CXFA_FFDocView::StartLayout(int32_t iStartPage) {
m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
m_pDoc->GetXFADoc()->DoProtoMerge();
m_pDoc->GetXFADoc()->DoDataMerge();
m_pXFADocLayout = GetXFALayout();
int32_t iStatus = m_pXFADocLayout->StartLayout();
if (iStatus < 0) {
return iStatus;
}
CXFA_Node* pRootItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pRootItem) {
return iStatus;
}
InitLayout(pRootItem);
InitCalculate(pRootItem);
InitValidate(pRootItem);
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, TRUE);
m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
return iStatus;
}
int32_t CXFA_FFDocView::DoLayout(IFX_Pause* pPause) {
int32_t iStatus = 100;
iStatus = m_pXFADocLayout->DoLayout(pPause);
if (iStatus != 100) {
return iStatus;
}
m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Doing;
return iStatus;
}
void CXFA_FFDocView::StopLayout() {
CXFA_Node* pRootItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pRootItem) {
return;
}
CXFA_Node* pSubformNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
if (!pSubformNode) {
return;
}
CXFA_Node* pPageSetNode =
pSubformNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);
if (!pPageSetNode) {
return;
}
RunCalculateWidgets();
RunValidate();
InitLayout(pPageSetNode);
InitCalculate(pPageSetNode);
InitValidate(pPageSetNode);
ExecEventActivityByDeepFirst(pPageSetNode, XFA_EVENT_Ready, TRUE);
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocReady);
RunCalculateWidgets();
RunValidate();
if (RunLayout()) {
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
}
m_CalculateAccs.RemoveAll();
if (m_pFocusAcc && !m_pFocusWidget) {
SetFocusWidgetAcc(m_pFocusAcc);
}
m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_End;
}
int32_t CXFA_FFDocView::GetLayoutStatus() {
return m_iStatus;
}
void CXFA_FFDocView::ShowNullTestMsg() {
int32_t iCount = m_arrNullTestMsg.GetSize();
CXFA_FFApp* pApp = m_pDoc->GetApp();
IXFA_AppProvider* pAppProvider = pApp->GetAppProvider();
if (pAppProvider && iCount) {
int32_t iRemain = iCount > 7 ? iCount - 7 : 0;
iCount -= iRemain;
CFX_WideString wsMsg;
for (int32_t i = 0; i < iCount; i++) {
wsMsg += m_arrNullTestMsg[i] + FX_WSTRC(L"\n");
}
if (iRemain > 0) {
CFX_WideString wsLimit;
pAppProvider->LoadString(XFA_IDS_ValidateLimit, wsLimit);
if (!wsLimit.IsEmpty()) {
CFX_WideString wsTemp;
wsTemp.Format((const FX_WCHAR*)wsLimit, iRemain);
wsMsg += FX_WSTRC(L"\n") + wsTemp;
}
}
CFX_WideString wsTitle;
pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
pAppProvider->MsgBox(wsMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
}
m_arrNullTestMsg.RemoveAll();
}
void CXFA_FFDocView::UpdateDocView() {
if (IsUpdateLocked()) {
return;
}
LockUpdate();
int32_t iNewAdds = m_NewAddedNodes.GetSize();
for (int32_t i = 0; i < iNewAdds; i++) {
CXFA_Node* pNode = reinterpret_cast<CXFA_Node*>(m_NewAddedNodes[i]);
InitCalculate(pNode);
InitValidate(pNode);
ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Ready, TRUE);
}
m_NewAddedNodes.RemoveAll();
this->RunSubformIndexChange();
this->RunCalculateWidgets();
this->RunValidate();
ShowNullTestMsg();
if (RunLayout() && m_bLayoutEvent) {
RunEventLayoutReady();
}
m_bLayoutEvent = FALSE;
m_CalculateAccs.RemoveAll();
this->RunInvalidate();
UnlockUpdate();
}
int32_t CXFA_FFDocView::CountPageViews() {
if (!m_pXFADocLayout) {
return 0;
}
return m_pXFADocLayout->CountPages();
}
IXFA_PageView* CXFA_FFDocView::GetPageView(int32_t nIndex) {
if (!m_pXFADocLayout) {
return NULL;
}
return static_cast<CXFA_FFPageView*>(m_pXFADocLayout->GetPage(nIndex));
}
IXFA_Widget* CXFA_FFDocView::GetWidgetByName(const CFX_WideStringC& wsName) {
return GetWidgetByName(wsName, NULL);
}
CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(
const CFX_WideStringC& wsName) {
return GetWidgetAccByName(wsName, NULL);
}
IXFA_DocLayout* CXFA_FFDocView::GetXFALayout() const {
return m_pDoc->GetXFADoc()->GetDocLayout();
}
FX_BOOL CXFA_FFDocView::ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc) {
CXFA_Node* pNode = pWidgetAcc->GetNode();
XFA_ELEMENT eType = pNode->GetClassID();
if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_ExclGroup) {
return FALSE;
}
FX_BOOL bNotify = IsStaticNotify();
pWidgetAcc->ResetData();
pWidgetAcc->UpdateUIDisplay();
if (bNotify) {
pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL,
NULL);
}
if (CXFA_Validate validate = pWidgetAcc->GetValidate()) {
AddValidateWidget(pWidgetAcc);
validate.GetNode()->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
}
return TRUE;
}
void CXFA_FFDocView::ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc) {
m_bLayoutEvent = TRUE;
FX_BOOL bChanged = FALSE;
CXFA_Node* pFormNode = NULL;
if (pWidgetAcc) {
bChanged = ResetSingleWidgetAccData(pWidgetAcc);
pFormNode = pWidgetAcc->GetNode();
} else {
pFormNode = GetRootSubform();
}
if (!pFormNode) {
return;
}
if (pFormNode->GetClassID() != XFA_ELEMENT_Field &&
pFormNode->GetClassID() != XFA_ELEMENT_ExclGroup) {
CXFA_WidgetAccIterator Iterator(this, pFormNode);
while (CXFA_WidgetAcc* pAcc = Iterator.MoveToNext()) {
bChanged |= ResetSingleWidgetAccData(pAcc);
if (pAcc->GetNode()->GetClassID() == XFA_ELEMENT_ExclGroup) {
Iterator.SkipTree();
}
}
}
if (bChanged) {
m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
}
}
int32_t CXFA_FFDocView::ProcessWidgetEvent(CXFA_EventParam* pParam,
CXFA_WidgetAcc* pWidgetAcc) {
if (pParam == NULL) {
return XFA_EVENTERROR_Error;
}
if (pParam->m_eType == XFA_EVENT_Validate) {
CFX_WideString wsValidateStr = FX_WSTRC(L"preSubmit");
CXFA_Node* pConfigItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Config));
if (pConfigItem) {
CXFA_Node* pValidateNode = NULL;
CXFA_Node* pAcrobatNode = pConfigItem->GetChild(0, XFA_ELEMENT_Acrobat);
pValidateNode =
pAcrobatNode ? pAcrobatNode->GetChild(0, XFA_ELEMENT_Validate) : NULL;
if (!pValidateNode) {
CXFA_Node* pPresentNode = pConfigItem->GetChild(0, XFA_ELEMENT_Present);
pValidateNode = pPresentNode
? pPresentNode->GetChild(0, XFA_ELEMENT_Validate)
: NULL;
}
if (pValidateNode) {
wsValidateStr = pValidateNode->GetContent();
}
}
FX_BOOL bValidate = FALSE;
switch (pParam->m_iValidateActivities) {
case XFA_VALIDATE_preSubmit:
bValidate = wsValidateStr.Find(L"preSubmit") != -1;
break;
case XFA_VALIDATE_prePrint:
bValidate = wsValidateStr.Find(L"prePrint") != -1;
break;
case XFA_VALIDATE_preExecute:
bValidate = wsValidateStr.Find(L"preExecute") != -1;
break;
case XFA_VALIDATE_preSave:
bValidate = wsValidateStr.Find(L"preSave") != -1;
break;
}
if (!bValidate) {
return XFA_EVENTERROR_Sucess;
}
}
CXFA_Node* pNode = pWidgetAcc ? pWidgetAcc->GetNode() : NULL;
if (!pNode) {
CXFA_Node* pRootItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pRootItem) {
return XFA_EVENTERROR_Error;
}
pNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
}
ExecEventActivityByDeepFirst(pNode, pParam->m_eType, pParam->m_bIsFormReady);
return XFA_EVENTERROR_Sucess;
}
IXFA_WidgetHandler* CXFA_FFDocView::GetWidgetHandler() {
if (!m_pWidgetHandler) {
m_pWidgetHandler = new CXFA_FFWidgetHandler(this);
}
return m_pWidgetHandler;
}
IXFA_WidgetIterator* CXFA_FFDocView::CreateWidgetIterator() {
CXFA_Node* pFormRoot = GetRootSubform();
if (!pFormRoot) {
return NULL;
}
return new CXFA_FFDocWidgetIterator(this, pFormRoot);
}
IXFA_WidgetAccIterator* CXFA_FFDocView::CreateWidgetAccIterator(
XFA_WIDGETORDER eOrder) {
CXFA_Node* pFormRoot = GetRootSubform();
if (!pFormRoot) {
return NULL;
}
return new CXFA_WidgetAccIterator(this, pFormRoot);
}
IXFA_Widget* CXFA_FFDocView::GetFocusWidget() {
return m_pFocusWidget;
}
void CXFA_FFDocView::KillFocus() {
if (m_pFocusWidget &&
(m_pFocusWidget->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
(m_pFocusWidget)->OnKillFocus(NULL);
}
m_pFocusAcc = NULL;
m_pFocusWidget = NULL;
m_pOldFocusWidget = NULL;
}
FX_BOOL CXFA_FFDocView::SetFocus(IXFA_Widget* hWidget) {
CXFA_FFWidget* pNewFocus = (CXFA_FFWidget*)hWidget;
if (m_pOldFocusWidget == pNewFocus) {
return FALSE;
}
CXFA_FFWidget* pOldFocus = m_pOldFocusWidget;
m_pOldFocusWidget = pNewFocus;
if (pOldFocus) {
if (m_pFocusWidget != m_pOldFocusWidget &&
(pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
m_pFocusWidget = pOldFocus;
pOldFocus->OnKillFocus(pNewFocus);
} else if ((pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
if (!pOldFocus->IsLoaded()) {
pOldFocus->LoadWidget();
}
pOldFocus->OnSetFocus(m_pFocusWidget);
m_pFocusWidget = pOldFocus;
pOldFocus->OnKillFocus(pNewFocus);
}
}
if (m_pFocusWidget == m_pOldFocusWidget) {
return FALSE;
}
pNewFocus = m_pOldFocusWidget;
if (m_pListFocusWidget && pNewFocus == m_pListFocusWidget) {
m_pFocusAcc = NULL;
m_pFocusWidget = NULL;
m_pListFocusWidget = NULL;
m_pOldFocusWidget = NULL;
return FALSE;
}
if (pNewFocus && (pNewFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
if (!pNewFocus->IsLoaded()) {
pNewFocus->LoadWidget();
}
pNewFocus->OnSetFocus(m_pFocusWidget);
}
m_pFocusAcc = pNewFocus ? pNewFocus->GetDataAcc() : NULL;
m_pFocusWidget = pNewFocus;
m_pOldFocusWidget = m_pFocusWidget;
return TRUE;
}
CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc() {
return m_pFocusAcc;
}
void CXFA_FFDocView::SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) {
CXFA_FFWidget* pNewFocus =
pWidgetAcc ? pWidgetAcc->GetNextWidget(NULL) : NULL;
if (SetFocus(pNewFocus)) {
m_pFocusAcc = pWidgetAcc;
if (m_iStatus == XFA_DOCVIEW_LAYOUTSTATUS_End) {
m_pDoc->GetDocProvider()->SetFocusWidget(m_pDoc, m_pFocusWidget);
}
}
}
void CXFA_FFDocView::DeleteLayoutItem(CXFA_FFWidget* pWidget) {
if (m_pFocusAcc == pWidget->GetDataAcc()) {
m_pFocusAcc = NULL;
m_pFocusWidget = NULL;
m_pOldFocusWidget = NULL;
}
}
static int32_t XFA_ProcessEvent(CXFA_FFDocView* pDocView,
CXFA_WidgetAcc* pWidgetAcc,
CXFA_EventParam* pParam) {
if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
return XFA_EVENTERROR_NotExist;
}
if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
return XFA_EVENTERROR_NotExist;
}
switch (pParam->m_eType) {
case XFA_EVENT_Calculate:
return pWidgetAcc->ProcessCalculate();
case XFA_EVENT_Validate:
if (((CXFA_FFDoc*)pDocView->GetDoc())
->GetDocProvider()
->IsValidationsEnabled(pDocView->GetDoc())) {
return pWidgetAcc->ProcessValidate(0x01);
}
return XFA_EVENTERROR_Disabled;
case XFA_EVENT_InitCalculate: {
CXFA_Calculate calc = pWidgetAcc->GetCalculate();
if (!calc) {
return XFA_EVENTERROR_NotExist;
}
if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
return XFA_EVENTERROR_Disabled;
}
CXFA_Script script = calc.GetScript();
return pWidgetAcc->ExecuteScript(script, pParam);
}
default:
break;
}
int32_t iRet =
pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
return iRet;
}
int32_t CXFA_FFDocView::ExecEventActivityByDeepFirst(CXFA_Node* pFormNode,
XFA_EVENTTYPE eEventType,
FX_BOOL bIsFormReady,
FX_BOOL bRecursive,
CXFA_Node* pExclude) {
int32_t iRet = XFA_EVENTERROR_NotExist;
if (pFormNode == pExclude) {
return iRet;
}
XFA_ELEMENT elementType = pFormNode->GetClassID();
if (elementType == XFA_ELEMENT_Field) {
if (eEventType == XFA_EVENT_IndexChange) {
return iRet;
}
CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
if (pWidgetAcc == NULL) {
return iRet;
}
CXFA_EventParam eParam;
eParam.m_eType = eEventType;
eParam.m_pTarget = pWidgetAcc;
eParam.m_bIsFormReady = bIsFormReady;
return XFA_ProcessEvent(this, pWidgetAcc, &eParam);
}
if (bRecursive) {
for (CXFA_Node* pNode = pFormNode->GetNodeItem(
XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling,
XFA_OBJECTTYPE_ContainerNode)) {
elementType = pNode->GetClassID();
if (elementType != XFA_ELEMENT_Variables &&
elementType != XFA_ELEMENT_Draw) {
iRet |= ExecEventActivityByDeepFirst(pNode, eEventType, bIsFormReady,
bRecursive, pExclude);
}
}
}
CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
if (pWidgetAcc == NULL) {
return iRet;
}
CXFA_EventParam eParam;
eParam.m_eType = eEventType;
eParam.m_pTarget = pWidgetAcc;
eParam.m_bIsFormReady = bIsFormReady;
iRet |= XFA_ProcessEvent(this, pWidgetAcc, &eParam);
return iRet;
}
CXFA_FFWidget* CXFA_FFDocView::GetWidgetByName(const CFX_WideStringC& wsName,
CXFA_FFWidget* pRefWidget) {
CXFA_WidgetAcc* pRefAcc = pRefWidget ? pRefWidget->GetDataAcc() : NULL;
if (CXFA_WidgetAcc* pAcc = GetWidgetAccByName(wsName, pRefAcc)) {
return pAcc->GetNextWidget(NULL);
}
return NULL;
}
CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(
const CFX_WideStringC& wsName,
CXFA_WidgetAcc* pRefWidgetAcc) {
CFX_WideString wsExpression;
FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
IXFA_ScriptContext* pScriptContext = m_pDoc->GetXFADoc()->GetScriptContext();
if (!pScriptContext) {
return NULL;
}
CXFA_Node* refNode = NULL;
if (pRefWidgetAcc != NULL) {
refNode = pRefWidgetAcc->GetNode();
wsExpression = wsName;
} else {
wsExpression = L"$form." + wsName;
}
XFA_RESOLVENODE_RS resoveNodeRS;
int32_t iRet = pScriptContext->ResolveObjects(refNode, wsExpression,
resoveNodeRS, dwStyle);
if (iRet < 1) {
return NULL;
}
if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
CXFA_Node* pNode = resoveNodeRS.nodes[0]->AsNode();
if (pNode) {
return (CXFA_WidgetAcc*)pNode->GetWidgetData();
}
}
return NULL;
}
void CXFA_FFDocView::OnPageEvent(IXFA_LayoutPage* pSender,
XFA_PAGEEVENT eEvent,
int32_t iPageIndex) {
CXFA_FFPageView* pFFPageView = static_cast<CXFA_FFPageView*>(pSender);
if (eEvent == XFA_PAGEEVENT_PageRemoved) {
m_pDoc->GetDocProvider()->PageViewEvent(pFFPageView,
XFA_PAGEVIEWEVENT_PostRemoved);
return;
}
m_pDoc->GetDocProvider()->PageViewEvent(pFFPageView,
XFA_PAGEVIEWEVENT_PostAdded);
pFFPageView->LoadPageView();
}
void CXFA_FFDocView::LockUpdate() {
m_iLock++;
}
void CXFA_FFDocView::UnlockUpdate() {
m_iLock--;
}
FX_BOOL CXFA_FFDocView::IsUpdateLocked() {
return m_iLock;
}
void CXFA_FFDocView::ClearInvalidateList() {
FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
while (ps) {
void* pPageView = NULL;
CFX_RectF* pRect = NULL;
m_mapPageInvalidate.GetNextAssoc(ps, pPageView, (void*&)pRect);
delete pRect;
}
m_mapPageInvalidate.RemoveAll();
}
void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget,
const CFX_RectF& rtInvalidate) {
AddInvalidateRect(pWidget->GetPageView(), rtInvalidate);
}
void CXFA_FFDocView::AddInvalidateRect(IXFA_PageView* pPageView,
const CFX_RectF& rtInvalidate) {
CFX_RectF* pRect = (CFX_RectF*)m_mapPageInvalidate.GetValueAt(pPageView);
if (!pRect) {
pRect = new CFX_RectF;
pRect->Set(rtInvalidate.left, rtInvalidate.top, rtInvalidate.width,
rtInvalidate.height);
m_mapPageInvalidate.SetAt(pPageView, pRect);
} else {
pRect->Union(rtInvalidate);
}
}
void CXFA_FFDocView::RunInvalidate() {
FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
while (ps) {
IXFA_PageView* pPageView = NULL;
CFX_RectF* pRect = NULL;
m_mapPageInvalidate.GetNextAssoc(ps, (void*&)pPageView, (void*&)pRect);
m_pDoc->GetDocProvider()->InvalidateRect(pPageView, *pRect);
delete pRect;
}
m_mapPageInvalidate.RemoveAll();
}
FX_BOOL CXFA_FFDocView::RunLayout() {
LockUpdate();
m_bInLayoutStatus = TRUE;
if (!m_pXFADocLayout->IncrementLayout() &&
m_pXFADocLayout->StartLayout() < 100) {
m_pXFADocLayout->DoLayout();
UnlockUpdate();
m_bInLayoutStatus = FALSE;
return TRUE;
}
m_bInLayoutStatus = FALSE;
UnlockUpdate();
return FALSE;
}
void CXFA_FFDocView::RunSubformIndexChange() {
int32_t iSubforms = m_IndexChangedSubforms.GetSize();
for (int32_t i = 0; i < iSubforms; i++) {
CXFA_Node* pSubformNode =
reinterpret_cast<CXFA_Node*>(m_IndexChangedSubforms[i]);
CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSubformNode->GetWidgetData();
if (!pWidgetAcc) {
continue;
}
CXFA_EventParam eParam;
eParam.m_eType = XFA_EVENT_IndexChange;
eParam.m_pTarget = pWidgetAcc;
pWidgetAcc->ProcessEvent(XFA_ATTRIBUTEENUM_IndexChange, &eParam);
}
m_IndexChangedSubforms.RemoveAll();
}
void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) {
m_NewAddedNodes.Add(pNode);
this->InitLayout(pNode);
}
void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
FXSYS_assert(pNode->GetClassID() == XFA_ELEMENT_Subform);
m_IndexChangedSubforms.Add(pNode);
}
void CXFA_FFDocView::RunDocClose() {
CXFA_Node* pRootItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pRootItem) {
return;
}
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocClose);
}
void CXFA_FFDocView::DestroyDocView() {
ClearInvalidateList();
m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None;
m_iLock = 0;
m_ValidateAccs.RemoveAll();
m_bindItems.RemoveAll();
m_CalculateAccs.RemoveAll();
}
FX_BOOL CXFA_FFDocView::IsStaticNotify() {
return m_pDoc->GetDocType() == XFA_DOCTYPE_Static;
}
void CXFA_FFDocView::AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) {
int32_t iAccs = m_CalculateAccs.GetSize();
CXFA_WidgetAcc* pCurrentAcc =
(iAccs < 1) ? (CXFA_WidgetAcc*)NULL
: (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
if (pCurrentAcc != pWidgetAcc) {
m_CalculateAccs.Add(pWidgetAcc);
}
}
void CXFA_FFDocView::AddCalculateNodeNotify(CXFA_Node* pNodeChange) {
CXFA_CalcData* pGlobalData =
(CXFA_CalcData*)pNodeChange->GetUserData(XFA_CalcData);
int32_t iCount = pGlobalData ? pGlobalData->m_Globals.GetSize() : 0;
for (int32_t i = 0; i < iCount; i++) {
CXFA_WidgetAcc* pResultAcc = (CXFA_WidgetAcc*)pGlobalData->m_Globals[i];
if (pResultAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
continue;
}
int32_t iAccs = m_CalculateAccs.GetSize();
CXFA_WidgetAcc* pCurrentAcc =
(iAccs < 1) ? (CXFA_WidgetAcc*)NULL
: (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
if (pCurrentAcc != pResultAcc) {
m_CalculateAccs.Add(pResultAcc);
}
}
}
void CXFA_FFDocView::RunCalculateRecursive(int32_t& iIndex) {
while (iIndex < m_CalculateAccs.GetSize()) {
CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[iIndex];
AddCalculateNodeNotify(pCurAcc->GetNode());
int32_t iRefCount =
(int32_t)(uintptr_t)pCurAcc->GetNode()->GetUserData(XFA_CalcRefCount);
iRefCount++;
pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount,
(void*)(uintptr_t)iRefCount);
if (iRefCount > 11) {
break;
}
if ((pCurAcc->ProcessCalculate()) == XFA_EVENTERROR_Sucess) {
AddValidateWidget(pCurAcc);
}
iIndex++;
RunCalculateRecursive(iIndex);
}
}
int32_t CXFA_FFDocView::RunCalculateWidgets() {
if (!m_pDoc->GetDocProvider()->IsCalculationsEnabled(m_pDoc)) {
return XFA_EVENTERROR_Disabled;
}
int32_t iCounts = m_CalculateAccs.GetSize();
int32_t iIndex = 0;
if (iCounts > 0) {
RunCalculateRecursive(iIndex);
}
for (int32_t i = 0; i < m_CalculateAccs.GetSize(); i++) {
CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[i];
pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, (void*)(uintptr_t)0);
}
m_CalculateAccs.RemoveAll();
return XFA_EVENTERROR_Sucess;
}
void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget) {
if (m_ValidateAccs.Find(pWidget) < 0) {
m_ValidateAccs.Add(pWidget);
}
}
FX_BOOL CXFA_FFDocView::InitCalculate(CXFA_Node* pNode) {
ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate);
return TRUE;
}
FX_BOOL CXFA_FFDocView::InitValidate(CXFA_Node* pNode) {
if (!m_pDoc->GetDocProvider()->IsValidationsEnabled(m_pDoc)) {
return FALSE;
}
ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Validate);
m_ValidateAccs.RemoveAll();
return TRUE;
}
FX_BOOL CXFA_FFDocView::RunValidate() {
if (!m_pDoc->GetDocProvider()->IsValidationsEnabled(m_pDoc)) {
return FALSE;
}
int32_t iCounts = m_ValidateAccs.GetSize();
for (int32_t i = 0; i < iCounts; i++) {
CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)m_ValidateAccs[i];
if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
continue;
}
pAcc->ProcessValidate();
}
m_ValidateAccs.RemoveAll();
return TRUE;
}
FX_BOOL CXFA_FFDocView::RunEventLayoutReady() {
CXFA_Node* pRootItem =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pRootItem) {
return FALSE;
}
ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
RunLayout();
return TRUE;
}
void CXFA_FFDocView::RunBindItems() {
int32_t iCount = m_bindItems.GetSize();
for (int32_t i = 0; i < iCount; i++) {
if (reinterpret_cast<CXFA_Node*>(m_bindItems[i])
->HasFlag(XFA_NODEFLAG_HasRemoved)) {
continue;
}
CXFA_Node* pWidgetNode = reinterpret_cast<CXFA_Node*>(m_bindItems[i])
->GetNodeItem(XFA_NODEITEM_Parent);
CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pWidgetNode->GetWidgetData();
if (!pAcc) {
continue;
}
CXFA_BindItems binditems(reinterpret_cast<CXFA_Node*>(m_bindItems[i]));
IXFA_ScriptContext* pScriptContext =
pWidgetNode->GetDocument()->GetScriptContext();
CFX_WideStringC wsRef;
binditems.GetRef(wsRef);
FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
XFA_RESOLVENODE_ALL;
XFA_RESOLVENODE_RS rs;
pScriptContext->ResolveObjects(pWidgetNode, wsRef, rs, dwStyle);
int32_t iCount = rs.nodes.GetSize();
pAcc->DeleteItem(-1);
if (rs.dwFlags != XFA_RESOVENODE_RSTYPE_Nodes || iCount < 1) {
continue;
}
CFX_WideStringC wsValueRef, wsLabelRef;
binditems.GetValueRef(wsValueRef);
binditems.GetLabelRef(wsLabelRef);
FX_BOOL bUseValue = wsLabelRef.IsEmpty() || wsLabelRef == wsValueRef;
FX_BOOL bLabelUseContent =
wsLabelRef.IsEmpty() || wsLabelRef == FX_WSTRC(L"$");
FX_BOOL bValueUseContent =
wsValueRef.IsEmpty() || wsValueRef == FX_WSTRC(L"$");
CFX_WideString wsValue, wsLabel;
FX_DWORD uValueHash = FX_HashCode_String_GetW(CFX_WideString(wsValueRef),
wsValueRef.GetLength());
for (int32_t i = 0; i < iCount; i++) {
CXFA_Object* refObj = rs.nodes[i];
if (!refObj->IsNode()) {
continue;
}
CXFA_Node* refNode = refObj->AsNode();
if (bValueUseContent) {
wsValue = refNode->GetContent();
} else {
CXFA_Node* nodeValue = refNode->GetFirstChildByName(uValueHash);
if (nodeValue == NULL) {
wsValue = refNode->GetContent();
} else {
wsValue = nodeValue->GetContent();
}
}
if (!bUseValue) {
if (bLabelUseContent) {
wsLabel = refNode->GetContent();
} else {
CXFA_Node* nodeLabel = refNode->GetFirstChildByName(wsLabelRef);
if (nodeLabel != NULL) {
wsLabel = nodeLabel->GetContent();
}
}
} else {
wsLabel = wsValue;
}
pAcc->InsertItem(wsLabel, wsValue);
}
}
m_bindItems.RemoveAll();
}
void CXFA_FFDocView::SetChangeMark() {
if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) {
return;
}
m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
}
CXFA_Node* CXFA_FFDocView::GetRootSubform() {
CXFA_Node* pFormPacketNode =
ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
if (!pFormPacketNode) {
return NULL;
}
return pFormPacketNode->GetFirstChildByClass(XFA_ELEMENT_Subform);
}
CXFA_FFDocWidgetIterator::CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView,
CXFA_Node* pTravelRoot)
: m_ContentIterator(pTravelRoot) {
m_pDocView = pDocView;
m_pCurWidget = NULL;
}
CXFA_FFDocWidgetIterator::~CXFA_FFDocWidgetIterator() {}
void CXFA_FFDocWidgetIterator::Reset() {
m_ContentIterator.Reset();
m_pCurWidget = NULL;
}
IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToFirst() {
return NULL;
}
IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToLast() {
return NULL;
}
IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToNext() {
CXFA_Node* pItem = m_pCurWidget ? m_ContentIterator.MoveToNext()
: m_ContentIterator.GetCurrent();
while (pItem) {
if (CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData()) {
while ((m_pCurWidget = pAcc->GetNextWidget(NULL)) != NULL) {
if (!m_pCurWidget->IsLoaded() &&
(m_pCurWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
m_pCurWidget->LoadWidget();
}
return m_pCurWidget;
}
}
pItem = m_ContentIterator.MoveToNext();
}
return NULL;
}
IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToPrevious() {
return NULL;
}
IXFA_Widget* CXFA_FFDocWidgetIterator::GetCurrentWidget() {
return NULL;
}
FX_BOOL CXFA_FFDocWidgetIterator::SetCurrentWidget(IXFA_Widget* hWidget) {
return FALSE;
}
IXFA_WidgetAccIterator* XFA_WidgetAccIterator_Create(
CXFA_WidgetAcc* pTravelRoot,
XFA_WIDGETORDER eOrder) {
if (!pTravelRoot) {
return NULL;
}
return new CXFA_WidgetAccIterator(pTravelRoot->GetDocView(),
pTravelRoot->GetNode());
}
CXFA_WidgetAccIterator::CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView,
CXFA_Node* pTravelRoot)
: m_ContentIterator(pTravelRoot) {
m_pDocView = pDocView;
m_pCurWidgetAcc = NULL;
}
CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator() {}
void CXFA_WidgetAccIterator::Reset() {
m_pCurWidgetAcc = NULL;
m_ContentIterator.Reset();
}
CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst() {
return NULL;
}
CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast() {
return NULL;
}
CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToNext() {
CXFA_Node* pItem = m_pCurWidgetAcc ? m_ContentIterator.MoveToNext()
: m_ContentIterator.GetCurrent();
while (pItem) {
if ((m_pCurWidgetAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData()) != NULL) {
return m_pCurWidgetAcc;
}
pItem = m_ContentIterator.MoveToNext();
}
return NULL;
}
CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious() {
return NULL;
}
CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc() {
return NULL;
}
FX_BOOL CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) {
return FALSE;
}
void CXFA_WidgetAccIterator::SkipTree() {
m_ContentIterator.SkipChildrenAndMoveToNext();
m_pCurWidgetAcc = NULL;
}