From a1cef70c08a16e2b9d7ec14987a8b20660d83534 Mon Sep 17 00:00:00 2001 From: jinming_wang Date: Fri, 18 Mar 2016 16:35:40 +0800 Subject: Trigger page view event when re-layout is finished BUG=pdfium:401 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1758553003 . --- fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp | 60 ++++++++++++++++++++++++----------- fpdfsdk/fsdk_mgr.cpp | 7 ++++ fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h | 9 ++++++ fpdfsdk/include/fsdk_mgr.h | 4 +-- public/fpdf_formfill.h | 15 +++++++-- xfa/fxfa/app/xfa_ffdocview.cpp | 4 +++ xfa/include/fxfa/fxfa.h | 1 + 7 files changed, 77 insertions(+), 23 deletions(-) diff --git a/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp index 6e0edf646e..d13bbec6cf 100644 --- a/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp +++ b/fpdfsdk/fpdfxfa/fpdfxfa_doc.cpp @@ -44,9 +44,13 @@ CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc, m_pXFADoc(nullptr), m_pXFADocView(nullptr), m_pApp(pProvider), - m_pJSContext(nullptr) {} + m_pJSContext(nullptr), + m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), + m_nPageCount(0) {} CPDFXFA_Document::~CPDFXFA_Document() { + m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; + if (m_pXFADoc) { IXFA_App* pApp = m_pApp->GetXFAApp(); if (pApp) { @@ -67,9 +71,13 @@ CPDFXFA_Document::~CPDFXFA_Document() { else delete m_pPDFDoc; } + + m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; } FX_BOOL CPDFXFA_Document::LoadXFADoc() { + m_nLoadStatus = FXFA_LOADSTATUS_LOADING; + if (!m_pPDFDoc) return FALSE; @@ -115,6 +123,8 @@ FX_BOOL CPDFXFA_Document::LoadXFADoc() { m_pXFADocView->DoLayout(NULL); m_pXFADocView->StopLayout(); + m_nLoadStatus = FXFA_LOADSTATUS_LOADED; + return TRUE; } @@ -147,7 +157,8 @@ CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) { if (pPage) pPage->AddRef(); } else { - m_XFAPageList.SetSize(GetPageCount()); + m_nPageCount = GetPageCount(); + m_XFAPageList.SetSize(m_nPageCount); } if (pPage) return pPage; @@ -480,25 +491,38 @@ FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget, void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags) { - if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded && - dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) { - return; - } - CPDFXFA_Page* pPage = nullptr; CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); - if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) { - int nPageIndex = pPageView->GetPageViewIndex(); - pPage = GetPage(nPageIndex); - if (pPage) - pPage->SetXFAPageView(pPageView); - pEnv->FFI_PageEvent(nPageIndex, dwFlags); + if (!pEnv) return; + + if (m_nLoadStatus != FXFA_LOADSTATUS_LOADING && + m_nLoadStatus != FXFA_LOADSTATUS_CLOSING && + XFA_PAGEVIEWEVENT_StopLayout == dwFlags) { + int nNewCount = GetPageCount(); + if (nNewCount == m_nPageCount) + return; + + IXFA_DocView* pXFADocView = GetXFADocView(); + if (!pXFADocView) + return; + for (int iPageIter = 0; iPageIter < m_nPageCount; iPageIter++) { + CPDFXFA_Page* pPage = m_XFAPageList.GetAt(iPageIter); + if (!pPage) + continue; + m_pSDKDoc->RemovePageView(pPage); + IXFA_PageView* pXFAPageView = pXFADocView->GetPageView(iPageIter); + pPage->SetXFAPageView(pXFAPageView); + if (pXFAPageView) + pXFAPageView->LoadPageView(nullptr); + } + + int flag = (nNewCount < m_nPageCount) ? FXFA_PAGEVIEWEVENT_POSTREMOVED + : FXFA_PAGEVIEWEVENT_POSTADDED; + int count = FXSYS_abs(nNewCount - m_nPageCount); + m_nPageCount = nNewCount; + m_XFAPageList.SetSize(nNewCount); + pEnv->FFI_PageEvent(count, flag); } - pPage = GetPage(pPageView); - if (!pPage) - return; - pEnv->FFI_PageEvent(pPage->GetPageIndex(), dwFlags); - pPage->Release(); } void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget, diff --git a/fpdfsdk/fsdk_mgr.cpp b/fpdfsdk/fsdk_mgr.cpp index 423bb8263a..1ff1ca7ca3 100644 --- a/fpdfsdk/fsdk_mgr.cpp +++ b/fpdfsdk/fsdk_mgr.cpp @@ -858,6 +858,13 @@ FX_BOOL CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) { pPage->GetDocument()->GetDocType() != DOCTYPE_DYNAMIC_XFA)) return FALSE; + if (GetFocusAnnot() == pAnnot) + KillFocusAnnot(); + CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); + CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr(); + if (pAnnotHandler) + pAnnotHandler->ReleaseAnnot(pAnnot); + auto it = std::find(m_fxAnnotArray.begin(), m_fxAnnotArray.end(), pAnnot); if (it != m_fxAnnotArray.end()) m_fxAnnotArray.erase(it); diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h index 55310e5615..5186fe51ab 100644 --- a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h +++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h @@ -204,6 +204,13 @@ class CPDFXFA_Document : public IXFA_DocProvider { void _ClearChangeMark(); private: + enum LoadStatus { + FXFA_LOADSTATUS_PRELOAD = 0, + FXFA_LOADSTATUS_LOADING, + FXFA_LOADSTATUS_LOADED, + FXFA_LOADSTATUS_CLOSING, + FXFA_LOADSTATUS_CLOSED + }; void CloseXFADoc(IXFA_DocHandler* pDoc) { if (pDoc) { pDoc->CloseDoc(m_pXFADoc); @@ -221,6 +228,8 @@ class CPDFXFA_Document : public IXFA_DocProvider { CPDFXFA_App* m_pApp; IJS_Context* m_pJSContext; CFX_ArrayTemplate m_XFAPageList; + LoadStatus m_nLoadStatus; + int m_nPageCount; }; #endif // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_DOC_H_ diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h index 88b539f7e7..b80e797f18 100644 --- a/fpdfsdk/include/fsdk_mgr.h +++ b/fpdfsdk/include/fsdk_mgr.h @@ -398,9 +398,9 @@ class CPDFDoc_Environment final { return L""; } - void FFI_PageEvent(int iPageIndex, FX_DWORD dwEventType) const { + void FFI_PageEvent(int iPageCount, FX_DWORD dwEventType) const { if (m_pInfo && m_pInfo->FFI_PageEvent) - m_pInfo->FFI_PageEvent(m_pInfo, iPageIndex, dwEventType); + m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType); } #endif // PDF_ENABLE_XFA diff --git a/public/fpdf_formfill.h b/public/fpdf_formfill.h index 81d6b691f0..90d6663137 100644 --- a/public/fpdf_formfill.h +++ b/public/fpdf_formfill.h @@ -823,20 +823,29 @@ typedef struct _FPDF_FORMFILLINFO { /** * Method: FFI_PageEvent - * This method fires when pages have been added or deleted. + * This method fires when pages have been added to or deleted from the XFA + * document. * Interface Version: * 2 * Implementation Required: * yes * Parameters: * pThis - Pointer to the interface structure itself. - * page_index - 0-based page number. + * page_count - The number of pages to be added to or deleted from the + * document. * event_type - See FXFA_PAGEVIEWEVENT_* above. * Return value: * None. + * Comments: + * The pages to be added or deleted always start from the last page + * of document. This means that if parameter page_count is 2 and + * event type is FXFA_PAGEVIEWEVENT_POSTADDED, 2 new pages have been + * appended to the tail of document; If page_count is 2 and + * event type is FXFA_PAGEVIEWEVENT_POSTREMOVED, the last 2 pages + * have been deleted. **/ void (*FFI_PageEvent)(struct _FPDF_FORMFILLINFO* pThis, - int page_index, + int page_count, FPDF_DWORD event_type); /** diff --git a/xfa/fxfa/app/xfa_ffdocview.cpp b/xfa/fxfa/app/xfa_ffdocview.cpp index 082ca2bbaa..64d4b2375e 100644 --- a/xfa/fxfa/app/xfa_ffdocview.cpp +++ b/xfa/fxfa/app/xfa_ffdocview.cpp @@ -599,9 +599,13 @@ FX_BOOL CXFA_FFDocView::RunLayout() { m_pXFADocLayout->DoLayout(); UnlockUpdate(); m_bInLayoutStatus = FALSE; + m_pDoc->GetDocProvider()->PageViewEvent(nullptr, + XFA_PAGEVIEWEVENT_StopLayout); return TRUE; } m_bInLayoutStatus = FALSE; + m_pDoc->GetDocProvider()->PageViewEvent(nullptr, + XFA_PAGEVIEWEVENT_StopLayout); UnlockUpdate(); return FALSE; } diff --git a/xfa/include/fxfa/fxfa.h b/xfa/include/fxfa/fxfa.h index 191056cd82..5e9dd0dde8 100644 --- a/xfa/include/fxfa/fxfa.h +++ b/xfa/include/fxfa/fxfa.h @@ -354,6 +354,7 @@ class IXFA_MenuHandler { #define XFA_PRINTOPT_PrintAnnot 0x00000020 #define XFA_PAGEVIEWEVENT_PostAdded 1 #define XFA_PAGEVIEWEVENT_PostRemoved 3 +#define XFA_PAGEVIEWEVENT_StopLayout 4 #define XFA_WIDGETEVENT_PostAdded 2 #define XFA_WIDGETEVENT_PreRemoved 3 #define XFA_WIDGETEVENT_PostContentChanged 6 -- cgit v1.2.3