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_ffpageview.h"
     11 #include "xfa_ffwidget.h"
     12 #include "xfa_ffdoc.h"
     13 #include "xfa_ffdocview.h"
     14 #include "xfa_fffield.h"
     15 #include "xfa_ffpushbutton.h"
     16 #include "xfa_ffcheckbutton.h"
     17 #include "xfa_ffchoicelist.h"
     18 #include "xfa_ffimageedit.h"
     19 #include "xfa_fftextedit.h"
     20 CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
     21     : CXFA_ContainerLayoutItem(pPageArea),
     22       m_pDocView(pDocView),
     23       m_bLoaded(FALSE) {}
     24 CXFA_FFPageView::~CXFA_FFPageView() {}
     25 IXFA_DocView* CXFA_FFPageView::GetDocView() {
     26   return m_pDocView;
     27 }
     28 int32_t CXFA_FFPageView::GetPageViewIndex() {
     29   return GetPageIndex();
     30 }
     31 void CXFA_FFPageView::GetPageViewRect(CFX_RectF& rtPage) {
     32   CFX_SizeF sz;
     33   GetPageSize(sz);
     34   rtPage.Set(0, 0, sz);
     35 }
     36 void CXFA_FFPageView::GetDisplayMatrix(CFX_Matrix& mt,
     37                                        const CFX_Rect& rtDisp,
     38                                        int32_t iRotate) {
     39   CFX_SizeF sz;
     40   GetPageSize(sz);
     41   CFX_RectF fdePage;
     42   fdePage.Set(0, 0, sz.x, sz.y);
     43   FDE_GetPageMatrix(mt, fdePage, rtDisp, iRotate, 0);
     44 }
     45 int32_t CXFA_FFPageView::LoadPageView(IFX_Pause* pPause) {
     46   if (m_bLoaded) {
     47     return 100;
     48   }
     49   m_bLoaded = TRUE;
     50   return 100;
     51 }
     52 void CXFA_FFPageView::UnloadPageView() {
     53   if (!m_bLoaded) {
     54     return;
     55   }
     56 }
     57 FX_BOOL CXFA_FFPageView::IsPageViewLoaded() {
     58   return m_bLoaded;
     59 }
     60 IXFA_Widget* CXFA_FFPageView::GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy) {
     61   if (!m_bLoaded) {
     62     return nullptr;
     63   }
     64   IXFA_WidgetIterator* pIterator = CreateWidgetIterator();
     65   CXFA_FFWidget* pWidget = nullptr;
     66   while ((pWidget = static_cast<CXFA_FFWidget*>(pIterator->MoveToNext()))) {
     67     if (!(pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
     68       continue;
     69     }
     70     CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
     71     int32_t type = pAcc->GetClassID();
     72     if (type != XFA_ELEMENT_Field && type != XFA_ELEMENT_Draw) {
     73       continue;
     74     }
     75     FX_FLOAT fWidgetx = fx;
     76     FX_FLOAT fWidgety = fy;
     77     pWidget->Rotate2Normal(fWidgetx, fWidgety);
     78     FX_DWORD dwFlag = pWidget->OnHitTest(fWidgetx, fWidgety);
     79     if ((FWL_WGTHITTEST_Client == dwFlag ||
     80          FWL_WGTHITTEST_HyperLink == dwFlag)) {
     81       break;
     82     }
     83   }
     84   pIterator->Release();
     85   return pWidget;
     86 }
     87 IXFA_WidgetIterator* CXFA_FFPageView::CreateWidgetIterator(
     88     FX_DWORD dwTraverseWay,
     89     FX_DWORD dwWidgetFilter) {
     90   switch (dwTraverseWay) {
     91     case XFA_TRAVERSEWAY_Tranvalse:
     92       return new CXFA_FFTabOrderPageWidgetIterator(this, dwWidgetFilter);
     93     case XFA_TRAVERSEWAY_Form:
     94       return new CXFA_FFPageWidgetIterator(this, dwWidgetFilter);
     95   }
     96   return NULL;
     97 }
     98 static FX_BOOL XFA_PageWidgetFilter(CXFA_FFWidget* pWidget,
     99                                     FX_DWORD dwFilter,
    100                                     FX_BOOL bTraversal,
    101                                     FX_BOOL bIgnorerelevant) {
    102   CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
    103   FX_DWORD dwType = dwFilter & XFA_WIDGETFILTER_AllType;
    104   if ((dwType == XFA_WIDGETFILTER_Field) &&
    105       (pWidgetAcc->GetClassID() != XFA_ELEMENT_Field)) {
    106     return FALSE;
    107   }
    108   FX_DWORD dwStatus = pWidget->GetStatus();
    109   if (bTraversal && (dwStatus & XFA_WIDGETSTATUS_Disabled)) {
    110     return FALSE;
    111   }
    112   if (bIgnorerelevant) {
    113     return (dwStatus & XFA_WIDGETFILTER_Visible) != 0;
    114   }
    115   dwFilter &= (XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable |
    116                XFA_WIDGETFILTER_Printable);
    117   return (dwFilter & dwStatus) == dwFilter;
    118 }
    119 CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView,
    120                                                      FX_DWORD dwFilter) {
    121   m_pPageView = pPageView;
    122   m_dwFilter = dwFilter;
    123   m_sIterator.Init(pPageView);
    124   m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())
    125                           ->GetXFADoc()
    126                           ->GetCurVersionMode() < XFA_VERSION_205;
    127 }
    128 CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator() {}
    129 void CXFA_FFPageWidgetIterator::Reset() {
    130   m_sIterator.Reset();
    131 }
    132 IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToFirst() {
    133   m_sIterator.Reset();
    134   for (CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem;
    135        pLayoutItem = m_sIterator.MoveToNext()) {
    136     if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
    137       return hWidget;
    138     }
    139   }
    140   return NULL;
    141 }
    142 IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToLast() {
    143   m_sIterator.SetCurrent(NULL);
    144   return MoveToPrevious();
    145 }
    146 IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToNext() {
    147   for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem;
    148        pLayoutItem = m_sIterator.MoveToNext()) {
    149     if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
    150       return hWidget;
    151     }
    152   }
    153   return NULL;
    154 }
    155 IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToPrevious() {
    156   for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem;
    157        pLayoutItem = m_sIterator.MoveToPrev()) {
    158     if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
    159       return hWidget;
    160     }
    161   }
    162   return NULL;
    163 }
    164 IXFA_Widget* CXFA_FFPageWidgetIterator::GetCurrentWidget() {
    165   CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
    166   return pLayoutItem ? XFA_GetWidgetFromLayoutItem(pLayoutItem) : NULL;
    167 }
    168 FX_BOOL CXFA_FFPageWidgetIterator::SetCurrentWidget(IXFA_Widget* hWidget) {
    169   CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(hWidget);
    170   return pWidget && m_sIterator.SetCurrent(pWidget);
    171 }
    172 IXFA_Widget* CXFA_FFPageWidgetIterator::GetWidget(
    173     CXFA_LayoutItem* pLayoutItem) {
    174   if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
    175     if (!XFA_PageWidgetFilter(pWidget, m_dwFilter, FALSE, m_bIgnorerelevant)) {
    176       return NULL;
    177     }
    178     if (!pWidget->IsLoaded() &&
    179         (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible) != 0) {
    180       pWidget->LoadWidget();
    181     }
    182     return pWidget;
    183   }
    184   return NULL;
    185 }
    186 CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(
    187     CXFA_FFPageView* pPageView,
    188     FX_DWORD dwFilter)
    189     : m_pPageView(pPageView), m_dwFilter(dwFilter), m_iCurWidget(-1) {
    190   m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())
    191                           ->GetXFADoc()
    192                           ->GetCurVersionMode() < XFA_VERSION_205;
    193   Reset();
    194 }
    195 CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator() {}
    196 void CXFA_FFTabOrderPageWidgetIterator::Release() {
    197   delete this;
    198 }
    199 void CXFA_FFTabOrderPageWidgetIterator::Reset() {
    200   CreateTabOrderWidgetArray();
    201   m_iCurWidget = -1;
    202 }
    203 IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToFirst() {
    204   if (m_TabOrderWidgetArray.GetSize() > 0) {
    205     for (int32_t i = 0; i < m_TabOrderWidgetArray.GetSize(); i++) {
    206       if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
    207                                m_bIgnorerelevant)) {
    208         m_iCurWidget = i;
    209         return m_TabOrderWidgetArray[m_iCurWidget];
    210       }
    211     }
    212   }
    213   return NULL;
    214 }
    215 IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToLast() {
    216   if (m_TabOrderWidgetArray.GetSize() > 0) {
    217     for (int32_t i = m_TabOrderWidgetArray.GetSize() - 1; i >= 0; i--) {
    218       if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
    219                                m_bIgnorerelevant)) {
    220         m_iCurWidget = i;
    221         return m_TabOrderWidgetArray[m_iCurWidget];
    222       }
    223     }
    224   }
    225   return NULL;
    226 }
    227 IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() {
    228   for (int32_t i = m_iCurWidget + 1; i < m_TabOrderWidgetArray.GetSize(); i++) {
    229     if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
    230                              m_bIgnorerelevant)) {
    231       m_iCurWidget = i;
    232       return m_TabOrderWidgetArray[m_iCurWidget];
    233     }
    234   }
    235   m_iCurWidget = -1;
    236   return NULL;
    237 }
    238 IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() {
    239   for (int32_t i = m_iCurWidget - 1; i >= 0; i--) {
    240     if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
    241                              m_bIgnorerelevant)) {
    242       m_iCurWidget = i;
    243       return m_TabOrderWidgetArray[m_iCurWidget];
    244     }
    245   }
    246   m_iCurWidget = -1;
    247   return NULL;
    248 }
    249 IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget() {
    250   if (m_iCurWidget >= 0) {
    251     return m_TabOrderWidgetArray[m_iCurWidget];
    252   }
    253   return NULL;
    254 }
    255 FX_BOOL CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(
    256     IXFA_Widget* hWidget) {
    257   int32_t iWidgetIndex =
    258       m_TabOrderWidgetArray.Find(static_cast<CXFA_FFWidget*>(hWidget));
    259   if (iWidgetIndex >= 0) {
    260     m_iCurWidget = iWidgetIndex;
    261     return TRUE;
    262   }
    263   return FALSE;
    264 }
    265 CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(
    266     CXFA_FFWidget* pWidget) {
    267   CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
    268   CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_ELEMENT_Traversal);
    269   if (pTraversal != NULL) {
    270     CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_ELEMENT_Traverse);
    271     if (pTraverse != NULL) {
    272       CFX_WideString wsTraverseWidgetName;
    273       if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
    274         return FindWidgetByName(wsTraverseWidgetName, pWidget);
    275       }
    276     }
    277   }
    278   return NULL;
    279 }
    280 CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(
    281     const CFX_WideStringC& wsWidgetName,
    282     CXFA_FFWidget* pRefWidget) {
    283   return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
    284 }
    285 void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
    286   m_TabOrderWidgetArray.RemoveAll();
    287   CXFA_WidgetArray SpaceOrderWidgetArray;
    288   CreateSpaceOrderWidgetArray(SpaceOrderWidgetArray);
    289   int32_t nWidgetCount = SpaceOrderWidgetArray.GetSize();
    290   if (nWidgetCount < 1) {
    291     return;
    292   }
    293   CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
    294   for (; m_TabOrderWidgetArray.GetSize() < nWidgetCount;) {
    295     if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
    296       m_TabOrderWidgetArray.Add(hWidget);
    297       CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
    298       if (pWidgetAcc->GetUIType() == XFA_ELEMENT_ExclGroup) {
    299         int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget) + 1;
    300         while (TRUE) {
    301           CXFA_FFWidget* pRadio =
    302               SpaceOrderWidgetArray[(iWidgetIndex) % nWidgetCount];
    303           if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
    304             break;
    305           }
    306           if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
    307             m_TabOrderWidgetArray.Add(pRadio);
    308           }
    309           iWidgetIndex++;
    310         }
    311       }
    312       if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
    313         hWidget = hTraverseWidget;
    314         continue;
    315       }
    316     }
    317     int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget);
    318     hWidget = SpaceOrderWidgetArray[(iWidgetIndex + 1) % nWidgetCount];
    319   }
    320 }
    321 static int32_t XFA_TabOrderWidgetComparator(const void* phWidget1,
    322                                             const void* phWidget2) {
    323   CXFA_FFWidget* pWidget1 = (*(CXFA_TabParam**)phWidget1)->m_pWidget;
    324   CXFA_FFWidget* pWidget2 = (*(CXFA_TabParam**)phWidget2)->m_pWidget;
    325   CFX_RectF rt1, rt2;
    326   pWidget1->GetWidgetRect(rt1);
    327   pWidget2->GetWidgetRect(rt2);
    328   FX_FLOAT x1 = rt1.left, y1 = rt1.top, x2 = rt2.left, y2 = rt2.top;
    329   if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) {
    330     return -1;
    331   }
    332   return 1;
    333 }
    334 void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(
    335     CXFA_LayoutItemIterator* sIterator,
    336     CXFA_LayoutItem* pContainerItem,
    337     CXFA_TabParam* pContainer,
    338     FX_BOOL& bCurrentItem,
    339     FX_BOOL& bContentArea,
    340     FX_BOOL bMarsterPage) {
    341   CFX_PtrArray tabParams;
    342   CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
    343   while (pSearchItem) {
    344     if (!pSearchItem->IsContentLayoutItem()) {
    345       bContentArea = TRUE;
    346       pSearchItem = sIterator->MoveToNext();
    347       continue;
    348     }
    349     if (bMarsterPage && bContentArea) {
    350       break;
    351     }
    352     if (bMarsterPage || bContentArea) {
    353       CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
    354       if (!hWidget) {
    355         pSearchItem = sIterator->MoveToNext();
    356         continue;
    357       }
    358       if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
    359         bCurrentItem = TRUE;
    360         break;
    361       }
    362       CXFA_TabParam* pParam = new CXFA_TabParam;
    363       pParam->m_pWidget = hWidget;
    364       tabParams.Add(pParam);
    365       if (XFA_IsLayoutElement(pSearchItem->GetFormNode()->GetClassID(), TRUE)) {
    366         OrderContainer(sIterator, pSearchItem, pParam, bCurrentItem,
    367                        bContentArea, bMarsterPage);
    368       }
    369     }
    370     if (bCurrentItem) {
    371       pSearchItem = sIterator->GetCurrent();
    372       bCurrentItem = FALSE;
    373     } else {
    374       pSearchItem = sIterator->MoveToNext();
    375     }
    376   }
    377   int32_t iChildren = tabParams.GetSize();
    378   if (iChildren > 1) {
    379     FXSYS_qsort(tabParams.GetData(), iChildren, sizeof(void*),
    380                 XFA_TabOrderWidgetComparator);
    381   }
    382   for (int32_t iStart = 0; iStart < iChildren; iStart++) {
    383     CXFA_TabParam* pParam = (CXFA_TabParam*)tabParams[iStart];
    384     pContainer->m_Children.Add(pParam->m_pWidget);
    385     if (pParam->m_Children.GetSize() > 0) {
    386       pContainer->m_Children.Append(pParam->m_Children);
    387     }
    388     delete pParam;
    389   }
    390   tabParams.RemoveAll();
    391 }
    392 void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(
    393     CXFA_WidgetArray& WidgetArray) {
    394   CXFA_LayoutItemIterator sIterator;
    395   sIterator.Init(m_pPageView);
    396   CXFA_TabParam* pParam = new CXFA_TabParam;
    397   FX_BOOL bCurrentItem = FALSE;
    398   FX_BOOL bContentArea = FALSE;
    399   OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea);
    400   if (pParam->m_Children.GetSize() > 0) {
    401     WidgetArray.Append(pParam->m_Children);
    402   }
    403   sIterator.Reset();
    404   bCurrentItem = FALSE;
    405   bContentArea = FALSE;
    406   pParam->m_Children.RemoveAll();
    407   OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea, TRUE);
    408   if (pParam->m_Children.GetSize() > 0) {
    409     WidgetArray.Append(pParam->m_Children);
    410   }
    411   delete pParam;
    412 }
    413 CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(
    414     CXFA_LayoutItem* pLayoutItem) {
    415   if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
    416     if (!pWidget->IsLoaded() &&
    417         (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
    418       pWidget->LoadWidget();
    419     }
    420     return pWidget;
    421   }
    422   return NULL;
    423 }
    424