1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_array.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_stream.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_stream_acc.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_string.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/retain_ptr.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_helpers.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_interactiveform.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_pageview.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffdocview.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffwidget.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_ffwidgethandler.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_readynodeiterator.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_node.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_submit.h"
30*3ac0a46fSAndroid Build Coastguard Worker
31*3ac0a46fSAndroid Build Coastguard Worker #define IDS_XFA_Validate_Input \
32*3ac0a46fSAndroid Build Coastguard Worker "At least one required field was empty. Please fill in the required " \
33*3ac0a46fSAndroid Build Coastguard Worker "fields\r\n(highlighted) before continuing."
34*3ac0a46fSAndroid Build Coastguard Worker
35*3ac0a46fSAndroid Build Coastguard Worker // submit
36*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_CONFIG 0x00000001
37*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_TEMPLATE 0x00000010
38*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_LOCALESET 0x00000100
39*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_DATASETS 0x00001000
40*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_XMPMETA 0x00010000
41*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_XFDF 0x00100000
42*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_FORM 0x01000000
43*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_PDF 0x10000000
44*3ac0a46fSAndroid Build Coastguard Worker #define FXFA_XFA_ALL 0x01111111
45*3ac0a46fSAndroid Build Coastguard Worker
46*3ac0a46fSAndroid Build Coastguard Worker // Although there isn't direct casting between these types at present,
47*3ac0a46fSAndroid Build Coastguard Worker // keep the internal and exernal types in sync.
48*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXFA_PAGEVIEWEVENT_POSTADDED ==
49*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(CXFA_FFDoc::PageViewEvent::kPostAdded),
50*3ac0a46fSAndroid Build Coastguard Worker "kPostAdded mismatch");
51*3ac0a46fSAndroid Build Coastguard Worker static_assert(FXFA_PAGEVIEWEVENT_POSTREMOVED ==
52*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(CXFA_FFDoc::PageViewEvent::kPostRemoved),
53*3ac0a46fSAndroid Build Coastguard Worker "kPostRemoved mismatch");
54*3ac0a46fSAndroid Build Coastguard Worker
CPDFXFA_DocEnvironment(CPDFXFA_Context * pContext)55*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Context* pContext)
56*3ac0a46fSAndroid Build Coastguard Worker : m_pContext(pContext) {
57*3ac0a46fSAndroid Build Coastguard Worker DCHECK(m_pContext);
58*3ac0a46fSAndroid Build Coastguard Worker }
59*3ac0a46fSAndroid Build Coastguard Worker
60*3ac0a46fSAndroid Build Coastguard Worker CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() = default;
61*3ac0a46fSAndroid Build Coastguard Worker
SetChangeMark(CXFA_FFDoc * hDoc)62*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) {
63*3ac0a46fSAndroid Build Coastguard Worker if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
64*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->SetChangeMark();
65*3ac0a46fSAndroid Build Coastguard Worker }
66*3ac0a46fSAndroid Build Coastguard Worker
InvalidateRect(CXFA_FFPageView * pPageView,const CFX_RectF & rt)67*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView,
68*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rt) {
69*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
70*3ac0a46fSAndroid Build Coastguard Worker return;
71*3ac0a46fSAndroid Build Coastguard Worker
72*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
73*3ac0a46fSAndroid Build Coastguard Worker return;
74*3ac0a46fSAndroid Build Coastguard Worker
75*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pPageView);
76*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
77*3ac0a46fSAndroid Build Coastguard Worker return;
78*3ac0a46fSAndroid Build Coastguard Worker
79*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
80*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
81*3ac0a46fSAndroid Build Coastguard Worker return;
82*3ac0a46fSAndroid Build Coastguard Worker
83*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->Invalidate(pPage.Get(), rt.ToFloatRect().ToFxRect());
84*3ac0a46fSAndroid Build Coastguard Worker }
85*3ac0a46fSAndroid Build Coastguard Worker
DisplayCaret(CXFA_FFWidget * hWidget,bool bVisible,const CFX_RectF * pRtAnchor)86*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget,
87*3ac0a46fSAndroid Build Coastguard Worker bool bVisible,
88*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF* pRtAnchor) {
89*3ac0a46fSAndroid Build Coastguard Worker if (!hWidget || !pRtAnchor || !m_pContext->GetXFADoc() ||
90*3ac0a46fSAndroid Build Coastguard Worker !m_pContext->GetFormFillEnv() || !m_pContext->GetXFADocView())
91*3ac0a46fSAndroid Build Coastguard Worker return;
92*3ac0a46fSAndroid Build Coastguard Worker
93*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
94*3ac0a46fSAndroid Build Coastguard Worker return;
95*3ac0a46fSAndroid Build Coastguard Worker
96*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFWidgetHandler* pWidgetHandler =
97*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetXFADocView()->GetWidgetHandler();
98*3ac0a46fSAndroid Build Coastguard Worker if (!pWidgetHandler)
99*3ac0a46fSAndroid Build Coastguard Worker return;
100*3ac0a46fSAndroid Build Coastguard Worker
101*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pPageView = hWidget->GetPageView();
102*3ac0a46fSAndroid Build Coastguard Worker if (!pPageView)
103*3ac0a46fSAndroid Build Coastguard Worker return;
104*3ac0a46fSAndroid Build Coastguard Worker
105*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pPageView);
106*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
107*3ac0a46fSAndroid Build Coastguard Worker return;
108*3ac0a46fSAndroid Build Coastguard Worker
109*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
110*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
111*3ac0a46fSAndroid Build Coastguard Worker return;
112*3ac0a46fSAndroid Build Coastguard Worker
113*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect rcCaret = pRtAnchor->ToFloatRect();
114*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->DisplayCaret(pPage.Get(), bVisible, rcCaret.left, rcCaret.top,
115*3ac0a46fSAndroid Build Coastguard Worker rcCaret.right, rcCaret.bottom);
116*3ac0a46fSAndroid Build Coastguard Worker }
117*3ac0a46fSAndroid Build Coastguard Worker
GetPopupPos(CXFA_FFWidget * hWidget,float fMinPopup,float fMaxPopup,const CFX_RectF & rtAnchor,CFX_RectF * pPopupRect)118*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget,
119*3ac0a46fSAndroid Build Coastguard Worker float fMinPopup,
120*3ac0a46fSAndroid Build Coastguard Worker float fMaxPopup,
121*3ac0a46fSAndroid Build Coastguard Worker const CFX_RectF& rtAnchor,
122*3ac0a46fSAndroid Build Coastguard Worker CFX_RectF* pPopupRect) {
123*3ac0a46fSAndroid Build Coastguard Worker if (!hWidget)
124*3ac0a46fSAndroid Build Coastguard Worker return false;
125*3ac0a46fSAndroid Build Coastguard Worker
126*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
127*3ac0a46fSAndroid Build Coastguard Worker if (!pXFAPageView)
128*3ac0a46fSAndroid Build Coastguard Worker return false;
129*3ac0a46fSAndroid Build Coastguard Worker
130*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pXFAPageView);
131*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
132*3ac0a46fSAndroid Build Coastguard Worker return false;
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
135*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
136*3ac0a46fSAndroid Build Coastguard Worker return false;
137*3ac0a46fSAndroid Build Coastguard Worker
138*3ac0a46fSAndroid Build Coastguard Worker FS_RECTF page_view_rect = pFormFillEnv->GetPageViewRect(pPage.Get());
139*3ac0a46fSAndroid Build Coastguard Worker int nRotate = hWidget->GetNode()->GetRotate();
140*3ac0a46fSAndroid Build Coastguard Worker
141*3ac0a46fSAndroid Build Coastguard Worker int space_available_below_anchor;
142*3ac0a46fSAndroid Build Coastguard Worker int space_available_above_anchor;
143*3ac0a46fSAndroid Build Coastguard Worker switch (nRotate) {
144*3ac0a46fSAndroid Build Coastguard Worker case 0:
145*3ac0a46fSAndroid Build Coastguard Worker default: {
146*3ac0a46fSAndroid Build Coastguard Worker space_available_below_anchor =
147*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(page_view_rect.bottom - rtAnchor.bottom());
148*3ac0a46fSAndroid Build Coastguard Worker space_available_above_anchor =
149*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(rtAnchor.top - page_view_rect.top);
150*3ac0a46fSAndroid Build Coastguard Worker
151*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.left < page_view_rect.left)
152*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left += page_view_rect.left - rtAnchor.left;
153*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.right() > page_view_rect.right)
154*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left -= rtAnchor.right() - page_view_rect.right;
155*3ac0a46fSAndroid Build Coastguard Worker break;
156*3ac0a46fSAndroid Build Coastguard Worker }
157*3ac0a46fSAndroid Build Coastguard Worker case 90: {
158*3ac0a46fSAndroid Build Coastguard Worker space_available_below_anchor =
159*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(page_view_rect.right - rtAnchor.right());
160*3ac0a46fSAndroid Build Coastguard Worker space_available_above_anchor =
161*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(rtAnchor.left - page_view_rect.left);
162*3ac0a46fSAndroid Build Coastguard Worker
163*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.bottom() > page_view_rect.bottom)
164*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left += rtAnchor.bottom() - page_view_rect.bottom;
165*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.top < page_view_rect.top)
166*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left -= page_view_rect.top - rtAnchor.top;
167*3ac0a46fSAndroid Build Coastguard Worker break;
168*3ac0a46fSAndroid Build Coastguard Worker }
169*3ac0a46fSAndroid Build Coastguard Worker case 180: {
170*3ac0a46fSAndroid Build Coastguard Worker space_available_below_anchor =
171*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(rtAnchor.top - page_view_rect.top);
172*3ac0a46fSAndroid Build Coastguard Worker space_available_above_anchor =
173*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(page_view_rect.bottom - rtAnchor.bottom());
174*3ac0a46fSAndroid Build Coastguard Worker
175*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.right() > page_view_rect.right)
176*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left += rtAnchor.right() - page_view_rect.right;
177*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.left < page_view_rect.left)
178*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left -= page_view_rect.left - rtAnchor.left;
179*3ac0a46fSAndroid Build Coastguard Worker break;
180*3ac0a46fSAndroid Build Coastguard Worker }
181*3ac0a46fSAndroid Build Coastguard Worker case 270: {
182*3ac0a46fSAndroid Build Coastguard Worker space_available_below_anchor =
183*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(rtAnchor.left - page_view_rect.left);
184*3ac0a46fSAndroid Build Coastguard Worker space_available_above_anchor =
185*3ac0a46fSAndroid Build Coastguard Worker static_cast<int>(page_view_rect.right - rtAnchor.right());
186*3ac0a46fSAndroid Build Coastguard Worker
187*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.top < page_view_rect.top)
188*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left += page_view_rect.top - rtAnchor.top;
189*3ac0a46fSAndroid Build Coastguard Worker if (rtAnchor.bottom() > page_view_rect.bottom)
190*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->left -= rtAnchor.bottom() - page_view_rect.bottom;
191*3ac0a46fSAndroid Build Coastguard Worker break;
192*3ac0a46fSAndroid Build Coastguard Worker }
193*3ac0a46fSAndroid Build Coastguard Worker }
194*3ac0a46fSAndroid Build Coastguard Worker
195*3ac0a46fSAndroid Build Coastguard Worker // If there is no space on either side, the popup can't be rendered.
196*3ac0a46fSAndroid Build Coastguard Worker if (space_available_below_anchor <= 0 && space_available_above_anchor <= 0)
197*3ac0a46fSAndroid Build Coastguard Worker return false;
198*3ac0a46fSAndroid Build Coastguard Worker
199*3ac0a46fSAndroid Build Coastguard Worker // Determine whether to draw above or below the anchor.
200*3ac0a46fSAndroid Build Coastguard Worker bool draw_below_anchor;
201*3ac0a46fSAndroid Build Coastguard Worker if (space_available_below_anchor <= 0)
202*3ac0a46fSAndroid Build Coastguard Worker draw_below_anchor = false;
203*3ac0a46fSAndroid Build Coastguard Worker else if (space_available_above_anchor <= 0)
204*3ac0a46fSAndroid Build Coastguard Worker draw_below_anchor = true;
205*3ac0a46fSAndroid Build Coastguard Worker else if (space_available_below_anchor > space_available_above_anchor)
206*3ac0a46fSAndroid Build Coastguard Worker draw_below_anchor = true;
207*3ac0a46fSAndroid Build Coastguard Worker else
208*3ac0a46fSAndroid Build Coastguard Worker draw_below_anchor = false;
209*3ac0a46fSAndroid Build Coastguard Worker
210*3ac0a46fSAndroid Build Coastguard Worker int space_available = (draw_below_anchor ? space_available_below_anchor
211*3ac0a46fSAndroid Build Coastguard Worker : space_available_above_anchor);
212*3ac0a46fSAndroid Build Coastguard Worker
213*3ac0a46fSAndroid Build Coastguard Worker // Set the popup height and y position according to what was decided above.
214*3ac0a46fSAndroid Build Coastguard Worker float popup_height;
215*3ac0a46fSAndroid Build Coastguard Worker if (space_available < fMinPopup)
216*3ac0a46fSAndroid Build Coastguard Worker popup_height = fMinPopup;
217*3ac0a46fSAndroid Build Coastguard Worker else if (space_available > fMaxPopup)
218*3ac0a46fSAndroid Build Coastguard Worker popup_height = fMaxPopup;
219*3ac0a46fSAndroid Build Coastguard Worker else
220*3ac0a46fSAndroid Build Coastguard Worker popup_height = static_cast<float>(space_available);
221*3ac0a46fSAndroid Build Coastguard Worker
222*3ac0a46fSAndroid Build Coastguard Worker switch (nRotate) {
223*3ac0a46fSAndroid Build Coastguard Worker case 0:
224*3ac0a46fSAndroid Build Coastguard Worker case 180: {
225*3ac0a46fSAndroid Build Coastguard Worker if (draw_below_anchor)
226*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->top = rtAnchor.height;
227*3ac0a46fSAndroid Build Coastguard Worker else
228*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->top = -popup_height;
229*3ac0a46fSAndroid Build Coastguard Worker break;
230*3ac0a46fSAndroid Build Coastguard Worker }
231*3ac0a46fSAndroid Build Coastguard Worker case 90:
232*3ac0a46fSAndroid Build Coastguard Worker case 270: {
233*3ac0a46fSAndroid Build Coastguard Worker if (draw_below_anchor)
234*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->top = rtAnchor.width;
235*3ac0a46fSAndroid Build Coastguard Worker else
236*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->top = -popup_height;
237*3ac0a46fSAndroid Build Coastguard Worker break;
238*3ac0a46fSAndroid Build Coastguard Worker }
239*3ac0a46fSAndroid Build Coastguard Worker default:
240*3ac0a46fSAndroid Build Coastguard Worker break;
241*3ac0a46fSAndroid Build Coastguard Worker }
242*3ac0a46fSAndroid Build Coastguard Worker
243*3ac0a46fSAndroid Build Coastguard Worker pPopupRect->height = popup_height;
244*3ac0a46fSAndroid Build Coastguard Worker return true;
245*3ac0a46fSAndroid Build Coastguard Worker }
246*3ac0a46fSAndroid Build Coastguard Worker
PopupMenu(CXFA_FFWidget * hWidget,const CFX_PointF & ptPopup)247*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::PopupMenu(CXFA_FFWidget* hWidget,
248*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& ptPopup) {
249*3ac0a46fSAndroid Build Coastguard Worker if (!hWidget)
250*3ac0a46fSAndroid Build Coastguard Worker return false;
251*3ac0a46fSAndroid Build Coastguard Worker
252*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
253*3ac0a46fSAndroid Build Coastguard Worker if (!pXFAPageView)
254*3ac0a46fSAndroid Build Coastguard Worker return false;
255*3ac0a46fSAndroid Build Coastguard Worker
256*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(pXFAPageView);
257*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
258*3ac0a46fSAndroid Build Coastguard Worker return false;
259*3ac0a46fSAndroid Build Coastguard Worker
260*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
261*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
262*3ac0a46fSAndroid Build Coastguard Worker return false;
263*3ac0a46fSAndroid Build Coastguard Worker
264*3ac0a46fSAndroid Build Coastguard Worker int menuFlag = 0;
265*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanUndo())
266*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_UNDO;
267*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanRedo())
268*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_REDO;
269*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanPaste())
270*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_PASTE;
271*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanCopy())
272*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_COPY;
273*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanCut())
274*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_CUT;
275*3ac0a46fSAndroid Build Coastguard Worker if (hWidget->CanSelectAll())
276*3ac0a46fSAndroid Build Coastguard Worker menuFlag |= FXFA_MENU_SELECTALL;
277*3ac0a46fSAndroid Build Coastguard Worker
278*3ac0a46fSAndroid Build Coastguard Worker return pFormFillEnv->PopupMenu(pPage.Get(), menuFlag, ptPopup);
279*3ac0a46fSAndroid Build Coastguard Worker }
280*3ac0a46fSAndroid Build Coastguard Worker
OnPageViewEvent(CXFA_FFPageView * pPageView,CXFA_FFDoc::PageViewEvent eEvent)281*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::OnPageViewEvent(CXFA_FFPageView* pPageView,
282*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc::PageViewEvent eEvent) {
283*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
284*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
285*3ac0a46fSAndroid Build Coastguard Worker return;
286*3ac0a46fSAndroid Build Coastguard Worker
287*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetLoadStatus() == CPDFXFA_Context::LoadStatus::kLoading ||
288*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetLoadStatus() == CPDFXFA_Context::LoadStatus::kClosing ||
289*3ac0a46fSAndroid Build Coastguard Worker eEvent != CXFA_FFDoc::PageViewEvent::kStopLayout) {
290*3ac0a46fSAndroid Build Coastguard Worker return;
291*3ac0a46fSAndroid Build Coastguard Worker }
292*3ac0a46fSAndroid Build Coastguard Worker int nNewCount = m_pContext->GetPageCount();
293*3ac0a46fSAndroid Build Coastguard Worker if (nNewCount == m_pContext->GetOriginalPageCount())
294*3ac0a46fSAndroid Build Coastguard Worker return;
295*3ac0a46fSAndroid Build Coastguard Worker
296*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
297*3ac0a46fSAndroid Build Coastguard Worker if (!pXFADocView)
298*3ac0a46fSAndroid Build Coastguard Worker return;
299*3ac0a46fSAndroid Build Coastguard Worker
300*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0; i < m_pContext->GetOriginalPageCount(); ++i) {
301*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pPage = m_pContext->GetXFAPage(i);
302*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
303*3ac0a46fSAndroid Build Coastguard Worker continue;
304*3ac0a46fSAndroid Build Coastguard Worker
305*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->RemovePageView(pPage.Get());
306*3ac0a46fSAndroid Build Coastguard Worker pPage->SetXFAPageViewIndex(i);
307*3ac0a46fSAndroid Build Coastguard Worker }
308*3ac0a46fSAndroid Build Coastguard Worker
309*3ac0a46fSAndroid Build Coastguard Worker int flag = (nNewCount < m_pContext->GetOriginalPageCount())
310*3ac0a46fSAndroid Build Coastguard Worker ? FXFA_PAGEVIEWEVENT_POSTREMOVED
311*3ac0a46fSAndroid Build Coastguard Worker : FXFA_PAGEVIEWEVENT_POSTADDED;
312*3ac0a46fSAndroid Build Coastguard Worker int count = abs(nNewCount - m_pContext->GetOriginalPageCount());
313*3ac0a46fSAndroid Build Coastguard Worker m_pContext->SetOriginalPageCount(nNewCount);
314*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->PageEvent(count, flag);
315*3ac0a46fSAndroid Build Coastguard Worker }
316*3ac0a46fSAndroid Build Coastguard Worker
WidgetPostAdd(CXFA_FFWidget * hWidget)317*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::WidgetPostAdd(CXFA_FFWidget* hWidget) {
318*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
319*3ac0a46fSAndroid Build Coastguard Worker return;
320*3ac0a46fSAndroid Build Coastguard Worker
321*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pPageView = hWidget->GetPageView();
322*3ac0a46fSAndroid Build Coastguard Worker if (!pPageView)
323*3ac0a46fSAndroid Build Coastguard Worker return;
324*3ac0a46fSAndroid Build Coastguard Worker
325*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pXFAPage = m_pContext->GetXFAPage(pPageView);
326*3ac0a46fSAndroid Build Coastguard Worker if (!pXFAPage)
327*3ac0a46fSAndroid Build Coastguard Worker return;
328*3ac0a46fSAndroid Build Coastguard Worker
329*3ac0a46fSAndroid Build Coastguard Worker auto* formfill = m_pContext->GetFormFillEnv();
330*3ac0a46fSAndroid Build Coastguard Worker formfill->GetOrCreatePageView(pXFAPage.Get())->AddAnnotForFFWidget(hWidget);
331*3ac0a46fSAndroid Build Coastguard Worker }
332*3ac0a46fSAndroid Build Coastguard Worker
WidgetPreRemove(CXFA_FFWidget * hWidget)333*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::WidgetPreRemove(CXFA_FFWidget* hWidget) {
334*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
335*3ac0a46fSAndroid Build Coastguard Worker return;
336*3ac0a46fSAndroid Build Coastguard Worker
337*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFPageView* pPageView = hWidget->GetPageView();
338*3ac0a46fSAndroid Build Coastguard Worker if (!pPageView)
339*3ac0a46fSAndroid Build Coastguard Worker return;
340*3ac0a46fSAndroid Build Coastguard Worker
341*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDFXFA_Page> pXFAPage = m_pContext->GetXFAPage(pPageView);
342*3ac0a46fSAndroid Build Coastguard Worker if (!pXFAPage)
343*3ac0a46fSAndroid Build Coastguard Worker return;
344*3ac0a46fSAndroid Build Coastguard Worker
345*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pSdkPageView =
346*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->GetOrCreatePageView(pXFAPage.Get());
347*3ac0a46fSAndroid Build Coastguard Worker pSdkPageView->DeleteAnnotForFFWidget(hWidget);
348*3ac0a46fSAndroid Build Coastguard Worker }
349*3ac0a46fSAndroid Build Coastguard Worker
CountPages(const CXFA_FFDoc * hDoc) const350*3ac0a46fSAndroid Build Coastguard Worker int32_t CPDFXFA_DocEnvironment::CountPages(const CXFA_FFDoc* hDoc) const {
351*3ac0a46fSAndroid Build Coastguard Worker if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
352*3ac0a46fSAndroid Build Coastguard Worker return m_pContext->GetPageCount();
353*3ac0a46fSAndroid Build Coastguard Worker return 0;
354*3ac0a46fSAndroid Build Coastguard Worker }
355*3ac0a46fSAndroid Build Coastguard Worker
GetCurrentPage(const CXFA_FFDoc * hDoc) const356*3ac0a46fSAndroid Build Coastguard Worker int32_t CPDFXFA_DocEnvironment::GetCurrentPage(const CXFA_FFDoc* hDoc) const {
357*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
358*3ac0a46fSAndroid Build Coastguard Worker return -1;
359*3ac0a46fSAndroid Build Coastguard Worker
360*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
361*3ac0a46fSAndroid Build Coastguard Worker return -1;
362*3ac0a46fSAndroid Build Coastguard Worker
363*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
364*3ac0a46fSAndroid Build Coastguard Worker return pFormFillEnv ? pFormFillEnv->GetCurrentPageIndex() : -1;
365*3ac0a46fSAndroid Build Coastguard Worker }
366*3ac0a46fSAndroid Build Coastguard Worker
SetCurrentPage(CXFA_FFDoc * hDoc,int32_t iCurPage)367*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetCurrentPage(CXFA_FFDoc* hDoc,
368*3ac0a46fSAndroid Build Coastguard Worker int32_t iCurPage) {
369*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv() ||
370*3ac0a46fSAndroid Build Coastguard Worker !m_pContext->ContainsExtensionForm() || iCurPage < 0 ||
371*3ac0a46fSAndroid Build Coastguard Worker iCurPage >= m_pContext->GetFormFillEnv()->GetPageCount()) {
372*3ac0a46fSAndroid Build Coastguard Worker return;
373*3ac0a46fSAndroid Build Coastguard Worker }
374*3ac0a46fSAndroid Build Coastguard Worker
375*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
376*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
377*3ac0a46fSAndroid Build Coastguard Worker return;
378*3ac0a46fSAndroid Build Coastguard Worker
379*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->SetCurrentPage(iCurPage);
380*3ac0a46fSAndroid Build Coastguard Worker }
381*3ac0a46fSAndroid Build Coastguard Worker
IsCalculationsEnabled(const CXFA_FFDoc * hDoc) const382*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::IsCalculationsEnabled(
383*3ac0a46fSAndroid Build Coastguard Worker const CXFA_FFDoc* hDoc) const {
384*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
385*3ac0a46fSAndroid Build Coastguard Worker return false;
386*3ac0a46fSAndroid Build Coastguard Worker auto* pForm = m_pContext->GetFormFillEnv()->GetInteractiveForm();
387*3ac0a46fSAndroid Build Coastguard Worker return pForm->IsXfaCalculateEnabled();
388*3ac0a46fSAndroid Build Coastguard Worker }
389*3ac0a46fSAndroid Build Coastguard Worker
SetCalculationsEnabled(CXFA_FFDoc * hDoc,bool bEnabled)390*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetCalculationsEnabled(CXFA_FFDoc* hDoc,
391*3ac0a46fSAndroid Build Coastguard Worker bool bEnabled) {
392*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
393*3ac0a46fSAndroid Build Coastguard Worker return;
394*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->GetInteractiveForm()->XfaEnableCalculate(
395*3ac0a46fSAndroid Build Coastguard Worker bEnabled);
396*3ac0a46fSAndroid Build Coastguard Worker }
397*3ac0a46fSAndroid Build Coastguard Worker
GetTitle(const CXFA_FFDoc * hDoc) const398*3ac0a46fSAndroid Build Coastguard Worker WideString CPDFXFA_DocEnvironment::GetTitle(const CXFA_FFDoc* hDoc) const {
399*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
400*3ac0a46fSAndroid Build Coastguard Worker return WideString();
401*3ac0a46fSAndroid Build Coastguard Worker
402*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
403*3ac0a46fSAndroid Build Coastguard Worker if (!pPDFDoc)
404*3ac0a46fSAndroid Build Coastguard Worker return WideString();
405*3ac0a46fSAndroid Build Coastguard Worker
406*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pInfoDict = pPDFDoc->GetInfo();
407*3ac0a46fSAndroid Build Coastguard Worker if (!pInfoDict)
408*3ac0a46fSAndroid Build Coastguard Worker return WideString();
409*3ac0a46fSAndroid Build Coastguard Worker
410*3ac0a46fSAndroid Build Coastguard Worker ByteString csTitle = pInfoDict->GetByteStringFor("Title");
411*3ac0a46fSAndroid Build Coastguard Worker return WideString::FromDefANSI(csTitle.AsStringView());
412*3ac0a46fSAndroid Build Coastguard Worker }
413*3ac0a46fSAndroid Build Coastguard Worker
SetTitle(CXFA_FFDoc * hDoc,const WideString & wsTitle)414*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc,
415*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsTitle) {
416*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
417*3ac0a46fSAndroid Build Coastguard Worker return;
418*3ac0a46fSAndroid Build Coastguard Worker
419*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
420*3ac0a46fSAndroid Build Coastguard Worker if (!pPDFDoc)
421*3ac0a46fSAndroid Build Coastguard Worker return;
422*3ac0a46fSAndroid Build Coastguard Worker
423*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDF_Dictionary> pInfoDict = pPDFDoc->GetInfo();
424*3ac0a46fSAndroid Build Coastguard Worker if (pInfoDict)
425*3ac0a46fSAndroid Build Coastguard Worker pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle.AsStringView());
426*3ac0a46fSAndroid Build Coastguard Worker }
427*3ac0a46fSAndroid Build Coastguard Worker
ExportData(CXFA_FFDoc * hDoc,const WideString & wsFilePath,bool bXDP)428*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
429*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsFilePath,
430*3ac0a46fSAndroid Build Coastguard Worker bool bXDP) {
431*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
432*3ac0a46fSAndroid Build Coastguard Worker return;
433*3ac0a46fSAndroid Build Coastguard Worker
434*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->ContainsExtensionForm())
435*3ac0a46fSAndroid Build Coastguard Worker return;
436*3ac0a46fSAndroid Build Coastguard Worker
437*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
438*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
439*3ac0a46fSAndroid Build Coastguard Worker return;
440*3ac0a46fSAndroid Build Coastguard Worker
441*3ac0a46fSAndroid Build Coastguard Worker int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
442*3ac0a46fSAndroid Build Coastguard Worker ByteString bs = wsFilePath.ToUTF16LE();
443*3ac0a46fSAndroid Build Coastguard Worker if (wsFilePath.IsEmpty()) {
444*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv->GetFormFillInfo() ||
445*3ac0a46fSAndroid Build Coastguard Worker !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform) {
446*3ac0a46fSAndroid Build Coastguard Worker return;
447*3ac0a46fSAndroid Build Coastguard Worker }
448*3ac0a46fSAndroid Build Coastguard Worker
449*3ac0a46fSAndroid Build Coastguard Worker WideString filepath = pFormFillEnv->JS_fieldBrowse();
450*3ac0a46fSAndroid Build Coastguard Worker bs = filepath.ToUTF16LE();
451*3ac0a46fSAndroid Build Coastguard Worker }
452*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* pFileHandler = pFormFillEnv->OpenFile(
453*3ac0a46fSAndroid Build Coastguard Worker bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, AsFPDFWideString(&bs), "wb");
454*3ac0a46fSAndroid Build Coastguard Worker if (!pFileHandler)
455*3ac0a46fSAndroid Build Coastguard Worker return;
456*3ac0a46fSAndroid Build Coastguard Worker
457*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableStream> fileWrite = MakeSeekableStream(pFileHandler);
458*3ac0a46fSAndroid Build Coastguard Worker if (fileType == FXFA_SAVEAS_XML) {
459*3ac0a46fSAndroid Build Coastguard Worker fileWrite->WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
460*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
461*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
462*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Data)), fileWrite);
463*3ac0a46fSAndroid Build Coastguard Worker } else if (fileType == FXFA_SAVEAS_XDP) {
464*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->GetPDFDoc())
465*3ac0a46fSAndroid Build Coastguard Worker return;
466*3ac0a46fSAndroid Build Coastguard Worker
467*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
468*3ac0a46fSAndroid Build Coastguard Worker if (!pRoot)
469*3ac0a46fSAndroid Build Coastguard Worker return;
470*3ac0a46fSAndroid Build Coastguard Worker
471*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pAcroForm = pRoot->GetDictFor("AcroForm");
472*3ac0a46fSAndroid Build Coastguard Worker if (!pAcroForm)
473*3ac0a46fSAndroid Build Coastguard Worker return;
474*3ac0a46fSAndroid Build Coastguard Worker
475*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pArray =
476*3ac0a46fSAndroid Build Coastguard Worker ToArray(pAcroForm->GetObjectFor("XFA"));
477*3ac0a46fSAndroid Build Coastguard Worker if (!pArray)
478*3ac0a46fSAndroid Build Coastguard Worker return;
479*3ac0a46fSAndroid Build Coastguard Worker
480*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 1; i < pArray->size(); i += 2) {
481*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pPDFObj = pArray->GetObjectAt(i);
482*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pPrePDFObj = pArray->GetObjectAt(i - 1);
483*3ac0a46fSAndroid Build Coastguard Worker if (!pPrePDFObj->IsString())
484*3ac0a46fSAndroid Build Coastguard Worker continue;
485*3ac0a46fSAndroid Build Coastguard Worker if (!pPDFObj->IsReference())
486*3ac0a46fSAndroid Build Coastguard Worker continue;
487*3ac0a46fSAndroid Build Coastguard Worker
488*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Stream> pStream = ToStream(pPDFObj->GetDirect());
489*3ac0a46fSAndroid Build Coastguard Worker if (!pStream)
490*3ac0a46fSAndroid Build Coastguard Worker continue;
491*3ac0a46fSAndroid Build Coastguard Worker if (pPrePDFObj->GetString() == "form") {
492*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
493*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
494*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)),
495*3ac0a46fSAndroid Build Coastguard Worker fileWrite);
496*3ac0a46fSAndroid Build Coastguard Worker continue;
497*3ac0a46fSAndroid Build Coastguard Worker }
498*3ac0a46fSAndroid Build Coastguard Worker if (pPrePDFObj->GetString() == "datasets") {
499*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
500*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
501*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
502*3ac0a46fSAndroid Build Coastguard Worker fileWrite);
503*3ac0a46fSAndroid Build Coastguard Worker continue;
504*3ac0a46fSAndroid Build Coastguard Worker }
505*3ac0a46fSAndroid Build Coastguard Worker if (i == pArray->size() - 1) {
506*3ac0a46fSAndroid Build Coastguard Worker WideString wPath = WideString::FromUTF16LE(
507*3ac0a46fSAndroid Build Coastguard Worker reinterpret_cast<const unsigned short*>(bs.c_str()),
508*3ac0a46fSAndroid Build Coastguard Worker bs.GetLength() / sizeof(unsigned short));
509*3ac0a46fSAndroid Build Coastguard Worker ByteString bPath = wPath.ToUTF8();
510*3ac0a46fSAndroid Build Coastguard Worker static const char kFormat[] =
511*3ac0a46fSAndroid Build Coastguard Worker "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
512*3ac0a46fSAndroid Build Coastguard Worker ByteString content = ByteString::Format(kFormat, bPath.c_str());
513*3ac0a46fSAndroid Build Coastguard Worker fileWrite->WriteString(content.AsStringView());
514*3ac0a46fSAndroid Build Coastguard Worker }
515*3ac0a46fSAndroid Build Coastguard Worker auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pStream));
516*3ac0a46fSAndroid Build Coastguard Worker pAcc->LoadAllDataFiltered();
517*3ac0a46fSAndroid Build Coastguard Worker fileWrite->WriteBlock(pAcc->GetSpan());
518*3ac0a46fSAndroid Build Coastguard Worker }
519*3ac0a46fSAndroid Build Coastguard Worker }
520*3ac0a46fSAndroid Build Coastguard Worker fileWrite->Flush();
521*3ac0a46fSAndroid Build Coastguard Worker }
522*3ac0a46fSAndroid Build Coastguard Worker
GotoURL(CXFA_FFDoc * hDoc,const WideString & wsURL)523*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::GotoURL(CXFA_FFDoc* hDoc,
524*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsURL) {
525*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
526*3ac0a46fSAndroid Build Coastguard Worker return;
527*3ac0a46fSAndroid Build Coastguard Worker
528*3ac0a46fSAndroid Build Coastguard Worker if (m_pContext->GetFormType() != FormType::kXFAFull)
529*3ac0a46fSAndroid Build Coastguard Worker return;
530*3ac0a46fSAndroid Build Coastguard Worker
531*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
532*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
533*3ac0a46fSAndroid Build Coastguard Worker return;
534*3ac0a46fSAndroid Build Coastguard Worker
535*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->GotoURL(wsURL);
536*3ac0a46fSAndroid Build Coastguard Worker }
537*3ac0a46fSAndroid Build Coastguard Worker
IsValidationsEnabled(const CXFA_FFDoc * hDoc) const538*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::IsValidationsEnabled(
539*3ac0a46fSAndroid Build Coastguard Worker const CXFA_FFDoc* hDoc) const {
540*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
541*3ac0a46fSAndroid Build Coastguard Worker return false;
542*3ac0a46fSAndroid Build Coastguard Worker
543*3ac0a46fSAndroid Build Coastguard Worker auto* pForm = m_pContext->GetFormFillEnv()->GetInteractiveForm();
544*3ac0a46fSAndroid Build Coastguard Worker return pForm->IsXfaValidationsEnabled();
545*3ac0a46fSAndroid Build Coastguard Worker }
546*3ac0a46fSAndroid Build Coastguard Worker
SetValidationsEnabled(CXFA_FFDoc * hDoc,bool bEnabled)547*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetValidationsEnabled(CXFA_FFDoc* hDoc,
548*3ac0a46fSAndroid Build Coastguard Worker bool bEnabled) {
549*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
550*3ac0a46fSAndroid Build Coastguard Worker return;
551*3ac0a46fSAndroid Build Coastguard Worker
552*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->GetInteractiveForm()->XfaSetValidationsEnabled(
553*3ac0a46fSAndroid Build Coastguard Worker bEnabled);
554*3ac0a46fSAndroid Build Coastguard Worker }
555*3ac0a46fSAndroid Build Coastguard Worker
SetFocusWidget(CXFA_FFDoc * hDoc,CXFA_FFWidget * hWidget)556*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::SetFocusWidget(CXFA_FFDoc* hDoc,
557*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFWidget* hWidget) {
558*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
559*3ac0a46fSAndroid Build Coastguard Worker return;
560*3ac0a46fSAndroid Build Coastguard Worker
561*3ac0a46fSAndroid Build Coastguard Worker if (!hWidget) {
562*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pNull;
563*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->SetFocusAnnot(pNull);
564*3ac0a46fSAndroid Build Coastguard Worker return;
565*3ac0a46fSAndroid Build Coastguard Worker }
566*3ac0a46fSAndroid Build Coastguard Worker
567*3ac0a46fSAndroid Build Coastguard Worker int pageViewCount = m_pContext->GetFormFillEnv()->GetPageViewCount();
568*3ac0a46fSAndroid Build Coastguard Worker for (int i = 0; i < pageViewCount; i++) {
569*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_PageView* pPageView =
570*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->GetPageViewAtIndex(i);
571*3ac0a46fSAndroid Build Coastguard Worker if (!pPageView)
572*3ac0a46fSAndroid Build Coastguard Worker continue;
573*3ac0a46fSAndroid Build Coastguard Worker
574*3ac0a46fSAndroid Build Coastguard Worker ObservedPtr<CPDFSDK_Annot> pAnnot(pPageView->GetAnnotForFFWidget(hWidget));
575*3ac0a46fSAndroid Build Coastguard Worker if (pAnnot) {
576*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->SetFocusAnnot(pAnnot);
577*3ac0a46fSAndroid Build Coastguard Worker break;
578*3ac0a46fSAndroid Build Coastguard Worker }
579*3ac0a46fSAndroid Build Coastguard Worker }
580*3ac0a46fSAndroid Build Coastguard Worker }
581*3ac0a46fSAndroid Build Coastguard Worker
Print(CXFA_FFDoc * hDoc,int32_t nStartPage,int32_t nEndPage,Mask<XFA_PrintOpt> dwOptions)582*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc,
583*3ac0a46fSAndroid Build Coastguard Worker int32_t nStartPage,
584*3ac0a46fSAndroid Build Coastguard Worker int32_t nEndPage,
585*3ac0a46fSAndroid Build Coastguard Worker Mask<XFA_PrintOpt> dwOptions) {
586*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
587*3ac0a46fSAndroid Build Coastguard Worker return;
588*3ac0a46fSAndroid Build Coastguard Worker
589*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
590*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv || !pFormFillEnv->GetFormFillInfo() ||
591*3ac0a46fSAndroid Build Coastguard Worker !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform ||
592*3ac0a46fSAndroid Build Coastguard Worker !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print) {
593*3ac0a46fSAndroid Build Coastguard Worker return;
594*3ac0a46fSAndroid Build Coastguard Worker }
595*3ac0a46fSAndroid Build Coastguard Worker
596*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
597*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->GetFormFillInfo()->m_pJsPlatform,
598*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kShowDialog), nStartPage, nEndPage,
599*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kCanCancel),
600*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kShrinkPage),
601*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kAsImage),
602*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kReverseOrder),
603*3ac0a46fSAndroid Build Coastguard Worker !!(dwOptions & XFA_PrintOpt::kPrintAnnot));
604*3ac0a46fSAndroid Build Coastguard Worker }
605*3ac0a46fSAndroid Build Coastguard Worker
GetHighlightColor(const CXFA_FFDoc * hDoc) const606*3ac0a46fSAndroid Build Coastguard Worker FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(
607*3ac0a46fSAndroid Build Coastguard Worker const CXFA_FFDoc* hDoc) const {
608*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
609*3ac0a46fSAndroid Build Coastguard Worker return 0;
610*3ac0a46fSAndroid Build Coastguard Worker
611*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_InteractiveForm* pForm =
612*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetFormFillEnv()->GetInteractiveForm();
613*3ac0a46fSAndroid Build Coastguard Worker return AlphaAndColorRefToArgb(pForm->GetHighlightAlpha(),
614*3ac0a46fSAndroid Build Coastguard Worker pForm->GetHighlightColor(FormFieldType::kXFA));
615*3ac0a46fSAndroid Build Coastguard Worker }
616*3ac0a46fSAndroid Build Coastguard Worker
GetIJSRuntime(const CXFA_FFDoc * hDoc) const617*3ac0a46fSAndroid Build Coastguard Worker IJS_Runtime* CPDFXFA_DocEnvironment::GetIJSRuntime(
618*3ac0a46fSAndroid Build Coastguard Worker const CXFA_FFDoc* hDoc) const {
619*3ac0a46fSAndroid Build Coastguard Worker if (hDoc != m_pContext->GetXFADoc())
620*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
621*3ac0a46fSAndroid Build Coastguard Worker
622*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
623*3ac0a46fSAndroid Build Coastguard Worker return pFormFillEnv ? pFormFillEnv->GetIJSRuntime() : nullptr;
624*3ac0a46fSAndroid Build Coastguard Worker }
625*3ac0a46fSAndroid Build Coastguard Worker
GetXMLDoc() const626*3ac0a46fSAndroid Build Coastguard Worker CFX_XMLDocument* CPDFXFA_DocEnvironment::GetXMLDoc() const {
627*3ac0a46fSAndroid Build Coastguard Worker return m_pContext->GetXMLDoc();
628*3ac0a46fSAndroid Build Coastguard Worker }
629*3ac0a46fSAndroid Build Coastguard Worker
OpenLinkedFile(CXFA_FFDoc * hDoc,const WideString & wsLink)630*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile(
631*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc* hDoc,
632*3ac0a46fSAndroid Build Coastguard Worker const WideString& wsLink) {
633*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
634*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
635*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
636*3ac0a46fSAndroid Build Coastguard Worker
637*3ac0a46fSAndroid Build Coastguard Worker ByteString bs = wsLink.ToUTF16LE();
638*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* pFileHandler =
639*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->OpenFile(0, AsFPDFWideString(&bs), "rb");
640*3ac0a46fSAndroid Build Coastguard Worker if (!pFileHandler)
641*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
642*3ac0a46fSAndroid Build Coastguard Worker
643*3ac0a46fSAndroid Build Coastguard Worker return MakeSeekableStream(pFileHandler);
644*3ac0a46fSAndroid Build Coastguard Worker }
645*3ac0a46fSAndroid Build Coastguard Worker
646*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_XFA_ELEMENT_SUBMIT_ENABLED
Submit(CXFA_FFDoc * hDoc,CXFA_Submit * submit)647*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::Submit(CXFA_FFDoc* hDoc, CXFA_Submit* submit) {
648*3ac0a46fSAndroid Build Coastguard Worker if (!OnBeforeNotifySubmit() || !m_pContext->GetXFADocView())
649*3ac0a46fSAndroid Build Coastguard Worker return false;
650*3ac0a46fSAndroid Build Coastguard Worker
651*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetXFADocView()->UpdateDocView();
652*3ac0a46fSAndroid Build Coastguard Worker bool ret = SubmitInternal(hDoc, submit);
653*3ac0a46fSAndroid Build Coastguard Worker OnAfterNotifySubmit();
654*3ac0a46fSAndroid Build Coastguard Worker return ret;
655*3ac0a46fSAndroid Build Coastguard Worker }
656*3ac0a46fSAndroid Build Coastguard Worker
MailToInfo(WideString & csURL,WideString & csToAddress,WideString & csCCAddress,WideString & csBCCAddress,WideString & csSubject,WideString & csMsg)657*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::MailToInfo(WideString& csURL,
658*3ac0a46fSAndroid Build Coastguard Worker WideString& csToAddress,
659*3ac0a46fSAndroid Build Coastguard Worker WideString& csCCAddress,
660*3ac0a46fSAndroid Build Coastguard Worker WideString& csBCCAddress,
661*3ac0a46fSAndroid Build Coastguard Worker WideString& csSubject,
662*3ac0a46fSAndroid Build Coastguard Worker WideString& csMsg) {
663*3ac0a46fSAndroid Build Coastguard Worker WideString srcURL = csURL;
664*3ac0a46fSAndroid Build Coastguard Worker srcURL.TrimLeft();
665*3ac0a46fSAndroid Build Coastguard Worker if (srcURL.Left(7).CompareNoCase(L"mailto:") != 0)
666*3ac0a46fSAndroid Build Coastguard Worker return false;
667*3ac0a46fSAndroid Build Coastguard Worker
668*3ac0a46fSAndroid Build Coastguard Worker auto pos = srcURL.Find(L'?');
669*3ac0a46fSAndroid Build Coastguard Worker
670*3ac0a46fSAndroid Build Coastguard Worker {
671*3ac0a46fSAndroid Build Coastguard Worker WideString tmp;
672*3ac0a46fSAndroid Build Coastguard Worker if (!pos.has_value()) {
673*3ac0a46fSAndroid Build Coastguard Worker pos = srcURL.Find(L'@');
674*3ac0a46fSAndroid Build Coastguard Worker if (!pos.has_value())
675*3ac0a46fSAndroid Build Coastguard Worker return false;
676*3ac0a46fSAndroid Build Coastguard Worker
677*3ac0a46fSAndroid Build Coastguard Worker tmp = srcURL.Right(csURL.GetLength() - 7);
678*3ac0a46fSAndroid Build Coastguard Worker } else {
679*3ac0a46fSAndroid Build Coastguard Worker tmp = srcURL.Left(pos.value());
680*3ac0a46fSAndroid Build Coastguard Worker tmp = tmp.Right(tmp.GetLength() - 7);
681*3ac0a46fSAndroid Build Coastguard Worker }
682*3ac0a46fSAndroid Build Coastguard Worker tmp.Trim();
683*3ac0a46fSAndroid Build Coastguard Worker csToAddress = std::move(tmp);
684*3ac0a46fSAndroid Build Coastguard Worker }
685*3ac0a46fSAndroid Build Coastguard Worker
686*3ac0a46fSAndroid Build Coastguard Worker srcURL = srcURL.Right(srcURL.GetLength() - (pos.value() + 1));
687*3ac0a46fSAndroid Build Coastguard Worker while (!srcURL.IsEmpty()) {
688*3ac0a46fSAndroid Build Coastguard Worker srcURL.Trim();
689*3ac0a46fSAndroid Build Coastguard Worker pos = srcURL.Find(L'&');
690*3ac0a46fSAndroid Build Coastguard Worker WideString tmp = (!pos.has_value()) ? srcURL : srcURL.Left(pos.value());
691*3ac0a46fSAndroid Build Coastguard Worker tmp.Trim();
692*3ac0a46fSAndroid Build Coastguard Worker if (tmp.GetLength() >= 3 && tmp.Left(3).CompareNoCase(L"cc=") == 0) {
693*3ac0a46fSAndroid Build Coastguard Worker tmp = tmp.Right(tmp.GetLength() - 3);
694*3ac0a46fSAndroid Build Coastguard Worker if (!csCCAddress.IsEmpty())
695*3ac0a46fSAndroid Build Coastguard Worker csCCAddress += L';';
696*3ac0a46fSAndroid Build Coastguard Worker csCCAddress += tmp;
697*3ac0a46fSAndroid Build Coastguard Worker } else if (tmp.GetLength() >= 4 &&
698*3ac0a46fSAndroid Build Coastguard Worker tmp.Left(4).CompareNoCase(L"bcc=") == 0) {
699*3ac0a46fSAndroid Build Coastguard Worker tmp = tmp.Right(tmp.GetLength() - 4);
700*3ac0a46fSAndroid Build Coastguard Worker if (!csBCCAddress.IsEmpty())
701*3ac0a46fSAndroid Build Coastguard Worker csBCCAddress += L';';
702*3ac0a46fSAndroid Build Coastguard Worker csBCCAddress += tmp;
703*3ac0a46fSAndroid Build Coastguard Worker } else if (tmp.GetLength() >= 8 &&
704*3ac0a46fSAndroid Build Coastguard Worker tmp.Left(8).CompareNoCase(L"subject=") == 0) {
705*3ac0a46fSAndroid Build Coastguard Worker tmp = tmp.Right(tmp.GetLength() - 8);
706*3ac0a46fSAndroid Build Coastguard Worker csSubject += tmp;
707*3ac0a46fSAndroid Build Coastguard Worker } else if (tmp.GetLength() >= 5 &&
708*3ac0a46fSAndroid Build Coastguard Worker tmp.Left(5).CompareNoCase(L"body=") == 0) {
709*3ac0a46fSAndroid Build Coastguard Worker tmp = tmp.Right(tmp.GetLength() - 5);
710*3ac0a46fSAndroid Build Coastguard Worker csMsg += tmp;
711*3ac0a46fSAndroid Build Coastguard Worker }
712*3ac0a46fSAndroid Build Coastguard Worker srcURL = pos.has_value()
713*3ac0a46fSAndroid Build Coastguard Worker ? srcURL.Right(csURL.GetLength() - (pos.value() + 1))
714*3ac0a46fSAndroid Build Coastguard Worker : WideString();
715*3ac0a46fSAndroid Build Coastguard Worker }
716*3ac0a46fSAndroid Build Coastguard Worker csToAddress.Replace(L",", L";");
717*3ac0a46fSAndroid Build Coastguard Worker csCCAddress.Replace(L",", L";");
718*3ac0a46fSAndroid Build Coastguard Worker csBCCAddress.Replace(L",", L";");
719*3ac0a46fSAndroid Build Coastguard Worker return true;
720*3ac0a46fSAndroid Build Coastguard Worker }
721*3ac0a46fSAndroid Build Coastguard Worker
ExportSubmitFile(FPDF_FILEHANDLER * pFileHandler,int fileType,FPDF_DWORD encodeType,FPDF_DWORD flag)722*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
723*3ac0a46fSAndroid Build Coastguard Worker int fileType,
724*3ac0a46fSAndroid Build Coastguard Worker FPDF_DWORD encodeType,
725*3ac0a46fSAndroid Build Coastguard Worker FPDF_DWORD flag) {
726*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->GetXFADocView())
727*3ac0a46fSAndroid Build Coastguard Worker return false;
728*3ac0a46fSAndroid Build Coastguard Worker
729*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
730*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
731*3ac0a46fSAndroid Build Coastguard Worker return false;
732*3ac0a46fSAndroid Build Coastguard Worker
733*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDoc* ffdoc = m_pContext->GetXFADocView()->GetDoc();
734*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<IFX_SeekableStream> fileStream = MakeSeekableStream(pFileHandler);
735*3ac0a46fSAndroid Build Coastguard Worker if (fileType == FXFA_SAVEAS_XML) {
736*3ac0a46fSAndroid Build Coastguard Worker fileStream->WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
737*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
738*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Data)),
739*3ac0a46fSAndroid Build Coastguard Worker fileStream);
740*3ac0a46fSAndroid Build Coastguard Worker return true;
741*3ac0a46fSAndroid Build Coastguard Worker }
742*3ac0a46fSAndroid Build Coastguard Worker
743*3ac0a46fSAndroid Build Coastguard Worker if (fileType != FXFA_SAVEAS_XDP)
744*3ac0a46fSAndroid Build Coastguard Worker return true;
745*3ac0a46fSAndroid Build Coastguard Worker
746*3ac0a46fSAndroid Build Coastguard Worker if (!flag) {
747*3ac0a46fSAndroid Build Coastguard Worker flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
748*3ac0a46fSAndroid Build Coastguard Worker FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
749*3ac0a46fSAndroid Build Coastguard Worker }
750*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->GetPDFDoc()) {
751*3ac0a46fSAndroid Build Coastguard Worker fileStream->Flush();
752*3ac0a46fSAndroid Build Coastguard Worker return false;
753*3ac0a46fSAndroid Build Coastguard Worker }
754*3ac0a46fSAndroid Build Coastguard Worker
755*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
756*3ac0a46fSAndroid Build Coastguard Worker if (!pRoot) {
757*3ac0a46fSAndroid Build Coastguard Worker fileStream->Flush();
758*3ac0a46fSAndroid Build Coastguard Worker return false;
759*3ac0a46fSAndroid Build Coastguard Worker }
760*3ac0a46fSAndroid Build Coastguard Worker
761*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pAcroForm = pRoot->GetDictFor("AcroForm");
762*3ac0a46fSAndroid Build Coastguard Worker if (!pAcroForm) {
763*3ac0a46fSAndroid Build Coastguard Worker fileStream->Flush();
764*3ac0a46fSAndroid Build Coastguard Worker return false;
765*3ac0a46fSAndroid Build Coastguard Worker }
766*3ac0a46fSAndroid Build Coastguard Worker
767*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
768*3ac0a46fSAndroid Build Coastguard Worker if (!pArray) {
769*3ac0a46fSAndroid Build Coastguard Worker fileStream->Flush();
770*3ac0a46fSAndroid Build Coastguard Worker return false;
771*3ac0a46fSAndroid Build Coastguard Worker }
772*3ac0a46fSAndroid Build Coastguard Worker
773*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 1; i < pArray->size(); i += 2) {
774*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pPDFObj = pArray->GetObjectAt(i);
775*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pPrePDFObj = pArray->GetObjectAt(i - 1);
776*3ac0a46fSAndroid Build Coastguard Worker if (!pPrePDFObj->IsString())
777*3ac0a46fSAndroid Build Coastguard Worker continue;
778*3ac0a46fSAndroid Build Coastguard Worker if (!pPDFObj->IsReference())
779*3ac0a46fSAndroid Build Coastguard Worker continue;
780*3ac0a46fSAndroid Build Coastguard Worker
781*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Object> pDirectObj = pPDFObj->GetDirect();
782*3ac0a46fSAndroid Build Coastguard Worker if (!pDirectObj->IsStream())
783*3ac0a46fSAndroid Build Coastguard Worker continue;
784*3ac0a46fSAndroid Build Coastguard Worker ByteString bsType = pPrePDFObj->GetString();
785*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "config" && !(flag & FXFA_CONFIG))
786*3ac0a46fSAndroid Build Coastguard Worker continue;
787*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "template" && !(flag & FXFA_TEMPLATE))
788*3ac0a46fSAndroid Build Coastguard Worker continue;
789*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "localeSet" && !(flag & FXFA_LOCALESET))
790*3ac0a46fSAndroid Build Coastguard Worker continue;
791*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "datasets" && !(flag & FXFA_DATASETS))
792*3ac0a46fSAndroid Build Coastguard Worker continue;
793*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "xmpmeta" && !(flag & FXFA_XMPMETA))
794*3ac0a46fSAndroid Build Coastguard Worker continue;
795*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "xfdf" && !(flag & FXFA_XFDF))
796*3ac0a46fSAndroid Build Coastguard Worker continue;
797*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "form" && !(flag & FXFA_FORM))
798*3ac0a46fSAndroid Build Coastguard Worker continue;
799*3ac0a46fSAndroid Build Coastguard Worker
800*3ac0a46fSAndroid Build Coastguard Worker if (bsType == "form") {
801*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
802*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form)),
803*3ac0a46fSAndroid Build Coastguard Worker fileStream);
804*3ac0a46fSAndroid Build Coastguard Worker } else if (pPrePDFObj->GetString() == "datasets") {
805*3ac0a46fSAndroid Build Coastguard Worker ffdoc->SavePackage(
806*3ac0a46fSAndroid Build Coastguard Worker ToNode(ffdoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Datasets)),
807*3ac0a46fSAndroid Build Coastguard Worker fileStream);
808*3ac0a46fSAndroid Build Coastguard Worker }
809*3ac0a46fSAndroid Build Coastguard Worker }
810*3ac0a46fSAndroid Build Coastguard Worker return true;
811*3ac0a46fSAndroid Build Coastguard Worker }
812*3ac0a46fSAndroid Build Coastguard Worker
ToXFAContentFlags(WideString csSrcContent,FPDF_DWORD & flag)813*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::ToXFAContentFlags(WideString csSrcContent,
814*3ac0a46fSAndroid Build Coastguard Worker FPDF_DWORD& flag) {
815*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" config "))
816*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_CONFIG;
817*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" template "))
818*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_TEMPLATE;
819*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" localeSet "))
820*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_LOCALESET;
821*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" datasets "))
822*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_DATASETS;
823*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" xmpmeta "))
824*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_XMPMETA;
825*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" xfdf "))
826*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_XFDF;
827*3ac0a46fSAndroid Build Coastguard Worker if (csSrcContent.Contains(L" form "))
828*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_FORM;
829*3ac0a46fSAndroid Build Coastguard Worker if (flag == 0) {
830*3ac0a46fSAndroid Build Coastguard Worker flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
831*3ac0a46fSAndroid Build Coastguard Worker FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
832*3ac0a46fSAndroid Build Coastguard Worker }
833*3ac0a46fSAndroid Build Coastguard Worker }
834*3ac0a46fSAndroid Build Coastguard Worker
OnBeforeNotifySubmit()835*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::OnBeforeNotifySubmit() {
836*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->ContainsXFAForm())
837*3ac0a46fSAndroid Build Coastguard Worker return true;
838*3ac0a46fSAndroid Build Coastguard Worker
839*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFDocView* docView = m_pContext->GetXFADocView();
840*3ac0a46fSAndroid Build Coastguard Worker if (!docView)
841*3ac0a46fSAndroid Build Coastguard Worker return true;
842*3ac0a46fSAndroid Build Coastguard Worker
843*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFWidgetHandler* pWidgetHandler = docView->GetWidgetHandler();
844*3ac0a46fSAndroid Build Coastguard Worker if (!pWidgetHandler)
845*3ac0a46fSAndroid Build Coastguard Worker return true;
846*3ac0a46fSAndroid Build Coastguard Worker
847*3ac0a46fSAndroid Build Coastguard Worker auto it = docView->CreateReadyNodeIterator();
848*3ac0a46fSAndroid Build Coastguard Worker if (it) {
849*3ac0a46fSAndroid Build Coastguard Worker CXFA_EventParam Param;
850*3ac0a46fSAndroid Build Coastguard Worker Param.m_eType = XFA_EVENT_PreSubmit;
851*3ac0a46fSAndroid Build Coastguard Worker while (CXFA_Node* pNode = it->MoveToNext())
852*3ac0a46fSAndroid Build Coastguard Worker pWidgetHandler->ProcessEvent(pNode, &Param);
853*3ac0a46fSAndroid Build Coastguard Worker }
854*3ac0a46fSAndroid Build Coastguard Worker
855*3ac0a46fSAndroid Build Coastguard Worker it = docView->CreateReadyNodeIterator();
856*3ac0a46fSAndroid Build Coastguard Worker if (!it)
857*3ac0a46fSAndroid Build Coastguard Worker return true;
858*3ac0a46fSAndroid Build Coastguard Worker
859*3ac0a46fSAndroid Build Coastguard Worker (void)it->MoveToNext();
860*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pNode = it->MoveToNext();
861*3ac0a46fSAndroid Build Coastguard Worker
862*3ac0a46fSAndroid Build Coastguard Worker while (pNode) {
863*3ac0a46fSAndroid Build Coastguard Worker if (pNode->ProcessValidate(docView, -1) == XFA_EventError::kError) {
864*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
865*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
866*3ac0a46fSAndroid Build Coastguard Worker return false;
867*3ac0a46fSAndroid Build Coastguard Worker
868*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->JS_appAlert(WideString::FromDefANSI(IDS_XFA_Validate_Input),
869*3ac0a46fSAndroid Build Coastguard Worker WideString(), JSPLATFORM_ALERT_BUTTON_OK,
870*3ac0a46fSAndroid Build Coastguard Worker JSPLATFORM_ALERT_ICON_WARNING);
871*3ac0a46fSAndroid Build Coastguard Worker return false;
872*3ac0a46fSAndroid Build Coastguard Worker }
873*3ac0a46fSAndroid Build Coastguard Worker pNode = it->MoveToNext();
874*3ac0a46fSAndroid Build Coastguard Worker }
875*3ac0a46fSAndroid Build Coastguard Worker
876*3ac0a46fSAndroid Build Coastguard Worker docView->UpdateDocView();
877*3ac0a46fSAndroid Build Coastguard Worker return true;
878*3ac0a46fSAndroid Build Coastguard Worker }
879*3ac0a46fSAndroid Build Coastguard Worker
OnAfterNotifySubmit()880*3ac0a46fSAndroid Build Coastguard Worker void CPDFXFA_DocEnvironment::OnAfterNotifySubmit() {
881*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->ContainsXFAForm())
882*3ac0a46fSAndroid Build Coastguard Worker return;
883*3ac0a46fSAndroid Build Coastguard Worker
884*3ac0a46fSAndroid Build Coastguard Worker if (!m_pContext->GetXFADocView())
885*3ac0a46fSAndroid Build Coastguard Worker return;
886*3ac0a46fSAndroid Build Coastguard Worker
887*3ac0a46fSAndroid Build Coastguard Worker CXFA_FFWidgetHandler* pWidgetHandler =
888*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetXFADocView()->GetWidgetHandler();
889*3ac0a46fSAndroid Build Coastguard Worker if (!pWidgetHandler)
890*3ac0a46fSAndroid Build Coastguard Worker return;
891*3ac0a46fSAndroid Build Coastguard Worker
892*3ac0a46fSAndroid Build Coastguard Worker auto it = m_pContext->GetXFADocView()->CreateReadyNodeIterator();
893*3ac0a46fSAndroid Build Coastguard Worker if (!it)
894*3ac0a46fSAndroid Build Coastguard Worker return;
895*3ac0a46fSAndroid Build Coastguard Worker
896*3ac0a46fSAndroid Build Coastguard Worker CXFA_EventParam Param;
897*3ac0a46fSAndroid Build Coastguard Worker Param.m_eType = XFA_EVENT_PostSubmit;
898*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pNode = it->MoveToNext();
899*3ac0a46fSAndroid Build Coastguard Worker while (pNode) {
900*3ac0a46fSAndroid Build Coastguard Worker pWidgetHandler->ProcessEvent(pNode, &Param);
901*3ac0a46fSAndroid Build Coastguard Worker pNode = it->MoveToNext();
902*3ac0a46fSAndroid Build Coastguard Worker }
903*3ac0a46fSAndroid Build Coastguard Worker m_pContext->GetXFADocView()->UpdateDocView();
904*3ac0a46fSAndroid Build Coastguard Worker }
905*3ac0a46fSAndroid Build Coastguard Worker
SubmitInternal(CXFA_FFDoc * hDoc,CXFA_Submit * submit)906*3ac0a46fSAndroid Build Coastguard Worker bool CPDFXFA_DocEnvironment::SubmitInternal(CXFA_FFDoc* hDoc,
907*3ac0a46fSAndroid Build Coastguard Worker CXFA_Submit* submit) {
908*3ac0a46fSAndroid Build Coastguard Worker CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
909*3ac0a46fSAndroid Build Coastguard Worker if (!pFormFillEnv)
910*3ac0a46fSAndroid Build Coastguard Worker return false;
911*3ac0a46fSAndroid Build Coastguard Worker
912*3ac0a46fSAndroid Build Coastguard Worker WideString csURL = submit->GetSubmitTarget();
913*3ac0a46fSAndroid Build Coastguard Worker if (csURL.IsEmpty()) {
914*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->JS_appAlert(WideString::FromDefANSI("Submit cancelled."),
915*3ac0a46fSAndroid Build Coastguard Worker WideString(), JSPLATFORM_ALERT_BUTTON_OK,
916*3ac0a46fSAndroid Build Coastguard Worker JSPLATFORM_ALERT_ICON_ASTERISK);
917*3ac0a46fSAndroid Build Coastguard Worker return false;
918*3ac0a46fSAndroid Build Coastguard Worker }
919*3ac0a46fSAndroid Build Coastguard Worker
920*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEHANDLER* pFileHandler = nullptr;
921*3ac0a46fSAndroid Build Coastguard Worker int fileFlag = -1;
922*3ac0a46fSAndroid Build Coastguard Worker switch (submit->GetSubmitFormat()) {
923*3ac0a46fSAndroid Build Coastguard Worker case XFA_AttributeValue::Xdp: {
924*3ac0a46fSAndroid Build Coastguard Worker WideString csContent = submit->GetSubmitXDPContent();
925*3ac0a46fSAndroid Build Coastguard Worker csContent.Trim();
926*3ac0a46fSAndroid Build Coastguard Worker
927*3ac0a46fSAndroid Build Coastguard Worker WideString space = WideString::FromDefANSI(" ");
928*3ac0a46fSAndroid Build Coastguard Worker csContent = space + csContent + space;
929*3ac0a46fSAndroid Build Coastguard Worker FPDF_DWORD flag = 0;
930*3ac0a46fSAndroid Build Coastguard Worker if (submit->IsSubmitEmbedPDF())
931*3ac0a46fSAndroid Build Coastguard Worker flag |= FXFA_PDF;
932*3ac0a46fSAndroid Build Coastguard Worker
933*3ac0a46fSAndroid Build Coastguard Worker ToXFAContentFlags(csContent, flag);
934*3ac0a46fSAndroid Build Coastguard Worker pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb");
935*3ac0a46fSAndroid Build Coastguard Worker fileFlag = FXFA_SAVEAS_XDP;
936*3ac0a46fSAndroid Build Coastguard Worker ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
937*3ac0a46fSAndroid Build Coastguard Worker break;
938*3ac0a46fSAndroid Build Coastguard Worker }
939*3ac0a46fSAndroid Build Coastguard Worker case XFA_AttributeValue::Xml:
940*3ac0a46fSAndroid Build Coastguard Worker pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
941*3ac0a46fSAndroid Build Coastguard Worker fileFlag = FXFA_SAVEAS_XML;
942*3ac0a46fSAndroid Build Coastguard Worker ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
943*3ac0a46fSAndroid Build Coastguard Worker break;
944*3ac0a46fSAndroid Build Coastguard Worker case XFA_AttributeValue::Pdf:
945*3ac0a46fSAndroid Build Coastguard Worker break;
946*3ac0a46fSAndroid Build Coastguard Worker case XFA_AttributeValue::Urlencoded:
947*3ac0a46fSAndroid Build Coastguard Worker pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
948*3ac0a46fSAndroid Build Coastguard Worker fileFlag = FXFA_SAVEAS_XML;
949*3ac0a46fSAndroid Build Coastguard Worker ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
950*3ac0a46fSAndroid Build Coastguard Worker break;
951*3ac0a46fSAndroid Build Coastguard Worker default:
952*3ac0a46fSAndroid Build Coastguard Worker return false;
953*3ac0a46fSAndroid Build Coastguard Worker }
954*3ac0a46fSAndroid Build Coastguard Worker if (!pFileHandler)
955*3ac0a46fSAndroid Build Coastguard Worker return false;
956*3ac0a46fSAndroid Build Coastguard Worker
957*3ac0a46fSAndroid Build Coastguard Worker if (csURL.Left(7).CompareNoCase(L"mailto:") == 0) {
958*3ac0a46fSAndroid Build Coastguard Worker WideString csToAddress;
959*3ac0a46fSAndroid Build Coastguard Worker WideString csCCAddress;
960*3ac0a46fSAndroid Build Coastguard Worker WideString csBCCAddress;
961*3ac0a46fSAndroid Build Coastguard Worker WideString csSubject;
962*3ac0a46fSAndroid Build Coastguard Worker WideString csMsg;
963*3ac0a46fSAndroid Build Coastguard Worker if (!MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,
964*3ac0a46fSAndroid Build Coastguard Worker csMsg)) {
965*3ac0a46fSAndroid Build Coastguard Worker return false;
966*3ac0a46fSAndroid Build Coastguard Worker }
967*3ac0a46fSAndroid Build Coastguard Worker ByteString bsTo = WideString(csToAddress).ToUTF16LE();
968*3ac0a46fSAndroid Build Coastguard Worker ByteString bsCC = WideString(csCCAddress).ToUTF16LE();
969*3ac0a46fSAndroid Build Coastguard Worker ByteString bsBcc = WideString(csBCCAddress).ToUTF16LE();
970*3ac0a46fSAndroid Build Coastguard Worker ByteString bsSubject = WideString(csSubject).ToUTF16LE();
971*3ac0a46fSAndroid Build Coastguard Worker ByteString bsMsg = WideString(csMsg).ToUTF16LE();
972*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->EmailTo(pFileHandler, AsFPDFWideString(&bsTo),
973*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC),
974*3ac0a46fSAndroid Build Coastguard Worker AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg));
975*3ac0a46fSAndroid Build Coastguard Worker return true;
976*3ac0a46fSAndroid Build Coastguard Worker }
977*3ac0a46fSAndroid Build Coastguard Worker
978*3ac0a46fSAndroid Build Coastguard Worker // HTTP or FTP
979*3ac0a46fSAndroid Build Coastguard Worker ByteString bs = csURL.ToUTF16LE();
980*3ac0a46fSAndroid Build Coastguard Worker pFormFillEnv->UploadTo(pFileHandler, fileFlag, AsFPDFWideString(&bs));
981*3ac0a46fSAndroid Build Coastguard Worker return true;
982*3ac0a46fSAndroid Build Coastguard Worker }
983*3ac0a46fSAndroid Build Coastguard Worker #endif // PDF_XFA_ELEMENT_SUBMIT_ENABLED
984