summaryrefslogtreecommitdiff
path: root/xfa/src/fxfa/src/app/xfa_ffpageview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fxfa/src/app/xfa_ffpageview.cpp')
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpageview.cpp428
1 files changed, 428 insertions, 0 deletions
diff --git a/xfa/src/fxfa/src/app/xfa_ffpageview.cpp b/xfa/src/fxfa/src/app/xfa_ffpageview.cpp
new file mode 100644
index 0000000000..ec591adb72
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpageview.cpp
@@ -0,0 +1,428 @@
+// 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 "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.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"
+CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
+ : CXFA_ContainerLayoutItemImpl(pPageArea)
+ , m_pDocView(pDocView)
+ , m_bLoaded(FALSE)
+{
+}
+CXFA_FFPageView::~CXFA_FFPageView()
+{
+}
+IXFA_DocView* CXFA_FFPageView::GetDocView()
+{
+ return m_pDocView;
+}
+FX_INT32 CXFA_FFPageView::GetPageViewIndex()
+{
+ return GetLayoutPage()->GetPageIndex();
+}
+void CXFA_FFPageView::GetPageViewRect(CFX_RectF &rtPage)
+{
+ CFX_SizeF sz;
+ GetLayoutPage()->GetPageSize(sz);
+ rtPage.Set(0, 0, sz);
+}
+void CXFA_FFPageView::GetDisplayMatrix(CFX_Matrix &mt, const CFX_Rect &rtDisp, FX_INT32 iRotate)
+{
+ CFX_SizeF sz;
+ GetLayoutPage()->GetPageSize(sz);
+ CFX_RectF fdePage;
+ fdePage.Set(0, 0, sz.x, sz.y);
+ FDE_GetPageMatrix(mt, fdePage, rtDisp, iRotate, 0);
+}
+FX_INT32 CXFA_FFPageView::LoadPageView(IFX_Pause *pPause )
+{
+ if (m_bLoaded) {
+ return 100;
+ }
+ m_bLoaded = TRUE;
+ return 100;
+}
+void CXFA_FFPageView::UnloadPageView()
+{
+ if (!m_bLoaded) {
+ return;
+ }
+}
+FX_BOOL CXFA_FFPageView::IsPageViewLoaded()
+{
+ return m_bLoaded;
+}
+XFA_HWIDGET CXFA_FFPageView::GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_bLoaded) {
+ return NULL;
+ }
+ IXFA_WidgetIterator* pIterator = CreateWidgetIterator();
+ while (CXFA_FFWidget* pWidget = (CXFA_FFWidget*)pIterator->MoveToNext()) {
+ if (!(pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ continue;
+ }
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ FX_INT32 type = pAcc->GetClassID();
+ if (type != XFA_ELEMENT_Field && type != XFA_ELEMENT_Draw) {
+ continue;
+ }
+ FX_FLOAT fWidgetx = fx, fWidgety = fy;
+ pWidget->Rotate2Normal(fWidgetx, fWidgety);
+ FX_DWORD dwFlag = pWidget->OnHitTest(fWidgetx, fWidgety);
+ if (( FWL_WGTHITTEST_Client == dwFlag
+ || FWL_WGTHITTEST_Transparent == dwFlag)) {
+ pIterator->Release();
+ return (XFA_HWIDGET)pWidget;
+ }
+ }
+ pIterator->Release();
+ return NULL;
+}
+IXFA_WidgetIterator* CXFA_FFPageView::CreateWidgetIterator(FX_DWORD dwTraverseWay ,
+ FX_DWORD dwWidgetFilter )
+{
+ switch (dwTraverseWay) {
+ case XFA_TRAVERSEWAY_Tranvalse:
+ return FX_NEW CXFA_FFTabOrderPageWidgetIterator(this, dwWidgetFilter);
+ case XFA_TRAVERSEWAY_Form:
+ return FX_NEW CXFA_FFPageWidgetIterator(this, dwWidgetFilter);
+ }
+ return NULL;
+}
+static FX_BOOL XFA_PageWidgetFilter(CXFA_FFWidget* pWidget, FX_DWORD dwFilter, FX_BOOL bTraversal, FX_BOOL bIgnorerelevant)
+{
+ CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+ FX_DWORD dwType = dwFilter & XFA_WIDGETFILTER_AllType;
+ if ((dwType == XFA_WIDGETFILTER_Field) && (pWidgetAcc->GetClassID() != XFA_ELEMENT_Field)) {
+ return FALSE;
+ }
+ FX_DWORD dwStatus = pWidget->GetStatus();
+ if (bTraversal && (dwStatus & XFA_WIDGETSTATUS_Disabled)) {
+ return FALSE;
+ }
+ if (bIgnorerelevant) {
+ return (dwStatus & XFA_WIDGETFILTER_Visible) != 0;
+ }
+ dwFilter &= (XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_Printable);
+ return (dwFilter & dwStatus) == dwFilter;
+}
+CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter)
+{
+ m_pPageView = pPageView;
+ m_dwFilter = dwFilter;
+ m_sIterator.Init((CXFA_LayoutItem*)pPageView->GetLayoutPage());
+ m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())->GetXFADoc()->GetCurVersionMode() < XFA_VERSION_205;
+}
+CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator()
+{
+}
+void CXFA_FFPageWidgetIterator::Reset()
+{
+ m_sIterator.Reset();
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToFirst()
+{
+ m_sIterator.Reset();
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem; pLayoutItem = m_sIterator.MoveToNext()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToLast()
+{
+ m_sIterator.SetCurrent(NULL);
+ return MoveToPrevious();
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToNext()
+{
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem; pLayoutItem = m_sIterator.MoveToNext()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToPrevious()
+{
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem; pLayoutItem = m_sIterator.MoveToPrev()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::GetCurrentWidget()
+{
+ CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
+ return pLayoutItem ? (XFA_HWIDGET)XFA_GetWidgetFromLayoutItem(pLayoutItem) : NULL;
+}
+FX_BOOL CXFA_FFPageWidgetIterator::SetCurrentWidget(XFA_HWIDGET hWidget)
+{
+ if(hWidget && m_sIterator.SetCurrent(((CXFA_FFWidget*)hWidget)->GetLayoutItem())) {
+ return TRUE;
+ }
+ return FALSE;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::GetWidget(CXFA_LayoutItem* pLayoutItem)
+{
+ if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+ if (!XFA_PageWidgetFilter(pWidget, m_dwFilter, FALSE, m_bIgnorerelevant)) {
+ return NULL;
+ }
+ if (!pWidget->IsLoaded() && (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible) != 0) {
+ pWidget->LoadWidget();
+ }
+ return (XFA_HWIDGET)pWidget;
+ }
+ return NULL;
+}
+CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter)
+ : m_pPageView(pPageView)
+ , m_dwFilter(dwFilter)
+ , m_iCurWidget(-1)
+{
+ m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())->GetXFADoc()->GetCurVersionMode() < XFA_VERSION_205;
+ Reset();
+}
+CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator()
+{
+}
+void CXFA_FFTabOrderPageWidgetIterator::Release()
+{
+ delete this;
+}
+void CXFA_FFTabOrderPageWidgetIterator::Reset()
+{
+ CreateTabOrderWidgetArray();
+ m_iCurWidget = -1;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToFirst()
+{
+ if (m_TabOrderWidgetArray.GetSize() > 0) {
+ for (FX_INT32 i = 0; i < m_TabOrderWidgetArray.GetSize(); i++) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToLast()
+{
+ if (m_TabOrderWidgetArray.GetSize() > 0) {
+ for (FX_INT32 i = m_TabOrderWidgetArray.GetSize() - 1; i >= 0; i--) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToNext()
+{
+ for (FX_INT32 i = m_iCurWidget + 1; i < m_TabOrderWidgetArray.GetSize(); i++) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ m_iCurWidget = -1;
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious()
+{
+ for (FX_INT32 i = m_iCurWidget - 1; i >= 0; i--) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ m_iCurWidget = -1;
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget()
+{
+ if (m_iCurWidget >= 0) {
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ return NULL;
+}
+FX_BOOL CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(XFA_HWIDGET hWidget)
+{
+ FX_INT32 iWidgetIndex = m_TabOrderWidgetArray.Find((CXFA_FFWidget*)hWidget);
+ if (iWidgetIndex >= 0) {
+ m_iCurWidget = iWidgetIndex;
+ return TRUE;
+ }
+ return FALSE;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(CXFA_FFWidget* pWidget)
+{
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_ELEMENT_Traversal);
+ if (pTraversal != NULL) {
+ CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_ELEMENT_Traverse);
+ if (pTraverse != NULL) {
+ CFX_WideString wsTraverseWidgetName;
+ if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
+ return FindWidgetByName(wsTraverseWidgetName, pWidget);
+ }
+ }
+ }
+ return NULL;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(FX_WSTR wsWidgetName, CXFA_FFWidget* pRefWidget)
+{
+ return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray()
+{
+ m_TabOrderWidgetArray.RemoveAll();
+ CXFA_WidgetArray SpaceOrderWidgetArray;
+ CreateSpaceOrderWidgetArray(SpaceOrderWidgetArray);
+ FX_INT32 nWidgetCount = SpaceOrderWidgetArray.GetSize();
+ if (nWidgetCount < 1) {
+ return;
+ }
+ CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
+ for (; m_TabOrderWidgetArray.GetSize() < nWidgetCount; ) {
+ if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+ m_TabOrderWidgetArray.Add(hWidget);
+ CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+ if (pWidgetAcc->GetUIType() == XFA_ELEMENT_ExclGroup) {
+ FX_INT32 iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget) + 1;
+ while (TRUE) {
+ CXFA_FFWidget* pRadio = SpaceOrderWidgetArray[(iWidgetIndex) % nWidgetCount];
+ if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
+ break;
+ }
+ if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+ m_TabOrderWidgetArray.Add(pRadio);
+ }
+ iWidgetIndex++;
+ }
+ }
+ if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
+ hWidget = hTraverseWidget;
+ continue;
+ }
+ }
+ FX_INT32 iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget);
+ hWidget = SpaceOrderWidgetArray[(iWidgetIndex + 1) % nWidgetCount];
+ }
+}
+static FX_INT32 XFA_TabOrderWidgetComparator(const void* phWidget1, const void* phWidget2)
+{
+ CXFA_FFWidget* pWidget1 = (*(CXFA_TabParam**)phWidget1)->m_pWidget;
+ CXFA_FFWidget* pWidget2 = (*(CXFA_TabParam**)phWidget2)->m_pWidget;
+ CFX_RectF rt1, rt2;
+ pWidget1->GetWidgetRect(rt1);
+ pWidget2->GetWidgetRect(rt2);
+ FX_FLOAT x1 = rt1.left, y1 = rt1.top, x2 = rt2.left, y2 = rt2.top;
+ if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) {
+ return -1;
+ }
+ return 1;
+}
+void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(CXFA_LayoutItemIterator* sIterator, CXFA_LayoutItem* pContainerItem, CXFA_TabParam* pContainer, FX_BOOL &bCurrentItem, FX_BOOL& bContentArea, FX_BOOL bMarsterPage)
+{
+ CFX_PtrArray tabParams;
+ CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
+ while(pSearchItem) {
+ FX_BOOL bIsContentLayoutItem = ((CXFA_LayoutItemImpl*)pSearchItem)->IsContentLayoutItem();
+ if(!bIsContentLayoutItem) {
+ bContentArea = TRUE;
+ pSearchItem = sIterator->MoveToNext();
+ continue;
+ }
+ if (bMarsterPage && bContentArea) {
+ break;
+ }
+ if (bMarsterPage || bContentArea) {
+ CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
+ if (!hWidget) {
+ pSearchItem = sIterator->MoveToNext();
+ continue;
+ }
+ if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
+ bCurrentItem = TRUE;
+ break;
+ }
+ CXFA_TabParam* pParam = FX_NEW CXFA_TabParam;
+ pParam->m_pWidget = hWidget;
+ tabParams.Add(pParam);
+ if (XFA_IsLayoutElement(pSearchItem->GetFormNode()->GetClassID(), TRUE)) {
+ OrderContainer(sIterator, pSearchItem, pParam, bCurrentItem, bContentArea, bMarsterPage);
+ }
+ }
+ if (bCurrentItem) {
+ pSearchItem = sIterator->GetCurrent();
+ bCurrentItem = FALSE;
+ } else {
+ pSearchItem = sIterator->MoveToNext();
+ }
+ }
+ FX_INT32 iChildren = tabParams.GetSize();
+ if (iChildren > 1) {
+ FXSYS_qsort(tabParams.GetData(), iChildren, sizeof(FX_LPVOID), XFA_TabOrderWidgetComparator);
+ }
+ for (FX_INT32 iStart = 0; iStart < iChildren; iStart++) {
+ CXFA_TabParam* pParam = (CXFA_TabParam*)tabParams[iStart];
+ pContainer->m_Children.Add(pParam->m_pWidget);
+ if (pParam->m_Children.GetSize() > 0) {
+ pContainer->m_Children.Append(pParam->m_Children);
+ }
+ delete pParam;
+ }
+ tabParams.RemoveAll();
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(CXFA_WidgetArray& WidgetArray)
+{
+ CXFA_LayoutItemIterator sIterator;
+ sIterator.Init((CXFA_LayoutItem*)m_pPageView->GetLayoutPage());
+ CXFA_TabParam* pParam = FX_NEW CXFA_TabParam;
+ FX_BOOL bCurrentItem = FALSE;
+ FX_BOOL bContentArea = FALSE;
+ OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea);
+ if (pParam->m_Children.GetSize() > 0) {
+ WidgetArray.Append(pParam->m_Children);
+ }
+ sIterator.Reset();
+ bCurrentItem = FALSE;
+ bContentArea = FALSE;
+ pParam->m_Children.RemoveAll();
+ OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea, TRUE);
+ if (pParam->m_Children.GetSize() > 0) {
+ WidgetArray.Append(pParam->m_Children);
+ }
+ delete pParam;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(CXFA_LayoutItem* pLayoutItem)
+{
+ if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+ if (!pWidget->IsLoaded() && (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ pWidget->LoadWidget();
+ }
+ return pWidget;
+ }
+ return NULL;
+}