blob: d027a83ce168b0271c5b69242a2b37aec8da49ce [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 Sinclaird9828fd2017-03-30 10:58:49 -040015#include "xfa/fde/cfde_rendercontext.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040016#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
17#include "xfa/fxfa/app/xfa_ffchoicelist.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040018#include "xfa/fxfa/app/xfa_fffield.h"
19#include "xfa/fxfa/app/xfa_ffimageedit.h"
20#include "xfa/fxfa/app/xfa_ffpushbutton.h"
21#include "xfa/fxfa/app/xfa_fftextedit.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040022#include "xfa/fxfa/app/xfa_fwladapter.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040023#include "xfa/fxfa/cxfa_ffdoc.h"
24#include "xfa/fxfa/cxfa_ffdocview.h"
25#include "xfa/fxfa/cxfa_ffwidget.h"
Dan Sinclairefcae5d2017-03-29 14:47:46 -040026#include "xfa/fxfa/parser/cxfa_node.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040027
dsinclairacd0d592016-04-21 11:06:27 -070028namespace {
29
Dan Sinclair1b08df12017-02-09 09:17:20 -050030CFX_Matrix GetPageMatrix(const CFX_RectF& docPageRect,
31 const CFX_Rect& devicePageRect,
32 int32_t iRotate,
33 uint32_t dwCoordinatesType) {
dsinclair43854a52016-04-27 12:26:00 -070034 ASSERT(iRotate >= 0 && iRotate <= 3);
Dan Sinclair1b08df12017-02-09 09:17:20 -050035
tsepezd19e9122016-11-02 15:43:18 -070036 bool bFlipX = (dwCoordinatesType & 0x01) != 0;
37 bool bFlipY = (dwCoordinatesType & 0x02) != 0;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050038 CFX_Matrix m((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0);
dsinclairacd0d592016-04-21 11:06:27 -070039 if (iRotate == 0 || iRotate == 2) {
Dan Sinclair05df0752017-03-14 14:43:42 -040040 m.a *= (float)devicePageRect.width / docPageRect.width;
41 m.d *= (float)devicePageRect.height / docPageRect.height;
dsinclairacd0d592016-04-21 11:06:27 -070042 } else {
Dan Sinclair05df0752017-03-14 14:43:42 -040043 m.a *= (float)devicePageRect.height / docPageRect.width;
44 m.d *= (float)devicePageRect.width / docPageRect.height;
dsinclairacd0d592016-04-21 11:06:27 -070045 }
46 m.Rotate(iRotate * 1.57079632675f);
47 switch (iRotate) {
48 case 0:
Dan Sinclair05df0752017-03-14 14:43:42 -040049 m.e = bFlipX ? (float)devicePageRect.right() : (float)devicePageRect.left;
50 m.f = bFlipY ? (float)devicePageRect.bottom() : (float)devicePageRect.top;
dsinclairacd0d592016-04-21 11:06:27 -070051 break;
52 case 1:
Dan Sinclair05df0752017-03-14 14:43:42 -040053 m.e = bFlipY ? (float)devicePageRect.left : (float)devicePageRect.right();
54 m.f = bFlipX ? (float)devicePageRect.bottom() : (float)devicePageRect.top;
dsinclairacd0d592016-04-21 11:06:27 -070055 break;
56 case 2:
Dan Sinclair05df0752017-03-14 14:43:42 -040057 m.e = bFlipX ? (float)devicePageRect.left : (float)devicePageRect.right();
58 m.f = bFlipY ? (float)devicePageRect.top : (float)devicePageRect.bottom();
dsinclairacd0d592016-04-21 11:06:27 -070059 break;
60 case 3:
Dan Sinclair05df0752017-03-14 14:43:42 -040061 m.e = bFlipY ? (float)devicePageRect.right() : (float)devicePageRect.left;
62 m.f = bFlipX ? (float)devicePageRect.top : (float)devicePageRect.bottom();
dsinclairacd0d592016-04-21 11:06:27 -070063 break;
64 default:
65 break;
66 }
Dan Sinclair1b08df12017-02-09 09:17:20 -050067 return m;
dsinclairacd0d592016-04-21 11:06:27 -070068}
69
dsinclair935d8d52016-05-17 10:32:18 -070070bool PageWidgetFilter(CXFA_FFWidget* pWidget,
71 uint32_t dwFilter,
tsepezd19e9122016-11-02 15:43:18 -070072 bool bTraversal,
73 bool bIgnorerelevant) {
dsinclair935d8d52016-05-17 10:32:18 -070074 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
75
76 if (!!(dwFilter & XFA_WidgetStatus_Focused) &&
dsinclair070fcdf2016-06-22 22:04:54 -070077 pWidgetAcc->GetElementType() != XFA_Element::Field) {
dsinclair935d8d52016-05-17 10:32:18 -070078 return false;
79 }
80
81 uint32_t dwStatus = pWidget->GetStatus();
82 if (bTraversal && (dwStatus & XFA_WidgetStatus_Disabled))
83 return false;
84 if (bIgnorerelevant)
85 return !!(dwStatus & XFA_WidgetStatus_Visible);
86
87 dwFilter &= (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable |
88 XFA_WidgetStatus_Printable);
89 return (dwFilter & dwStatus) == dwFilter;
90}
91
dsinclaird1cf2392016-07-11 06:46:59 -070092bool IsLayoutElement(XFA_Element eElement, bool bLayoutContainer) {
93 switch (eElement) {
94 case XFA_Element::Draw:
95 case XFA_Element::Field:
96 case XFA_Element::InstanceManager:
97 return !bLayoutContainer;
98 case XFA_Element::Area:
99 case XFA_Element::Subform:
100 case XFA_Element::ExclGroup:
101 case XFA_Element::SubformSet:
102 case XFA_Element::PageArea:
103 case XFA_Element::Form:
104 return true;
105 default:
106 return false;
107 }
108}
109
dsinclairacd0d592016-04-21 11:06:27 -0700110} // namespace
dsinclair935d8d52016-05-17 10:32:18 -0700111
Dan Sinclair1770c022016-03-14 14:14:16 -0400112CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
thestig9f3dbbc2016-04-13 13:18:21 -0700113 : CXFA_ContainerLayoutItem(pPageArea), m_pDocView(pDocView) {}
114
Dan Sinclair1770c022016-03-14 14:14:16 -0400115CXFA_FFPageView::~CXFA_FFPageView() {}
thestig9f3dbbc2016-04-13 13:18:21 -0700116
117CXFA_FFDocView* CXFA_FFPageView::GetDocView() const {
Dan Sinclair1770c022016-03-14 14:14:16 -0400118 return m_pDocView;
119}
thestig9f3dbbc2016-04-13 13:18:21 -0700120
Dan Sinclair1b08df12017-02-09 09:17:20 -0500121CFX_RectF CXFA_FFPageView::GetPageViewRect() const {
122 return CFX_RectF(0, 0, GetPageSize());
Dan Sinclair1770c022016-03-14 14:14:16 -0400123}
dsinclair0b851ff2016-07-21 12:03:01 -0700124
Dan Sinclair1b08df12017-02-09 09:17:20 -0500125CFX_Matrix CXFA_FFPageView::GetDisplayMatrix(const CFX_Rect& rtDisp,
126 int32_t iRotate) const {
127 return GetPageMatrix(CFX_RectF(0, 0, GetPageSize()), rtDisp, iRotate, 0);
Dan Sinclair1770c022016-03-14 14:14:16 -0400128}
thestig9f3dbbc2016-04-13 13:18:21 -0700129
Tom Sepez40badde2017-05-01 13:21:39 -0700130std::unique_ptr<IXFA_WidgetIterator> CXFA_FFPageView::CreateWidgetIterator(
tsepez736f28a2016-03-25 14:19:51 -0700131 uint32_t dwTraverseWay,
132 uint32_t dwWidgetFilter) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400133 switch (dwTraverseWay) {
134 case XFA_TRAVERSEWAY_Tranvalse:
Tom Sepez40badde2017-05-01 13:21:39 -0700135 return pdfium::MakeUnique<CXFA_FFTabOrderPageWidgetIterator>(
136 this, dwWidgetFilter);
Dan Sinclair1770c022016-03-14 14:14:16 -0400137 case XFA_TRAVERSEWAY_Form:
Tom Sepez40badde2017-05-01 13:21:39 -0700138 return pdfium::MakeUnique<CXFA_FFPageWidgetIterator>(this,
139 dwWidgetFilter);
Dan Sinclair1770c022016-03-14 14:14:16 -0400140 }
thestig9f3dbbc2016-04-13 13:18:21 -0700141 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400142}
thestig9f3dbbc2016-04-13 13:18:21 -0700143
Dan Sinclair1770c022016-03-14 14:14:16 -0400144CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView,
Tom Sepez312ce172017-03-06 14:00:07 -0800145 uint32_t dwFilter)
146 : m_pPageView(pPageView), m_dwFilter(dwFilter), m_sIterator(pPageView) {
tsepez20d6b762016-06-09 11:46:16 -0700147 m_bIgnorerelevant =
148 m_pPageView->GetDocView()->GetDoc()->GetXFADoc()->GetCurVersionMode() <
149 XFA_VERSION_205;
Dan Sinclair1770c022016-03-14 14:14:16 -0400150}
Tom Sepez312ce172017-03-06 14:00:07 -0800151
Dan Sinclair1770c022016-03-14 14:14:16 -0400152CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator() {}
Tom Sepez312ce172017-03-06 14:00:07 -0800153
Dan Sinclair1770c022016-03-14 14:14:16 -0400154void CXFA_FFPageWidgetIterator::Reset() {
155 m_sIterator.Reset();
156}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700157
dsinclairdf4bc592016-03-31 20:34:43 -0700158CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToFirst() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400159 m_sIterator.Reset();
160 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem;
161 pLayoutItem = m_sIterator.MoveToNext()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700162 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400163 return hWidget;
164 }
165 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700166 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400167}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700168
dsinclairdf4bc592016-03-31 20:34:43 -0700169CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToLast() {
dsinclair85d1f2c2016-06-23 12:40:16 -0700170 m_sIterator.SetCurrent(nullptr);
Dan Sinclair1770c022016-03-14 14:14:16 -0400171 return MoveToPrevious();
172}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700173
dsinclairdf4bc592016-03-31 20:34:43 -0700174CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToNext() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400175 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem;
176 pLayoutItem = m_sIterator.MoveToNext()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700177 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400178 return hWidget;
179 }
180 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700181 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400182}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700183
dsinclairdf4bc592016-03-31 20:34:43 -0700184CXFA_FFWidget* CXFA_FFPageWidgetIterator::MoveToPrevious() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400185 for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem;
186 pLayoutItem = m_sIterator.MoveToPrev()) {
dsinclairdf4bc592016-03-31 20:34:43 -0700187 if (CXFA_FFWidget* hWidget = GetWidget(pLayoutItem)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400188 return hWidget;
189 }
190 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700191 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400192}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700193
dsinclairdf4bc592016-03-31 20:34:43 -0700194CXFA_FFWidget* CXFA_FFPageWidgetIterator::GetCurrentWidget() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400195 CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
dsinclair85d1f2c2016-06-23 12:40:16 -0700196 return pLayoutItem ? XFA_GetWidgetFromLayoutItem(pLayoutItem) : nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400197}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700198
tsepezd19e9122016-11-02 15:43:18 -0700199bool CXFA_FFPageWidgetIterator::SetCurrentWidget(CXFA_FFWidget* hWidget) {
dsinclairdf4bc592016-03-31 20:34:43 -0700200 return hWidget && m_sIterator.SetCurrent(hWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400201}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700202
dsinclairdf4bc592016-03-31 20:34:43 -0700203CXFA_FFWidget* CXFA_FFPageWidgetIterator::GetWidget(
Dan Sinclair1770c022016-03-14 14:14:16 -0400204 CXFA_LayoutItem* pLayoutItem) {
Lei Zhangafc8eb32017-03-28 14:32:13 -0700205 CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem);
206 if (!pWidget)
207 return nullptr;
208
209 if (!PageWidgetFilter(pWidget, m_dwFilter, false, m_bIgnorerelevant))
210 return nullptr;
211
212 if (!pWidget->IsLoaded() &&
213 !!(pWidget->GetStatus() & XFA_WidgetStatus_Visible)) {
214 pWidget->LoadWidget();
Dan Sinclair1770c022016-03-14 14:14:16 -0400215 }
Lei Zhangafc8eb32017-03-28 14:32:13 -0700216 return pWidget;
217}
218
219void CXFA_TabParam::AppendTabParam(CXFA_TabParam* pParam) {
220 m_Children.push_back(pParam->GetWidget());
221 m_Children.insert(m_Children.end(), pParam->GetChildren().begin(),
222 pParam->GetChildren().end());
223}
224
225void CXFA_TabParam::ClearChildren() {
226 m_Children.clear();
Dan Sinclair1770c022016-03-14 14:14:16 -0400227}
tsepezcc4d6d82016-05-16 13:21:03 -0700228
Dan Sinclair1770c022016-03-14 14:14:16 -0400229CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(
230 CXFA_FFPageView* pPageView,
tsepez736f28a2016-03-25 14:19:51 -0700231 uint32_t dwFilter)
Dan Sinclair1770c022016-03-14 14:14:16 -0400232 : m_pPageView(pPageView), m_dwFilter(dwFilter), m_iCurWidget(-1) {
tsepez20d6b762016-06-09 11:46:16 -0700233 m_bIgnorerelevant =
234 m_pPageView->GetDocView()->GetDoc()->GetXFADoc()->GetCurVersionMode() <
235 XFA_VERSION_205;
Dan Sinclair1770c022016-03-14 14:14:16 -0400236 Reset();
237}
tsepezcc4d6d82016-05-16 13:21:03 -0700238
Dan Sinclair1770c022016-03-14 14:14:16 -0400239CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator() {}
tsepezcc4d6d82016-05-16 13:21:03 -0700240
Dan Sinclair1770c022016-03-14 14:14:16 -0400241void CXFA_FFTabOrderPageWidgetIterator::Reset() {
242 CreateTabOrderWidgetArray();
243 m_iCurWidget = -1;
244}
tsepeza0b2d232017-01-23 11:32:36 -0800245
dsinclairdf4bc592016-03-31 20:34:43 -0700246CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToFirst() {
tsepeza0b2d232017-01-23 11:32:36 -0800247 for (int32_t i = 0;
248 i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) {
249 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
250 m_bIgnorerelevant)) {
251 m_iCurWidget = i;
252 return m_TabOrderWidgetArray[m_iCurWidget];
Dan Sinclair1770c022016-03-14 14:14:16 -0400253 }
254 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700255 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400256}
tsepeza0b2d232017-01-23 11:32:36 -0800257
dsinclairdf4bc592016-03-31 20:34:43 -0700258CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToLast() {
tsepeza0b2d232017-01-23 11:32:36 -0800259 for (int32_t i = pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) - 1;
260 i >= 0; i--) {
261 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
262 m_bIgnorerelevant)) {
263 m_iCurWidget = i;
264 return m_TabOrderWidgetArray[m_iCurWidget];
Dan Sinclair1770c022016-03-14 14:14:16 -0400265 }
266 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700267 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400268}
tsepeza0b2d232017-01-23 11:32:36 -0800269
dsinclairdf4bc592016-03-31 20:34:43 -0700270CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() {
tsepeza0b2d232017-01-23 11:32:36 -0800271 for (int32_t i = m_iCurWidget + 1;
272 i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) {
tsepezd19e9122016-11-02 15:43:18 -0700273 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
dsinclair935d8d52016-05-17 10:32:18 -0700274 m_bIgnorerelevant)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400275 m_iCurWidget = i;
276 return m_TabOrderWidgetArray[m_iCurWidget];
277 }
278 }
279 m_iCurWidget = -1;
dsinclair85d1f2c2016-06-23 12:40:16 -0700280 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400281}
tsepeza0b2d232017-01-23 11:32:36 -0800282
dsinclairdf4bc592016-03-31 20:34:43 -0700283CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400284 for (int32_t i = m_iCurWidget - 1; i >= 0; i--) {
tsepezd19e9122016-11-02 15:43:18 -0700285 if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true,
dsinclair935d8d52016-05-17 10:32:18 -0700286 m_bIgnorerelevant)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400287 m_iCurWidget = i;
288 return m_TabOrderWidgetArray[m_iCurWidget];
289 }
290 }
291 m_iCurWidget = -1;
dsinclair85d1f2c2016-06-23 12:40:16 -0700292 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400293}
tsepeza0b2d232017-01-23 11:32:36 -0800294
dsinclairdf4bc592016-03-31 20:34:43 -0700295CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget() {
tsepeza0b2d232017-01-23 11:32:36 -0800296 return m_iCurWidget >= 0 ? m_TabOrderWidgetArray[m_iCurWidget] : nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400297}
tsepeza0b2d232017-01-23 11:32:36 -0800298
tsepezd19e9122016-11-02 15:43:18 -0700299bool CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(
dsinclairdf4bc592016-03-31 20:34:43 -0700300 CXFA_FFWidget* hWidget) {
tsepeza0b2d232017-01-23 11:32:36 -0800301 auto it = std::find(m_TabOrderWidgetArray.begin(),
302 m_TabOrderWidgetArray.end(), hWidget);
303 if (it == m_TabOrderWidgetArray.end())
304 return false;
305
306 m_iCurWidget = it - m_TabOrderWidgetArray.begin();
307 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400308}
tsepeza0b2d232017-01-23 11:32:36 -0800309
Dan Sinclair1770c022016-03-14 14:14:16 -0400310CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(
311 CXFA_FFWidget* pWidget) {
312 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
dsinclair56a8b192016-06-21 14:15:25 -0700313 CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_Element::Traversal);
Dan Sinclair1770c022016-03-14 14:14:16 -0400314 if (pTraversal) {
dsinclair56a8b192016-06-21 14:15:25 -0700315 CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_Element::Traverse);
Dan Sinclair1770c022016-03-14 14:14:16 -0400316 if (pTraverse) {
317 CFX_WideString wsTraverseWidgetName;
318 if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
tsepez70c55202016-04-14 15:32:35 -0700319 return FindWidgetByName(wsTraverseWidgetName, pWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400320 }
321 }
322 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700323 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400324}
325CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(
tsepez70c55202016-04-14 15:32:35 -0700326 const CFX_WideString& wsWidgetName,
Dan Sinclair1770c022016-03-14 14:14:16 -0400327 CXFA_FFWidget* pRefWidget) {
328 return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
329}
tsepeza0b2d232017-01-23 11:32:36 -0800330
Dan Sinclair1770c022016-03-14 14:14:16 -0400331void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
tsepeza0b2d232017-01-23 11:32:36 -0800332 m_TabOrderWidgetArray.clear();
333
334 std::vector<CXFA_FFWidget*> SpaceOrderWidgetArray;
335 CreateSpaceOrderWidgetArray(&SpaceOrderWidgetArray);
336 if (SpaceOrderWidgetArray.empty())
Dan Sinclair1770c022016-03-14 14:14:16 -0400337 return;
tsepeza0b2d232017-01-23 11:32:36 -0800338
339 int32_t nWidgetCount = pdfium::CollectionSize<int32_t>(SpaceOrderWidgetArray);
Dan Sinclair1770c022016-03-14 14:14:16 -0400340 CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
tsepeza0b2d232017-01-23 11:32:36 -0800341 while (pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) <
342 nWidgetCount) {
343 if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
344 m_TabOrderWidgetArray.push_back(hWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -0400345 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
dsinclair56a8b192016-06-21 14:15:25 -0700346 if (pWidgetAcc->GetUIType() == XFA_Element::ExclGroup) {
tsepeza0b2d232017-01-23 11:32:36 -0800347 auto it = std::find(SpaceOrderWidgetArray.begin(),
348 SpaceOrderWidgetArray.end(), hWidget);
349 int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end()
350 ? it - SpaceOrderWidgetArray.begin() + 1
351 : 0;
tsepezd19e9122016-11-02 15:43:18 -0700352 while (true) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400353 CXFA_FFWidget* pRadio =
tsepeza0b2d232017-01-23 11:32:36 -0800354 SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount];
Dan Sinclair1770c022016-03-14 14:14:16 -0400355 if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
356 break;
357 }
tsepeza0b2d232017-01-23 11:32:36 -0800358 if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) {
359 m_TabOrderWidgetArray.push_back(pRadio);
Dan Sinclair1770c022016-03-14 14:14:16 -0400360 }
361 iWidgetIndex++;
362 }
363 }
364 if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
365 hWidget = hTraverseWidget;
366 continue;
367 }
368 }
tsepeza0b2d232017-01-23 11:32:36 -0800369 auto it = std::find(SpaceOrderWidgetArray.begin(),
370 SpaceOrderWidgetArray.end(), hWidget);
371 int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end()
372 ? it - SpaceOrderWidgetArray.begin() + 1
373 : 0;
374 hWidget = SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount];
Dan Sinclair1770c022016-03-14 14:14:16 -0400375 }
376}
tsepeza0b2d232017-01-23 11:32:36 -0800377
Dan Sinclair1770c022016-03-14 14:14:16 -0400378void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(
379 CXFA_LayoutItemIterator* sIterator,
380 CXFA_LayoutItem* pContainerItem,
381 CXFA_TabParam* pContainer,
tsepezd19e9122016-11-02 15:43:18 -0700382 bool& bCurrentItem,
383 bool& bContentArea,
384 bool bMarsterPage) {
Tom Sepezb8227822017-03-24 13:10:14 -0700385 std::vector<std::unique_ptr<CXFA_TabParam>> tabParams;
Dan Sinclair1770c022016-03-14 14:14:16 -0400386 CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
387 while (pSearchItem) {
388 if (!pSearchItem->IsContentLayoutItem()) {
tsepezd19e9122016-11-02 15:43:18 -0700389 bContentArea = true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400390 pSearchItem = sIterator->MoveToNext();
391 continue;
392 }
393 if (bMarsterPage && bContentArea) {
394 break;
395 }
396 if (bMarsterPage || bContentArea) {
397 CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
398 if (!hWidget) {
399 pSearchItem = sIterator->MoveToNext();
400 continue;
401 }
402 if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
tsepezd19e9122016-11-02 15:43:18 -0700403 bCurrentItem = true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400404 break;
405 }
Tom Sepezb8227822017-03-24 13:10:14 -0700406 tabParams.push_back(pdfium::MakeUnique<CXFA_TabParam>(hWidget));
dsinclaird1cf2392016-07-11 06:46:59 -0700407 if (IsLayoutElement(pSearchItem->GetFormNode()->GetElementType(), true)) {
Tom Sepezb8227822017-03-24 13:10:14 -0700408 OrderContainer(sIterator, pSearchItem, tabParams.back().get(),
409 bCurrentItem, bContentArea, bMarsterPage);
Dan Sinclair1770c022016-03-14 14:14:16 -0400410 }
411 }
412 if (bCurrentItem) {
413 pSearchItem = sIterator->GetCurrent();
tsepezd19e9122016-11-02 15:43:18 -0700414 bCurrentItem = false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400415 } else {
416 pSearchItem = sIterator->MoveToNext();
417 }
418 }
Tom Sepezb8227822017-03-24 13:10:14 -0700419 std::sort(tabParams.begin(), tabParams.end(),
420 [](const std::unique_ptr<CXFA_TabParam>& arg1,
421 const std::unique_ptr<CXFA_TabParam>& arg2) {
Lei Zhangafc8eb32017-03-28 14:32:13 -0700422 const CFX_RectF& rt1 = arg1->GetWidget()->GetWidgetRect();
423 const CFX_RectF& rt2 = arg2->GetWidget()->GetWidgetRect();
Tom Sepezb8227822017-03-24 13:10:14 -0700424 if (rt1.top - rt2.top >= XFA_FLOAT_PERCISION)
425 return rt1.top < rt2.top;
426 return rt1.left < rt2.left;
427 });
Lei Zhangafc8eb32017-03-28 14:32:13 -0700428 for (const auto& pParam : tabParams)
429 pContainer->AppendTabParam(pParam.get());
Dan Sinclair1770c022016-03-14 14:14:16 -0400430}
Lei Zhangafc8eb32017-03-28 14:32:13 -0700431
Dan Sinclair1770c022016-03-14 14:14:16 -0400432void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(
tsepeza0b2d232017-01-23 11:32:36 -0800433 std::vector<CXFA_FFWidget*>* WidgetArray) {
Tom Sepez312ce172017-03-06 14:00:07 -0800434 CXFA_LayoutItemIterator sIterator(m_pPageView);
Tom Sepezb8227822017-03-24 13:10:14 -0700435 auto pParam = pdfium::MakeUnique<CXFA_TabParam>(nullptr);
tsepezd19e9122016-11-02 15:43:18 -0700436 bool bCurrentItem = false;
437 bool bContentArea = false;
tsepeza0b2d232017-01-23 11:32:36 -0800438 OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea);
Lei Zhangafc8eb32017-03-28 14:32:13 -0700439 WidgetArray->insert(WidgetArray->end(), pParam->GetChildren().begin(),
440 pParam->GetChildren().end());
tsepeza0b2d232017-01-23 11:32:36 -0800441
Dan Sinclair1770c022016-03-14 14:14:16 -0400442 sIterator.Reset();
tsepezd19e9122016-11-02 15:43:18 -0700443 bCurrentItem = false;
444 bContentArea = false;
Lei Zhangafc8eb32017-03-28 14:32:13 -0700445 pParam->ClearChildren();
tsepeza0b2d232017-01-23 11:32:36 -0800446 OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea,
447 true);
Lei Zhangafc8eb32017-03-28 14:32:13 -0700448 WidgetArray->insert(WidgetArray->end(), pParam->GetChildren().begin(),
449 pParam->GetChildren().end());
Dan Sinclair1770c022016-03-14 14:14:16 -0400450}
tsepeza0b2d232017-01-23 11:32:36 -0800451
Dan Sinclair1770c022016-03-14 14:14:16 -0400452CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(
453 CXFA_LayoutItem* pLayoutItem) {
454 if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
455 if (!pWidget->IsLoaded() &&
dsinclair935d8d52016-05-17 10:32:18 -0700456 (pWidget->GetStatus() & XFA_WidgetStatus_Visible)) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400457 pWidget->LoadWidget();
458 }
459 return pWidget;
460 }
dsinclair85d1f2c2016-06-23 12:40:16 -0700461 return nullptr;
Dan Sinclair1770c022016-03-14 14:14:16 -0400462}
weili47bcd4c2016-06-16 08:00:06 -0700463
Tom Sepezb8227822017-03-24 13:10:14 -0700464CXFA_TabParam::CXFA_TabParam(CXFA_FFWidget* pWidget) : m_pWidget(pWidget) {}
weili47bcd4c2016-06-16 08:00:06 -0700465
466CXFA_TabParam::~CXFA_TabParam() {}