blob: 0e0db8dae0d9cc4427e18709026c71351d0e35cd [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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
Dan Sinclair80c48782017-03-23 12:11:20 -04007#include "xfa/fxfa/cxfa_ffpageview.h"
Dan Sinclair1770c022016-03-14 14:14:16 -04008
Tom Sepezb8227822017-03-24 13:10:14 -07009#include <algorithm>
tsepeza0b2d232017-01-23 11:32:36 -080010#include <memory>
11#include <vector>
12
13#include "third_party/base/ptr_util.h"
14#include "third_party/base/stl_util.h"
Dan Sinclair24ef6332017-07-24 10:52:57 -040015#include "xfa/fxfa/cxfa_ffcheckbutton.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040016#include "xfa/fxfa/cxfa_ffdoc.h"
17#include "xfa/fxfa/cxfa_ffdocview.h"
Dan Sinclair24ef6332017-07-24 10:52:57 -040018#include "xfa/fxfa/cxfa_fffield.h"
19#include "xfa/fxfa/cxfa_ffimageedit.h"
20#include "xfa/fxfa/cxfa_ffpushbutton.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040021#include "xfa/fxfa/cxfa_ffwidget.h"
Dan Sinclair24ef6332017-07-24 10:52:57 -040022#include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
Dan Sinclairefcae5d2017-03-29 14:47:46 -040023#include "xfa/fxfa/parser/cxfa_node.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040024
dsinclairacd0d592016-04-21 11:06:27 -070025namespace {
26
Dan Sinclair1b08df12017-02-09 09:17:20 -050027CFX_Matrix GetPageMatrix(const CFX_RectF& docPageRect,
28 const CFX_Rect& devicePageRect,
29 int32_t iRotate,
30 uint32_t dwCoordinatesType) {
dsinclair43854a52016-04-27 12:26:00 -070031 ASSERT(iRotate >= 0 && iRotate <= 3);
Dan Sinclair1b08df12017-02-09 09:17:20 -050032
tsepezd19e9122016-11-02 15:43:18 -070033 bool bFlipX = (dwCoordinatesType & 0x01) != 0;
34 bool bFlipY = (dwCoordinatesType & 0x02) != 0;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050035 CFX_Matrix m((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0);
dsinclairacd0d592016-04-21 11:06:27 -070036 if (iRotate == 0 || iRotate == 2) {
Dan Sinclair05df0752017-03-14 14:43:42 -040037 m.a *= (float)devicePageRect.width / docPageRect.width;
38 m.d *= (float)devicePageRect.height / docPageRect.height;
dsinclairacd0d592016-04-21 11:06:27 -070039 } else {
Dan Sinclair05df0752017-03-14 14:43:42 -040040 m.a *= (float)devicePageRect.height / docPageRect.width;
41 m.d *= (float)devicePageRect.width / docPageRect.height;
dsinclairacd0d592016-04-21 11:06:27 -070042 }
43 m.Rotate(iRotate * 1.57079632675f);
44 switch (iRotate) {
45 case 0:
Dan Sinclair05df0752017-03-14 14:43:42 -040046 m.e = bFlipX ? (float)devicePageRect.right() : (float)devicePageRect.left;
47 m.f = bFlipY ? (float)devicePageRect.bottom() : (float)devicePageRect.top;
dsinclairacd0d592016-04-21 11:06:27 -070048 break;
49 case 1:
Dan Sinclair05df0752017-03-14 14:43:42 -040050 m.e = bFlipY ? (float)devicePageRect.left : (float)devicePageRect.right();
51 m.f = bFlipX ? (float)devicePageRect.bottom() : (float)devicePageRect.top;
dsinclairacd0d592016-04-21 11:06:27 -070052 break;
53 case 2:
Dan Sinclair05df0752017-03-14 14:43:42 -040054 m.e = bFlipX ? (float)devicePageRect.left : (float)devicePageRect.right();
55 m.f = bFlipY ? (float)devicePageRect.top : (float)devicePageRect.bottom();
dsinclairacd0d592016-04-21 11:06:27 -070056 break;
57 case 3:
Dan Sinclair05df0752017-03-14 14:43:42 -040058 m.e = bFlipY ? (float)devicePageRect.right() : (float)devicePageRect.left;
59 m.f = bFlipX ? (float)devicePageRect.top : (float)devicePageRect.bottom();
dsinclairacd0d592016-04-21 11:06:27 -070060 break;
61 default:
62 break;
63 }
Dan Sinclair1b08df12017-02-09 09:17:20 -050064 return m;
dsinclairacd0d592016-04-21 11:06:27 -070065}
66
dsinclair935d8d52016-05-17 10:32:18 -070067bool PageWidgetFilter(CXFA_FFWidget* pWidget,
68 uint32_t dwFilter,
tsepezd19e9122016-11-02 15:43:18 -070069 bool bTraversal,
70 bool bIgnorerelevant) {
dsinclair935d8d52016-05-17 10:32:18 -070071 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
72
73 if (!!(dwFilter & XFA_WidgetStatus_Focused) &&
dsinclair070fcdf2016-06-22 22:04:54 -070074 pWidgetAcc->GetElementType() != XFA_Element::Field) {
dsinclair935d8d52016-05-17 10:32:18 -070075 return false;
76 }
77
78 uint32_t dwStatus = pWidget->GetStatus();
79 if (bTraversal && (dwStatus & XFA_WidgetStatus_Disabled))
80 return false;
81 if (bIgnorerelevant)
82 return !!(dwStatus & XFA_WidgetStatus_Visible);
83
84 dwFilter &= (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable |
85 XFA_WidgetStatus_Printable);
86 return (dwFilter & dwStatus) == dwFilter;
87}
88
dsinclaird1cf2392016-07-11 06:46:59 -070089bool IsLayoutElement(XFA_Element eElement, bool bLayoutContainer) {
90 switch (eElement) {
91 case XFA_Element::Draw:
92 case XFA_Element::Field:
93 case XFA_Element::InstanceManager:
94 return !bLayoutContainer;
95 case XFA_Element::Area:
96 case XFA_Element::Subform:
97 case XFA_Element::ExclGroup:
98 case XFA_Element::SubformSet:
99 case XFA_Element::PageArea:
100 case XFA_Element::Form:
101 return true;
102 default:
103 return false;
104 }
105}
106
dsinclairacd0d592016-04-21 11:06:27 -0700107} // namespace
dsinclair935d8d52016-05-17 10:32:18 -0700108
Dan Sinclair1770c022016-03-14 14:14:16 -0400109CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
thestig9f3dbbc2016-04-13 13:18:21 -0700110 : CXFA_ContainerLayoutItem(pPageArea), m_pDocView(pDocView) {}
111
Dan Sinclair1770c022016-03-14 14:14:16 -0400112CXFA_FFPageView::~CXFA_FFPageView() {}
thestig9f3dbbc2016-04-13 13:18:21 -0700113
114CXFA_FFDocView* CXFA_FFPageView::GetDocView() const {
Tom Sepez797ca5c2017-05-25 12:03:18 -0700115 return m_pDocView.Get();
Dan Sinclair1770c022016-03-14 14:14:16 -0400116}
thestig9f3dbbc2016-04-13 13:18:21 -0700117
Dan Sinclair1b08df12017-02-09 09:17:20 -0500118CFX_RectF CXFA_FFPageView::GetPageViewRect() const {
119 return CFX_RectF(0, 0, GetPageSize());
Dan Sinclair1770c022016-03-14 14:14:16 -0400120}
dsinclair0b851ff2016-07-21 12:03:01 -0700121
Dan Sinclair1b08df12017-02-09 09:17:20 -0500122CFX_Matrix CXFA_FFPageView::GetDisplayMatrix(const CFX_Rect& rtDisp,
123 int32_t iRotate) const {
124 return GetPageMatrix(CFX_RectF(0, 0, GetPageSize()), rtDisp, iRotate, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -0400125}
thestig9f3dbbc2016-04-13 13:18:21 -0700126
Tom Sepez40badde2017-05-01 13:21:39 -0700127std::unique_ptr<IXFA_WidgetIterator> CXFA_FFPageView::CreateWidgetIterator(
tsepez736f28a2016-03-25 14:19:51 -0700128 uint32_t dwTraverseWay,
129 uint32_t dwWidgetFilter) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400130 switch (dwTraverseWay) {
131 case XFA_TRAVERSEWAY_Tranvalse:
Tom Sepez40badde2017-05-01 13:21:39 -0700132 return pdfium::MakeUnique<CXFA_FFTabOrderPageWidgetIterator>(
133 this, dwWidgetFilter);
Dan Sinclair1770c022016-03-14 14:14:16 -0400134 case XFA_TRAVERSEWAY_Form:
Tom Sepez40badde2017-05-01 13:21:39 -0700135 return pdfium::MakeUnique<CXFA_FFPageWidgetIterator>(this,
136 dwWidgetFilter);
Dan Sinclair1770c022016-03-14 14:14:16 -0400137 }
thestig9f3dbbc2016-04-13 13:18:21 -0700138 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400139}
thestig9f3dbbc2016-04-13 13:18:21 -0700140
Dan Sinclair1770c022016-03-14 14:14:16 -0400141CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView,
Tom Sepez312ce172017-03-06 14:00:07 -0800142 uint32_t dwFilter)
143 : m_pPageView(pPageView), m_dwFilter(dwFilter), m_sIterator(pPageView) {
tsepez20d6b762016-06-09 11:46:16 -0700144 m_bIgnorerelevant =
145 m_pPageView->GetDocView()->GetDoc()->GetXFADoc()->GetCurVersionMode() <
146 XFA_VERSION_205;
Dan Sinclair1770c022016-03-14 14:14:16 -0400147}
Tom Sepez312ce172017-03-06 14:00:07 -0800148
Dan Sinclair1770c022016-03-14 14:14:16 -0400149CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator() {}
Tom Sepez312ce172017-03-06 14:00:07 -0800150
Dan Sinclair1770c022016-03-14 14:14:16 -0400151void CXFA_FFPageWidgetIterator::Reset() {
152 m_sIterator.Reset();
153}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700154
dsinclairdf4bc592016-03-31 20:34:43 -0700155CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToFirst() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400156 m_sIterator.Reset();
157 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem;
158 pLayoutItem = m_sIterator.MoveToNext()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700159 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400160 return hWidget;
161 }
162 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700163 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400164}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700165
dsinclairdf4bc592016-03-31 20:34:43 -0700166CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToLast() {
dsinclair85d1f2c2016-06-23 12:40:16 -0700167 m_sIterator.SetCurrent(nullptr);
Dan Sinclair1770c022016-03-14 14:14:16 -0400168 return MoveToPrevious();
169}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700170
dsinclairdf4bc592016-03-31 20:34:43 -0700171CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToNext() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400172 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem;
173 pLayoutItem = m_sIterator.MoveToNext()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700174 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400175 return hWidget;
176 }
177 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700178 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400179}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700180
dsinclairdf4bc592016-03-31 20:34:43 -0700181CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToPrevious() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400182 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem;
183 pLayoutItem = m_sIterator.MoveToPrev()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700184 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400185 return hWidget;
186 }
187 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700188 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400189}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700190
dsinclairdf4bc592016-03-31 20:34:43 -0700191CXFA_FFWidget* CXFA_FFPageWidgetIterator::GetCurrentWidget() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400192 CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
dsinclair85d1f2c2016-06-23 12:40:16 -0700193 return pLayoutItem ? XFA_GetWidgetFromLayoutItem(pLayoutItem) : nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400194}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700195
tsepezd19e9122016-11-02 15:43:18 -0700196bool CXFA_FFPageWidgetIterator::SetCurrentWidget(CXFA_FFWidget* hWidget) {
dsinclairdf4bc592016-03-31 20:34:43 -0700197 return hWidget && m_sIterator.SetCurrent(hWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400198}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700199
dsinclairdf4bc592016-03-31 20:34:43 -0700200CXFA_FFWidget* CXFA_FFPageWidgetIterator::GetWidget(
Dan Sinclair1770c022016-03-14 14:14:16 -0400201 CXFA_LayoutItem* pLayoutItem) {
Lei Zhangafc8eb32017-03-28 14:32:13 -0700202 CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem);
203 if (!pWidget)
204 return nullptr;
205
206 if (!PageWidgetFilter(pWidget, m_dwFilter, false, m_bIgnorerelevant))
207 return nullptr;
208
209 if (!pWidget->IsLoaded() &&
210 !!(pWidget->GetStatus() & XFA_WidgetStatus_Visible)) {
Ryan Harrison73bed4e2017-09-22 10:53:34 -0400211 if (!pWidget->LoadWidget())
212 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400213 }
Lei Zhangafc8eb32017-03-28 14:32:13 -0700214 return pWidget;
215}
216
217void CXFA_TabParam::AppendTabParam(CXFA_TabParam* pParam) {
218 m_Children.push_back(pParam->GetWidget());
219 m_Children.insert(m_Children.end(), pParam->GetChildren().begin(),
220 pParam->GetChildren().end());
221}
222
223void CXFA_TabParam::ClearChildren() {
224 m_Children.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -0400225}
tsepezcc4d6d82016-05-16 13:21:03 -0700226
Dan Sinclair1770c022016-03-14 14:14:16 -0400227CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(
228 CXFA_FFPageView* pPageView,
tsepez736f28a2016-03-25 14:19:51 -0700229 uint32_t dwFilter)
Dan Sinclair1770c022016-03-14 14:14:16 -0400230 : m_pPageView(pPageView), m_dwFilter(dwFilter), m_iCurWidget(-1) {
tsepez20d6b762016-06-09 11:46:16 -0700231 m_bIgnorerelevant =
232 m_pPageView->GetDocView()->GetDoc()->GetXFADoc()->GetCurVersionMode() <
233 XFA_VERSION_205;
Dan Sinclair1770c022016-03-14 14:14:16 -0400234 Reset();
235}
tsepezcc4d6d82016-05-16 13:21:03 -0700236
Dan Sinclair1770c022016-03-14 14:14:16 -0400237CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator() {}
tsepezcc4d6d82016-05-16 13:21:03 -0700238
Dan Sinclair1770c022016-03-14 14:14:16 -0400239void CXFA_FFTabOrderPageWidgetIterator::Reset() {
240 CreateTabOrderWidgetArray();
241 m_iCurWidget = -1;
242}
tsepeza0b2d232017-01-23 11:32:36 -0800243
dsinclairdf4bc592016-03-31 20:34:43 -0700244CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToFirst() {
tsepeza0b2d232017-01-23 11:32:36 -0800245 for (int32_t i = 0;
246 i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) {
247 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
248 m_bIgnorerelevant)) {
249 m_iCurWidget = i;
250 return m_TabOrderWidgetArray[m_iCurWidget];
Dan Sinclair1770c022016-03-14 14:14:16 -0400251 }
252 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700253 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400254}
tsepeza0b2d232017-01-23 11:32:36 -0800255
dsinclairdf4bc592016-03-31 20:34:43 -0700256CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToLast() {
tsepeza0b2d232017-01-23 11:32:36 -0800257 for (int32_t i = pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) - 1;
258 i >= 0; i--) {
259 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
260 m_bIgnorerelevant)) {
261 m_iCurWidget = i;
262 return m_TabOrderWidgetArray[m_iCurWidget];
Dan Sinclair1770c022016-03-14 14:14:16 -0400263 }
264 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700265 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400266}
tsepeza0b2d232017-01-23 11:32:36 -0800267
dsinclairdf4bc592016-03-31 20:34:43 -0700268CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() {
tsepeza0b2d232017-01-23 11:32:36 -0800269 for (int32_t i = m_iCurWidget + 1;
270 i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) {
tsepezd19e9122016-11-02 15:43:18 -0700271 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
dsinclair935d8d52016-05-17 10:32:18 -0700272 m_bIgnorerelevant)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400273 m_iCurWidget = i;
274 return m_TabOrderWidgetArray[m_iCurWidget];
275 }
276 }
277 m_iCurWidget = -1;
dsinclair85d1f2c2016-06-23 12:40:16 -0700278 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400279}
tsepeza0b2d232017-01-23 11:32:36 -0800280
dsinclairdf4bc592016-03-31 20:34:43 -0700281CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400282 for (int32_t i = m_iCurWidget - 1; i >= 0; i--) {
tsepezd19e9122016-11-02 15:43:18 -0700283 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
dsinclair935d8d52016-05-17 10:32:18 -0700284 m_bIgnorerelevant)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400285 m_iCurWidget = i;
286 return m_TabOrderWidgetArray[m_iCurWidget];
287 }
288 }
289 m_iCurWidget = -1;
dsinclair85d1f2c2016-06-23 12:40:16 -0700290 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400291}
tsepeza0b2d232017-01-23 11:32:36 -0800292
dsinclairdf4bc592016-03-31 20:34:43 -0700293CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget() {
tsepeza0b2d232017-01-23 11:32:36 -0800294 return m_iCurWidget >= 0 ? m_TabOrderWidgetArray[m_iCurWidget] : nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400295}
tsepeza0b2d232017-01-23 11:32:36 -0800296
tsepezd19e9122016-11-02 15:43:18 -0700297bool CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(
dsinclairdf4bc592016-03-31 20:34:43 -0700298 CXFA_FFWidget* hWidget) {
tsepeza0b2d232017-01-23 11:32:36 -0800299 auto it = std::find(m_TabOrderWidgetArray.begin(),
300 m_TabOrderWidgetArray.end(), hWidget);
301 if (it == m_TabOrderWidgetArray.end())
302 return false;
303
304 m_iCurWidget = it - m_TabOrderWidgetArray.begin();
305 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400306}
tsepeza0b2d232017-01-23 11:32:36 -0800307
Dan Sinclair1770c022016-03-14 14:14:16 -0400308CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(
309 CXFA_FFWidget* pWidget) {
310 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
dsinclair56a8b192016-06-21 14:15:25 -0700311 CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_Element::Traversal);
Dan Sinclair1770c022016-03-14 14:14:16 -0400312 if (pTraversal) {
dsinclair56a8b192016-06-21 14:15:25 -0700313 CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_Element::Traverse);
Dan Sinclair1770c022016-03-14 14:14:16 -0400314 if (pTraverse) {
Ryan Harrison275e2602017-09-18 14:23:18 -0400315 WideString wsTraverseWidgetName;
Dan Sinclair1770c022016-03-14 14:14:16 -0400316 if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
tsepez70c55202016-04-14 15:32:35 -0700317 return FindWidgetByName(wsTraverseWidgetName, pWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400318 }
319 }
320 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700321 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400322}
323CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(
Ryan Harrison275e2602017-09-18 14:23:18 -0400324 const WideString& wsWidgetName,
Dan Sinclair1770c022016-03-14 14:14:16 -0400325 CXFA_FFWidget* pRefWidget) {
326 return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
327}
tsepeza0b2d232017-01-23 11:32:36 -0800328
Dan Sinclair1770c022016-03-14 14:14:16 -0400329void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
tsepeza0b2d232017-01-23 11:32:36 -0800330 m_TabOrderWidgetArray.clear();
331
332 std::vector<CXFA_FFWidget*> SpaceOrderWidgetArray;
333 CreateSpaceOrderWidgetArray(&SpaceOrderWidgetArray);
334 if (SpaceOrderWidgetArray.empty())
Dan Sinclair1770c022016-03-14 14:14:16 -0400335 return;
tsepeza0b2d232017-01-23 11:32:36 -0800336
337 int32_t nWidgetCount = pdfium::CollectionSize<int32_t>(SpaceOrderWidgetArray);
Dan Sinclair1770c022016-03-14 14:14:16 -0400338 CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
tsepeza0b2d232017-01-23 11:32:36 -0800339 while (pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) <
340 nWidgetCount) {
341 if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
342 m_TabOrderWidgetArray.push_back(hWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400343 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
dsinclair56a8b192016-06-21 14:15:25 -0700344 if (pWidgetAcc->GetUIType() == XFA_Element::ExclGroup) {
tsepeza0b2d232017-01-23 11:32:36 -0800345 auto it = std::find(SpaceOrderWidgetArray.begin(),
346 SpaceOrderWidgetArray.end(), hWidget);
347 int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end()
348 ? it - SpaceOrderWidgetArray.begin() + 1
349 : 0;
tsepezd19e9122016-11-02 15:43:18 -0700350 while (true) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400351 CXFA_FFWidget* pRadio =
tsepeza0b2d232017-01-23 11:32:36 -0800352 SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount];
Dan Sinclair1770c022016-03-14 14:14:16 -0400353 if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
354 break;
355 }
tsepeza0b2d232017-01-23 11:32:36 -0800356 if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
357 m_TabOrderWidgetArray.push_back(pRadio);
Dan Sinclair1770c022016-03-14 14:14:16 -0400358 }
359 iWidgetIndex++;
360 }
361 }
362 if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
363 hWidget = hTraverseWidget;
364 continue;
365 }
366 }
tsepeza0b2d232017-01-23 11:32:36 -0800367 auto it = std::find(SpaceOrderWidgetArray.begin(),
368 SpaceOrderWidgetArray.end(), hWidget);
369 int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end()
370 ? it - SpaceOrderWidgetArray.begin() + 1
371 : 0;
372 hWidget = SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount];
Dan Sinclair1770c022016-03-14 14:14:16 -0400373 }
374}
tsepeza0b2d232017-01-23 11:32:36 -0800375
Dan Sinclair1770c022016-03-14 14:14:16 -0400376void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(
377 CXFA_LayoutItemIterator* sIterator,
378 CXFA_LayoutItem* pContainerItem,
379 CXFA_TabParam* pContainer,
tsepezd19e9122016-11-02 15:43:18 -0700380 bool& bCurrentItem,
381 bool& bContentArea,
382 bool bMarsterPage) {
Tom Sepezb8227822017-03-24 13:10:14 -0700383 std::vector<std::unique_ptr<CXFA_TabParam>> tabParams;
Dan Sinclair1770c022016-03-14 14:14:16 -0400384 CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
385 while (pSearchItem) {
386 if (!pSearchItem->IsContentLayoutItem()) {
tsepezd19e9122016-11-02 15:43:18 -0700387 bContentArea = true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400388 pSearchItem = sIterator->MoveToNext();
389 continue;
390 }
391 if (bMarsterPage && bContentArea) {
392 break;
393 }
394 if (bMarsterPage || bContentArea) {
395 CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
396 if (!hWidget) {
397 pSearchItem = sIterator->MoveToNext();
398 continue;
399 }
400 if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
tsepezd19e9122016-11-02 15:43:18 -0700401 bCurrentItem = true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400402 break;
403 }
Tom Sepezb8227822017-03-24 13:10:14 -0700404 tabParams.push_back(pdfium::MakeUnique<CXFA_TabParam>(hWidget));
dsinclaird1cf2392016-07-11 06:46:59 -0700405 if (IsLayoutElement(pSearchItem->GetFormNode()->GetElementType(), true)) {
Tom Sepezb8227822017-03-24 13:10:14 -0700406 OrderContainer(sIterator, pSearchItem, tabParams.back().get(),
407 bCurrentItem, bContentArea, bMarsterPage);
Dan Sinclair1770c022016-03-14 14:14:16 -0400408 }
409 }
410 if (bCurrentItem) {
411 pSearchItem = sIterator->GetCurrent();
tsepezd19e9122016-11-02 15:43:18 -0700412 bCurrentItem = false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400413 } else {
414 pSearchItem = sIterator->MoveToNext();
415 }
416 }
Tom Sepezb8227822017-03-24 13:10:14 -0700417 std::sort(tabParams.begin(), tabParams.end(),
418 [](const std::unique_ptr<CXFA_TabParam>& arg1,
419 const std::unique_ptr<CXFA_TabParam>& arg2) {
Lei Zhangafc8eb32017-03-28 14:32:13 -0700420 const CFX_RectF& rt1 = arg1->GetWidget()->GetWidgetRect();
421 const CFX_RectF& rt2 = arg2->GetWidget()->GetWidgetRect();
Tom Sepezb8227822017-03-24 13:10:14 -0700422 if (rt1.top - rt2.top >= XFA_FLOAT_PERCISION)
423 return rt1.top < rt2.top;
424 return rt1.left < rt2.left;
425 });
Lei Zhangafc8eb32017-03-28 14:32:13 -0700426 for (const auto& pParam : tabParams)
427 pContainer->AppendTabParam(pParam.get());
Dan Sinclair1770c022016-03-14 14:14:16 -0400428}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700429
Dan Sinclair1770c022016-03-14 14:14:16 -0400430void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(
tsepeza0b2d232017-01-23 11:32:36 -0800431 std::vector<CXFA_FFWidget*>* WidgetArray) {
Tom Sepez312ce172017-03-06 14:00:07 -0800432 CXFA_LayoutItemIterator sIterator(m_pPageView);
Tom Sepezb8227822017-03-24 13:10:14 -0700433 auto pParam = pdfium::MakeUnique<CXFA_TabParam>(nullptr);
tsepezd19e9122016-11-02 15:43:18 -0700434 bool bCurrentItem = false;
435 bool bContentArea = false;
tsepeza0b2d232017-01-23 11:32:36 -0800436 OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea);
Lei Zhangafc8eb32017-03-28 14:32:13 -0700437 WidgetArray->insert(WidgetArray->end(), pParam->GetChildren().begin(),
438 pParam->GetChildren().end());
tsepeza0b2d232017-01-23 11:32:36 -0800439
Dan Sinclair1770c022016-03-14 14:14:16 -0400440 sIterator.Reset();
tsepezd19e9122016-11-02 15:43:18 -0700441 bCurrentItem = false;
442 bContentArea = false;
Lei Zhangafc8eb32017-03-28 14:32:13 -0700443 pParam->ClearChildren();
tsepeza0b2d232017-01-23 11:32:36 -0800444 OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea,
445 true);
Lei Zhangafc8eb32017-03-28 14:32:13 -0700446 WidgetArray->insert(WidgetArray->end(), pParam->GetChildren().begin(),
447 pParam->GetChildren().end());
Dan Sinclair1770c022016-03-14 14:14:16 -0400448}
tsepeza0b2d232017-01-23 11:32:36 -0800449
Dan Sinclair1770c022016-03-14 14:14:16 -0400450CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(
451 CXFA_LayoutItem* pLayoutItem) {
452 if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
453 if (!pWidget->IsLoaded() &&
dsinclair935d8d52016-05-17 10:32:18 -0700454 (pWidget->GetStatus() & XFA_WidgetStatus_Visible)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400455 pWidget->LoadWidget();
456 }
457 return pWidget;
458 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700459 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400460}
weili47bcd4c2016-06-16 08:00:06 -0700461
Tom Sepezb8227822017-03-24 13:10:14 -0700462CXFA_TabParam::CXFA_TabParam(CXFA_FFWidget* pWidget) : m_pWidget(pWidget) {}
weili47bcd4c2016-06-16 08:00:06 -0700463
464CXFA_TabParam::~CXFA_TabParam() {}