Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1 | // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 7 | #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" |
Dan Sinclair | 61046b9 | 2016-02-18 14:48:48 -0500 | [diff] [blame] | 8 | #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 9 | #include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" |
Dan Sinclair | 61046b9 | 2016-02-18 14:48:48 -0500 | [diff] [blame] | 10 | #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" |
| 11 | #include "fpdfsdk/include/fsdk_define.h" |
| 12 | #include "fpdfsdk/include/fsdk_mgr.h" |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 13 | #include "fpdfsdk/include/javascript/IJavaScript.h" |
| 14 | #include "public/fpdf_formfill.h" |
| 15 | |
| 16 | #define IDS_XFA_Validate_Input \ |
| 17 | "At least one required field was empty. Please fill in the required " \ |
| 18 | "fields\r\n(highlighted) before continuing." |
| 19 | |
| 20 | // submit |
| 21 | #define FXFA_CONFIG 0x00000001 |
| 22 | #define FXFA_TEMPLATE 0x00000010 |
| 23 | #define FXFA_LOCALESET 0x00000100 |
| 24 | #define FXFA_DATASETS 0x00001000 |
| 25 | #define FXFA_XMPMETA 0x00010000 |
| 26 | #define FXFA_XFDF 0x00100000 |
| 27 | #define FXFA_FORM 0x01000000 |
| 28 | #define FXFA_PDF 0x10000000 |
| 29 | |
| 30 | #ifndef _WIN32 |
| 31 | extern void SetLastError(int err); |
| 32 | |
| 33 | extern int GetLastError(); |
| 34 | #endif |
| 35 | |
| 36 | CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc, |
| 37 | CPDFXFA_App* pProvider) |
| 38 | : m_iDocType(DOCTYPE_PDF), |
| 39 | m_pPDFDoc(pPDFDoc), |
| 40 | m_pSDKDoc(nullptr), |
| 41 | m_pXFADoc(nullptr), |
| 42 | m_pXFADocView(nullptr), |
| 43 | m_pApp(pProvider), |
| 44 | m_pJSContext(nullptr) { |
| 45 | } |
| 46 | |
| 47 | CPDFXFA_Document::~CPDFXFA_Document() { |
Jun Fang | 23bf560 | 2016-02-01 20:29:55 -0800 | [diff] [blame] | 48 | if (m_pXFADoc) { |
| 49 | IXFA_App* pApp = m_pApp->GetXFAApp(); |
| 50 | if (pApp) { |
| 51 | IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); |
| 52 | if (pDocHandler) { |
| 53 | CloseXFADoc(pDocHandler); |
| 54 | } |
| 55 | } |
| 56 | delete m_pXFADoc; |
| 57 | } |
Jun Fang | f7e38ed | 2016-02-04 17:47:00 -0800 | [diff] [blame] | 58 | if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv()) |
| 59 | m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext); |
| 60 | delete m_pSDKDoc; |
| 61 | if (m_pPDFDoc) { |
| 62 | CPDF_Parser* pParser = m_pPDFDoc->GetParser(); |
| 63 | if (pParser) |
| 64 | delete pParser; |
| 65 | else |
| 66 | delete m_pPDFDoc; |
| 67 | } |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | FX_BOOL CPDFXFA_Document::LoadXFADoc() { |
| 71 | if (!m_pPDFDoc) |
| 72 | return FALSE; |
| 73 | |
| 74 | m_XFAPageList.RemoveAll(); |
| 75 | |
| 76 | IXFA_App* pApp = m_pApp->GetXFAApp(); |
| 77 | if (!pApp) |
| 78 | return FALSE; |
| 79 | |
| 80 | m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc); |
| 81 | if (!m_pXFADoc) { |
| 82 | SetLastError(FPDF_ERR_XFALOAD); |
| 83 | return FALSE; |
| 84 | } |
| 85 | |
| 86 | IXFA_DocHandler* pDocHandler = pApp->GetDocHandler(); |
| 87 | if (!pDocHandler) { |
| 88 | SetLastError(FPDF_ERR_XFALOAD); |
| 89 | return FALSE; |
| 90 | } |
| 91 | |
| 92 | pDocHandler->StartLoad(m_pXFADoc); |
| 93 | int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL); |
| 94 | if (iStatus != XFA_PARSESTATUS_Done) { |
| 95 | CloseXFADoc(pDocHandler); |
| 96 | SetLastError(FPDF_ERR_XFALOAD); |
| 97 | return FALSE; |
| 98 | } |
| 99 | pDocHandler->StopLoad(m_pXFADoc); |
| 100 | pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime()); |
| 101 | |
| 102 | if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic) |
| 103 | m_iDocType = DOCTYPE_DYNAMIC_XFA; |
| 104 | else |
| 105 | m_iDocType = DOCTYPE_STATIC_XFA; |
| 106 | |
| 107 | m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View); |
| 108 | if (m_pXFADocView->StartLayout() < 0) { |
| 109 | CloseXFADoc(pDocHandler); |
| 110 | SetLastError(FPDF_ERR_XFALAYOUT); |
| 111 | return FALSE; |
| 112 | } |
| 113 | |
| 114 | m_pXFADocView->DoLayout(NULL); |
| 115 | m_pXFADocView->StopLayout(); |
| 116 | return TRUE; |
| 117 | } |
| 118 | |
| 119 | int CPDFXFA_Document::GetPageCount() { |
| 120 | if (!m_pPDFDoc && !m_pXFADoc) |
| 121 | return 0; |
| 122 | |
| 123 | switch (m_iDocType) { |
| 124 | case DOCTYPE_PDF: |
| 125 | case DOCTYPE_STATIC_XFA: |
| 126 | if (m_pPDFDoc) |
| 127 | return m_pPDFDoc->GetPageCount(); |
| 128 | case DOCTYPE_DYNAMIC_XFA: |
| 129 | if (m_pXFADoc) |
| 130 | return m_pXFADocView->CountPageViews(); |
| 131 | default: |
| 132 | return 0; |
| 133 | } |
| 134 | |
| 135 | return 0; |
| 136 | } |
| 137 | |
| 138 | CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) { |
| 139 | if (page_index < 0) |
| 140 | return nullptr; |
| 141 | CPDFXFA_Page* pPage = nullptr; |
| 142 | int nCount = m_XFAPageList.GetSize(); |
| 143 | if (nCount > 0 && page_index < nCount) { |
| 144 | pPage = m_XFAPageList.GetAt(page_index); |
| 145 | if (pPage) |
| 146 | pPage->AddRef(); |
| 147 | } else { |
| 148 | m_XFAPageList.SetSize(GetPageCount()); |
| 149 | } |
| 150 | if (pPage) |
| 151 | return pPage; |
| 152 | pPage = new CPDFXFA_Page(this, page_index); |
| 153 | if (!pPage->LoadPage()) { |
| 154 | delete pPage; |
| 155 | return nullptr; |
| 156 | } |
| 157 | m_XFAPageList.SetAt(page_index, pPage); |
| 158 | return pPage; |
| 159 | } |
| 160 | |
| 161 | CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) { |
| 162 | if (!pPage) |
| 163 | return NULL; |
| 164 | |
| 165 | if (!m_pXFADoc) |
| 166 | return NULL; |
| 167 | |
| 168 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 169 | return NULL; |
| 170 | |
| 171 | int nSize = m_XFAPageList.GetSize(); |
| 172 | for (int i = 0; i < nSize; i++) { |
| 173 | CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i); |
| 174 | if (!pTempPage) |
| 175 | continue; |
| 176 | if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage) |
| 177 | return pTempPage; |
| 178 | } |
| 179 | |
| 180 | return NULL; |
| 181 | } |
| 182 | |
| 183 | void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { |
| 184 | m_XFAPageList.SetAt(page->GetPageIndex(), NULL); |
| 185 | } |
| 186 | |
| 187 | CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument( |
| 188 | CPDFDoc_Environment* pFormFillEnv) { |
| 189 | if (!m_pSDKDoc && pFormFillEnv) |
| 190 | m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv); |
| 191 | return m_pSDKDoc; |
| 192 | } |
| 193 | |
| 194 | void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF, |
Tom Sepez | 566b974 | 2016-02-26 13:17:56 -0800 | [diff] [blame^] | 195 | CPDF_Rect& pdfRect) { |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 196 | pdfRect.left = fxRectF.left; |
| 197 | pdfRect.top = fxRectF.bottom(); |
| 198 | pdfRect.right = fxRectF.right(); |
| 199 | pdfRect.bottom = fxRectF.top; |
| 200 | } |
| 201 | |
| 202 | void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) { |
| 203 | if (hDoc == m_pXFADoc && m_pSDKDoc) { |
| 204 | m_pSDKDoc->SetChangeMark(); |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) { |
| 209 | if (hDoc == m_pXFADoc && m_pSDKDoc) |
| 210 | return m_pSDKDoc->GetChangeMark(); |
| 211 | return FALSE; |
| 212 | } |
| 213 | |
| 214 | void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView, |
| 215 | const CFX_RectF& rt, |
| 216 | FX_DWORD dwFlags /* = 0 */) { |
| 217 | if (!m_pXFADoc || !m_pSDKDoc) |
| 218 | return; |
| 219 | |
| 220 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 221 | return; |
| 222 | |
Tom Sepez | 566b974 | 2016-02-26 13:17:56 -0800 | [diff] [blame^] | 223 | CPDF_Rect rcPage; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 224 | FXRect2PDFRect(rt, rcPage); |
| 225 | |
| 226 | CPDFXFA_Page* pPage = GetPage(pPageView); |
| 227 | |
| 228 | if (pPage == NULL) |
| 229 | return; |
| 230 | |
| 231 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 232 | if (!pEnv) |
| 233 | return; |
| 234 | |
| 235 | pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom, |
| 236 | rcPage.right, rcPage.top); |
| 237 | } |
| 238 | |
| 239 | void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget, |
| 240 | FX_DWORD dwFlags /* = 0 */) { |
| 241 | if (!hWidget) |
| 242 | return; |
| 243 | |
| 244 | if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) |
| 245 | return; |
| 246 | |
| 247 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 248 | return; |
| 249 | |
| 250 | IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); |
| 251 | if (!pWidgetHandler) |
| 252 | return; |
| 253 | |
| 254 | IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); |
| 255 | if (!pPageView) |
| 256 | return; |
| 257 | |
| 258 | CFX_RectF rect; |
| 259 | pWidgetHandler->GetRect(hWidget, rect); |
| 260 | InvalidateRect(pPageView, rect, dwFlags); |
| 261 | } |
| 262 | |
| 263 | void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget, |
| 264 | FX_BOOL bVisible, |
| 265 | const CFX_RectF* pRtAnchor) { |
| 266 | if (!hWidget || pRtAnchor == NULL) |
| 267 | return; |
| 268 | |
| 269 | if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView) |
| 270 | return; |
| 271 | |
| 272 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 273 | return; |
| 274 | |
| 275 | IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); |
| 276 | if (!pWidgetHandler) |
| 277 | return; |
| 278 | |
| 279 | IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget); |
| 280 | if (!pPageView) |
| 281 | return; |
| 282 | |
| 283 | CPDFXFA_Page* pPage = GetPage(pPageView); |
| 284 | |
| 285 | if (pPage == NULL) |
| 286 | return; |
| 287 | |
Tom Sepez | 566b974 | 2016-02-26 13:17:56 -0800 | [diff] [blame^] | 288 | CPDF_Rect rcCaret; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 289 | FXRect2PDFRect(*pRtAnchor, rcCaret); |
| 290 | |
| 291 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 292 | if (!pEnv) |
| 293 | return; |
| 294 | |
| 295 | pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top, |
| 296 | rcCaret.right, rcCaret.bottom); |
| 297 | } |
| 298 | |
| 299 | FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget, |
| 300 | FX_FLOAT fMinPopup, |
| 301 | FX_FLOAT fMaxPopup, |
| 302 | const CFX_RectF& rtAnchor, |
| 303 | CFX_RectF& rtPopup) { |
| 304 | if (NULL == hWidget) { |
| 305 | return FALSE; |
| 306 | } |
| 307 | IXFA_PageView* pXFAPageView = |
| 308 | m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); |
| 309 | if (NULL == pXFAPageView) { |
| 310 | return FALSE; |
| 311 | } |
| 312 | CPDFXFA_Page* pPage = GetPage(pXFAPageView); |
| 313 | if (pPage == NULL) |
| 314 | return FALSE; |
| 315 | |
| 316 | CXFA_WidgetAcc* pWidgetAcc = |
| 317 | m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget); |
| 318 | |
| 319 | int nRotate = 0; |
| 320 | #ifdef PDF_ENABLE_XFA |
| 321 | nRotate = pWidgetAcc->GetRotate(); |
| 322 | #endif |
| 323 | |
| 324 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 325 | if (pEnv == NULL) |
| 326 | return FALSE; |
| 327 | FS_RECTF pageViewRect; |
| 328 | pEnv->FFI_GetPageViewRect(pPage, pageViewRect); |
| 329 | |
Tom Sepez | 566b974 | 2016-02-26 13:17:56 -0800 | [diff] [blame^] | 330 | CPDF_Rect rcAnchor; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 331 | |
| 332 | rcAnchor.left = rtAnchor.left; |
| 333 | rcAnchor.top = rtAnchor.bottom(); |
| 334 | rcAnchor.right = rtAnchor.right(); |
| 335 | rcAnchor.bottom = rtAnchor.top; |
| 336 | |
| 337 | int t1, t2, t; |
| 338 | FX_DWORD dwPos; |
| 339 | FX_FLOAT fPoupHeight; |
| 340 | switch (nRotate) { |
| 341 | case 90: { |
| 342 | t1 = (int)(pageViewRect.right - rcAnchor.right); |
| 343 | t2 = (int)(rcAnchor.left - pageViewRect.left); |
| 344 | if (rcAnchor.bottom < pageViewRect.bottom) { |
| 345 | rtPopup.left += rcAnchor.bottom - pageViewRect.bottom; |
| 346 | } |
| 347 | |
| 348 | break; |
| 349 | } |
| 350 | |
| 351 | case 180: { |
| 352 | t2 = (int)(pageViewRect.top - rcAnchor.top); |
| 353 | t1 = (int)(rcAnchor.bottom - pageViewRect.bottom); |
| 354 | if (rcAnchor.left < pageViewRect.left) { |
| 355 | rtPopup.left += rcAnchor.left - pageViewRect.left; |
| 356 | } |
| 357 | break; |
| 358 | } |
| 359 | case 270: { |
| 360 | t1 = (int)(rcAnchor.left - pageViewRect.left); |
| 361 | t2 = (int)(pageViewRect.right - rcAnchor.right); |
| 362 | |
| 363 | if (rcAnchor.top > pageViewRect.top) { |
| 364 | rtPopup.left -= rcAnchor.top - pageViewRect.top; |
| 365 | } |
| 366 | break; |
| 367 | } |
| 368 | case 0: |
| 369 | default: { |
| 370 | t1 = (int)(pageViewRect.top - rcAnchor.top); |
| 371 | t2 = (int)(rcAnchor.bottom - pageViewRect.bottom); |
| 372 | if (rcAnchor.right > pageViewRect.right) { |
| 373 | rtPopup.left -= rcAnchor.right - pageViewRect.right; |
| 374 | } |
| 375 | break; |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | if (t1 <= 0 && t2 <= 0) { |
| 380 | return FALSE; |
| 381 | } |
| 382 | if (t1 <= 0) { |
| 383 | t = t2; |
| 384 | dwPos = 1; |
| 385 | } else if (t2 <= 0) { |
| 386 | t = t1; |
| 387 | dwPos = 0; |
| 388 | } else if (t1 > t2) { |
| 389 | t = t1; |
| 390 | dwPos = 0; |
| 391 | } else { |
| 392 | t = t2; |
| 393 | dwPos = 1; |
| 394 | } |
| 395 | if (t < fMinPopup) { |
| 396 | fPoupHeight = fMinPopup; |
| 397 | } else if (t > fMaxPopup) { |
| 398 | fPoupHeight = fMaxPopup; |
| 399 | } else { |
| 400 | fPoupHeight = (FX_FLOAT)t; |
| 401 | } |
| 402 | |
| 403 | switch (nRotate) { |
| 404 | case 0: |
| 405 | case 180: { |
| 406 | if (dwPos == 0) { |
| 407 | rtPopup.top = rtAnchor.height; |
| 408 | rtPopup.height = fPoupHeight; |
| 409 | } else { |
| 410 | rtPopup.top = -fPoupHeight; |
| 411 | rtPopup.height = fPoupHeight; |
| 412 | } |
| 413 | break; |
| 414 | } |
| 415 | case 90: |
| 416 | case 270: { |
| 417 | if (dwPos == 0) { |
| 418 | rtPopup.top = rtAnchor.width; |
| 419 | rtPopup.height = fPoupHeight; |
| 420 | } else { |
| 421 | rtPopup.top = -fPoupHeight; |
| 422 | rtPopup.height = fPoupHeight; |
| 423 | } |
| 424 | break; |
| 425 | } |
| 426 | default: |
| 427 | break; |
| 428 | } |
| 429 | |
| 430 | return TRUE; |
| 431 | } |
| 432 | |
| 433 | FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget, |
| 434 | CFX_PointF ptPopup, |
| 435 | const CFX_RectF* pRectExclude) { |
| 436 | if (NULL == hWidget) { |
| 437 | return FALSE; |
| 438 | } |
| 439 | IXFA_PageView* pXFAPageView = |
| 440 | m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); |
| 441 | if (pXFAPageView == NULL) |
| 442 | return FALSE; |
| 443 | CPDFXFA_Page* pPage = GetPage(pXFAPageView); |
| 444 | |
| 445 | if (pPage == NULL) |
| 446 | return FALSE; |
| 447 | |
| 448 | int menuFlag = 0; |
| 449 | |
| 450 | IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler(); |
| 451 | if (pXFAMenuHander->CanUndo(hWidget)) |
| 452 | menuFlag |= FXFA_MEMU_UNDO; |
| 453 | if (pXFAMenuHander->CanRedo(hWidget)) |
| 454 | menuFlag |= FXFA_MEMU_REDO; |
| 455 | if (pXFAMenuHander->CanPaste(hWidget)) |
| 456 | menuFlag |= FXFA_MEMU_PASTE; |
| 457 | if (pXFAMenuHander->CanCopy(hWidget)) |
| 458 | menuFlag |= FXFA_MEMU_COPY; |
| 459 | if (pXFAMenuHander->CanCut(hWidget)) |
| 460 | menuFlag |= FXFA_MEMU_CUT; |
| 461 | if (pXFAMenuHander->CanSelectAll(hWidget)) |
| 462 | menuFlag |= FXFA_MEMU_SELECTALL; |
| 463 | |
| 464 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 465 | if (pEnv == NULL) |
| 466 | return FALSE; |
| 467 | |
| 468 | return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL); |
| 469 | } |
| 470 | |
| 471 | void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView, |
| 472 | FX_DWORD dwFlags) { |
| 473 | if (!pPageView || (dwFlags != XFA_PAGEVIEWEVENT_PostAdded && |
| 474 | dwFlags != XFA_PAGEVIEWEVENT_PostRemoved)) { |
| 475 | return; |
| 476 | } |
| 477 | CPDFXFA_Page* pPage = nullptr; |
Jun Fang | c30d5bf | 2016-02-02 18:12:23 -0800 | [diff] [blame] | 478 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 479 | if (dwFlags == XFA_PAGEVIEWEVENT_PostAdded) { |
Jun Fang | c30d5bf | 2016-02-02 18:12:23 -0800 | [diff] [blame] | 480 | int nPageIndex = pPageView->GetPageViewIndex(); |
| 481 | pPage = GetPage(nPageIndex); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 482 | if (pPage) |
| 483 | pPage->SetXFAPageView(pPageView); |
Jun Fang | c30d5bf | 2016-02-02 18:12:23 -0800 | [diff] [blame] | 484 | pEnv->FFI_PageEvent(nPageIndex, dwFlags); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 485 | return; |
| 486 | } |
| 487 | pPage = GetPage(pPageView); |
| 488 | if (!pPage) |
| 489 | return; |
Jun Fang | c30d5bf | 2016-02-02 18:12:23 -0800 | [diff] [blame] | 490 | pEnv->FFI_PageEvent(pPage->GetPageIndex(), dwFlags); |
Jun Fang | c30d5bf | 2016-02-02 18:12:23 -0800 | [diff] [blame] | 491 | pPage->Release(); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 492 | } |
| 493 | |
| 494 | void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget, |
| 495 | CXFA_WidgetAcc* pWidgetData, |
| 496 | FX_DWORD dwEvent, |
| 497 | void* pParam, |
| 498 | void* pAdditional) { |
| 499 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget) |
| 500 | return; |
| 501 | |
| 502 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 503 | if (!pEnv) |
| 504 | return; |
| 505 | |
| 506 | IXFA_PageView* pPageView = |
| 507 | m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget); |
| 508 | if (pPageView == NULL) |
| 509 | return; |
| 510 | |
| 511 | CPDFXFA_Page* pXFAPage = GetPage(pPageView); |
| 512 | if (pXFAPage == NULL) |
| 513 | return; |
| 514 | |
| 515 | CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage); |
| 516 | if (dwEvent == XFA_WIDGETEVENT_PostAdded) { |
| 517 | pSdkPageView->AddAnnot(hWidget); |
| 518 | |
| 519 | } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) { |
| 520 | CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget); |
| 521 | if (pAnnot) { |
| 522 | pSdkPageView->DeleteAnnot(pAnnot); |
| 523 | } |
| 524 | } |
| 525 | } |
| 526 | |
| 527 | int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) { |
| 528 | if (hDoc == m_pXFADoc && m_pSDKDoc) { |
| 529 | return GetPageCount(); |
| 530 | } |
| 531 | return 0; |
| 532 | } |
| 533 | int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) { |
| 534 | if (hDoc != m_pXFADoc || !m_pSDKDoc) |
| 535 | return -1; |
| 536 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 537 | return -1; |
| 538 | |
| 539 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 540 | if (pEnv == NULL) |
| 541 | return -1; |
| 542 | |
| 543 | return pEnv->FFI_GetCurrentPageIndex(this); |
| 544 | } |
| 545 | void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) { |
Jun Fang | 8878029 | 2016-02-02 17:19:57 -0800 | [diff] [blame] | 546 | if (hDoc != m_pXFADoc || !m_pSDKDoc || m_iDocType != DOCTYPE_DYNAMIC_XFA || |
| 547 | iCurPage < 0 || iCurPage >= m_pSDKDoc->GetPageCount()) { |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 548 | return; |
Jun Fang | 8878029 | 2016-02-02 17:19:57 -0800 | [diff] [blame] | 549 | } |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 550 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
Jun Fang | 8878029 | 2016-02-02 17:19:57 -0800 | [diff] [blame] | 551 | if (!pEnv) |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 552 | return; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 553 | pEnv->FFI_SetCurrentPage(this, iCurPage); |
| 554 | } |
| 555 | FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) { |
| 556 | if (hDoc != m_pXFADoc || !m_pSDKDoc) |
| 557 | return FALSE; |
| 558 | if (m_pSDKDoc->GetInterForm()) |
| 559 | return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled(); |
| 560 | |
| 561 | return FALSE; |
| 562 | } |
| 563 | void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc, |
| 564 | FX_BOOL bEnabled) { |
| 565 | if (hDoc != m_pXFADoc || !m_pSDKDoc) |
| 566 | return; |
| 567 | if (m_pSDKDoc->GetInterForm()) |
| 568 | m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled); |
| 569 | } |
| 570 | |
| 571 | void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) { |
| 572 | if (hDoc != m_pXFADoc) |
| 573 | return; |
| 574 | if (m_pPDFDoc == NULL) |
| 575 | return; |
| 576 | CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); |
| 577 | |
| 578 | if (pInfoDict == NULL) |
| 579 | return; |
| 580 | |
Wei Li | 9b76113 | 2016-01-29 15:44:20 -0800 | [diff] [blame] | 581 | CFX_ByteString csTitle = pInfoDict->GetStringBy("Title"); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 582 | wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength())); |
| 583 | csTitle.ReleaseBuffer(csTitle.GetLength()); |
| 584 | } |
| 585 | void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc, |
| 586 | const CFX_WideStringC& wsTitle) { |
| 587 | if (hDoc != m_pXFADoc) |
| 588 | return; |
| 589 | if (m_pPDFDoc == NULL) |
| 590 | return; |
| 591 | CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo(); |
| 592 | |
| 593 | if (pInfoDict == NULL) |
| 594 | return; |
| 595 | pInfoDict->SetAt("Title", new CPDF_String(wsTitle)); |
| 596 | } |
| 597 | void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc, |
| 598 | const CFX_WideStringC& wsFilePath, |
| 599 | FX_BOOL bXDP) { |
| 600 | if (hDoc != m_pXFADoc) |
| 601 | return; |
| 602 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) |
| 603 | return; |
| 604 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 605 | if (pEnv == NULL) |
| 606 | return; |
| 607 | int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML; |
| 608 | CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode(); |
| 609 | |
| 610 | if (wsFilePath.IsEmpty()) { |
| 611 | if (!pEnv->GetFormFillInfo() || |
| 612 | pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) |
| 613 | return; |
| 614 | CFX_WideString filepath = pEnv->JS_fieldBrowse(); |
| 615 | bs = filepath.UTF16LE_Encode(); |
| 616 | } |
| 617 | int len = bs.GetLength() / sizeof(unsigned short); |
| 618 | FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( |
| 619 | bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML, |
| 620 | (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb"); |
| 621 | bs.ReleaseBuffer(len * sizeof(unsigned short)); |
| 622 | |
| 623 | if (pFileHandler == NULL) |
| 624 | return; |
| 625 | |
| 626 | CFPDF_FileStream fileWrite(pFileHandler); |
| 627 | |
| 628 | IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler(); |
| 629 | CFX_ByteString content; |
| 630 | if (fileType == FXFA_SAVEAS_XML) { |
| 631 | content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"; |
| 632 | fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), |
| 633 | content.GetLength()); |
| 634 | CFX_WideStringC data(L"data"); |
| 635 | if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) { |
| 636 | // TODO: Maybe report error. |
| 637 | } |
| 638 | } else if (fileType == FXFA_SAVEAS_XDP) { |
| 639 | if (m_pPDFDoc == NULL) |
| 640 | return; |
| 641 | CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); |
| 642 | if (pRoot == NULL) |
| 643 | return; |
Wei Li | 9b76113 | 2016-01-29 15:44:20 -0800 | [diff] [blame] | 644 | CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 645 | if (NULL == pAcroForm) |
| 646 | return; |
| 647 | CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); |
| 648 | if (pXFA == NULL) |
| 649 | return; |
| 650 | if (!pXFA->IsArray()) |
| 651 | return; |
| 652 | CPDF_Array* pArray = pXFA->GetArray(); |
| 653 | if (NULL == pArray) |
| 654 | return; |
| 655 | int size = pArray->GetCount(); |
| 656 | for (int i = 1; i < size; i += 2) { |
| 657 | CPDF_Object* pPDFObj = pArray->GetElement(i); |
| 658 | CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); |
| 659 | if (!pPrePDFObj->IsString()) |
| 660 | continue; |
| 661 | if (!pPDFObj->IsReference()) |
| 662 | continue; |
| 663 | CPDF_Object* pDirectObj = pPDFObj->GetDirect(); |
| 664 | if (!pDirectObj->IsStream()) |
| 665 | continue; |
| 666 | if (pPrePDFObj->GetString() == "form") { |
| 667 | CFX_WideStringC form(L"form"); |
| 668 | pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite); |
| 669 | } else if (pPrePDFObj->GetString() == "datasets") { |
| 670 | CFX_WideStringC datasets(L"datasets"); |
| 671 | pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets, |
| 672 | &fileWrite); |
| 673 | } else { |
| 674 | if (i == size - 1) { |
| 675 | CFX_WideString wPath = CFX_WideString::FromUTF16LE( |
| 676 | (unsigned short*)(const FX_CHAR*)bs, |
| 677 | bs.GetLength() / sizeof(unsigned short)); |
| 678 | CFX_ByteString bPath = wPath.UTF8Encode(); |
| 679 | CFX_ByteString szFormat = |
| 680 | "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>"; |
| 681 | content.Format(szFormat, (char*)(const FX_CHAR*)bPath); |
| 682 | fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(), |
| 683 | content.GetLength()); |
| 684 | } |
| 685 | |
| 686 | CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj; |
| 687 | CPDF_StreamAcc* pAcc = new CPDF_StreamAcc; |
| 688 | pAcc->LoadAllData(pStream); |
| 689 | fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(), |
| 690 | pAcc->GetSize()); |
| 691 | delete pAcc; |
| 692 | } |
| 693 | } |
| 694 | } |
| 695 | if (!fileWrite.Flush()) { |
| 696 | // TODO: Report error. |
| 697 | } |
| 698 | } |
| 699 | void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc, |
| 700 | const CFX_WideStringC& wsFilePath) { |
Dan Sinclair | 50cce60 | 2016-02-24 09:51:16 -0500 | [diff] [blame] | 701 | // TODO ... |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 702 | } |
| 703 | |
| 704 | void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc, |
| 705 | const CFX_WideStringC& bsURL, |
| 706 | FX_BOOL bAppend) { |
| 707 | if (hDoc != m_pXFADoc) |
| 708 | return; |
| 709 | |
| 710 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA) |
| 711 | return; |
| 712 | |
| 713 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 714 | if (pEnv == NULL) |
| 715 | return; |
| 716 | |
| 717 | CFX_WideStringC str(bsURL.GetPtr()); |
| 718 | |
| 719 | pEnv->FFI_GotoURL(this, str, bAppend); |
| 720 | } |
| 721 | |
| 722 | FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) { |
| 723 | if (hDoc != m_pXFADoc || !m_pSDKDoc) |
| 724 | return FALSE; |
| 725 | if (m_pSDKDoc->GetInterForm()) |
| 726 | return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled(); |
| 727 | |
| 728 | return TRUE; |
| 729 | } |
| 730 | void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) { |
| 731 | if (hDoc != m_pXFADoc || !m_pSDKDoc) |
| 732 | return; |
| 733 | if (m_pSDKDoc->GetInterForm()) |
| 734 | m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled); |
| 735 | } |
| 736 | void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) { |
| 737 | if (hDoc != m_pXFADoc) |
| 738 | return; |
| 739 | |
| 740 | if (NULL == hWidget) { |
| 741 | m_pSDKDoc->SetFocusAnnot(NULL); |
| 742 | return; |
| 743 | } |
| 744 | |
| 745 | int pageViewCount = m_pSDKDoc->GetPageViewCount(); |
| 746 | for (int i = 0; i < pageViewCount; i++) { |
| 747 | CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i); |
| 748 | if (pPageView == NULL) |
| 749 | continue; |
| 750 | CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget); |
| 751 | if (pAnnot) { |
| 752 | m_pSDKDoc->SetFocusAnnot(pAnnot); |
| 753 | break; |
| 754 | } |
| 755 | } |
| 756 | } |
| 757 | void CPDFXFA_Document::Print(IXFA_Doc* hDoc, |
| 758 | int32_t nStartPage, |
| 759 | int32_t nEndPage, |
| 760 | FX_DWORD dwOptions) { |
| 761 | if (hDoc != m_pXFADoc) |
| 762 | return; |
| 763 | |
| 764 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 765 | if (pEnv == NULL) |
| 766 | return; |
| 767 | |
| 768 | if (!pEnv->GetFormFillInfo() || |
| 769 | pEnv->GetFormFillInfo()->m_pJsPlatform == NULL) |
| 770 | return; |
| 771 | if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL) |
| 772 | return; |
| 773 | pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print( |
| 774 | pEnv->GetFormFillInfo()->m_pJsPlatform, |
| 775 | dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage, |
| 776 | dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage, |
| 777 | dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder, |
| 778 | dwOptions & XFA_PRINTOPT_PrintAnnot); |
| 779 | } |
| 780 | |
| 781 | void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) { |
| 782 | if (hDoc != m_pXFADoc) |
| 783 | return; |
| 784 | |
| 785 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 786 | if (pEnv == NULL) |
| 787 | return; |
| 788 | |
| 789 | pEnv->FFI_GetURL(this, wsDocURL); |
| 790 | } |
| 791 | |
| 792 | FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) { |
| 793 | if (hDoc != m_pXFADoc) |
| 794 | return 0; |
| 795 | if (m_pSDKDoc) { |
| 796 | if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) { |
| 797 | FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA); |
| 798 | uint8_t alpha = pInterForm->GetHighlightAlpha(); |
| 799 | FX_ARGB argb = ArgbEncode((int)alpha, color); |
| 800 | return argb; |
| 801 | } |
| 802 | } |
| 803 | return 0; |
| 804 | } |
| 805 | |
| 806 | FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) { |
| 807 | if (bPrevOrPost) |
| 808 | return _OnBeforeNotifySumbit(); |
| 809 | |
| 810 | _OnAfterNotifySumbit(); |
| 811 | return TRUE; |
| 812 | } |
| 813 | |
| 814 | FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() { |
| 815 | #ifdef PDF_ENABLE_XFA |
| 816 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) |
| 817 | return TRUE; |
| 818 | if (m_pXFADocView == NULL) |
| 819 | return TRUE; |
| 820 | IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); |
| 821 | if (pWidgetHandler == NULL) |
| 822 | return TRUE; |
| 823 | IXFA_WidgetAccIterator* pWidgetAccIterator = |
| 824 | m_pXFADocView->CreateWidgetAccIterator(); |
| 825 | if (pWidgetAccIterator) { |
| 826 | CXFA_EventParam Param; |
| 827 | Param.m_eType = XFA_EVENT_PreSubmit; |
| 828 | CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 829 | while (pWidgetAcc) { |
| 830 | pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); |
| 831 | pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 832 | } |
| 833 | pWidgetAccIterator->Release(); |
| 834 | } |
| 835 | pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator(); |
| 836 | if (pWidgetAccIterator) { |
| 837 | CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 838 | pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 839 | while (pWidgetAcc) { |
| 840 | int fRet = pWidgetAcc->ProcessValidate(-1); |
| 841 | if (fRet == XFA_EVENTERROR_Error) { |
| 842 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 843 | if (pEnv == NULL) |
| 844 | return FALSE; |
| 845 | CFX_WideString ws; |
| 846 | ws.FromLocal(IDS_XFA_Validate_Input); |
| 847 | CFX_ByteString bs = ws.UTF16LE_Encode(); |
| 848 | int len = bs.GetLength() / sizeof(unsigned short); |
| 849 | pEnv->FFI_Alert( |
| 850 | (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), |
| 851 | (FPDF_WIDESTRING)L"", 0, 1); |
| 852 | bs.ReleaseBuffer(len * sizeof(unsigned short)); |
| 853 | pWidgetAccIterator->Release(); |
| 854 | return FALSE; |
| 855 | } |
| 856 | pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 857 | } |
| 858 | pWidgetAccIterator->Release(); |
| 859 | m_pXFADocView->UpdateDocView(); |
| 860 | } |
| 861 | #endif |
| 862 | return TRUE; |
| 863 | } |
| 864 | void CPDFXFA_Document::_OnAfterNotifySumbit() { |
| 865 | if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA) |
| 866 | return; |
| 867 | if (m_pXFADocView == NULL) |
| 868 | return; |
| 869 | IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler(); |
| 870 | if (pWidgetHandler == NULL) |
| 871 | return; |
| 872 | IXFA_WidgetAccIterator* pWidgetAccIterator = |
| 873 | m_pXFADocView->CreateWidgetAccIterator(); |
| 874 | if (pWidgetAccIterator == NULL) |
| 875 | return; |
| 876 | CXFA_EventParam Param; |
| 877 | Param.m_eType = XFA_EVENT_PostSubmit; |
| 878 | |
| 879 | CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 880 | while (pWidgetAcc) { |
| 881 | pWidgetHandler->ProcessEvent(pWidgetAcc, &Param); |
| 882 | pWidgetAcc = pWidgetAccIterator->MoveToNext(); |
| 883 | } |
| 884 | pWidgetAccIterator->Release(); |
| 885 | m_pXFADocView->UpdateDocView(); |
| 886 | } |
| 887 | |
| 888 | FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { |
| 889 | if (!_NotifySubmit(TRUE)) |
| 890 | return FALSE; |
| 891 | if (NULL == m_pXFADocView) |
| 892 | return FALSE; |
| 893 | m_pXFADocView->UpdateDocView(); |
| 894 | |
| 895 | FX_BOOL ret = _SubmitData(hDoc, submit); |
| 896 | _NotifySubmit(FALSE); |
| 897 | return ret; |
| 898 | } |
| 899 | |
| 900 | IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc, |
| 901 | const CFX_WideString& wsLink) { |
| 902 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 903 | if (pEnv == NULL) |
| 904 | return FALSE; |
| 905 | CFX_ByteString bs = wsLink.UTF16LE_Encode(); |
| 906 | int len = bs.GetLength() / sizeof(unsigned short); |
| 907 | FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile( |
| 908 | 0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb"); |
| 909 | bs.ReleaseBuffer(len * sizeof(unsigned short)); |
| 910 | |
| 911 | if (pFileHandler == NULL) |
| 912 | return NULL; |
| 913 | return new CFPDF_FileStream(pFileHandler); |
| 914 | } |
| 915 | FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler, |
| 916 | int fileType, |
| 917 | FPDF_DWORD encodeType, |
| 918 | FPDF_DWORD flag) { |
| 919 | if (NULL == m_pXFADocView) |
| 920 | return FALSE; |
| 921 | IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler(); |
| 922 | CFX_ByteString content; |
| 923 | |
| 924 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 925 | if (pEnv == NULL) |
| 926 | return FALSE; |
| 927 | |
| 928 | CFPDF_FileStream fileStream(pFileHandler); |
| 929 | |
| 930 | if (fileType == FXFA_SAVEAS_XML) { |
| 931 | CFX_WideString ws; |
| 932 | ws.FromLocal("data"); |
| 933 | CFX_ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"; |
| 934 | fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength()); |
| 935 | pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); |
| 936 | } else if (fileType == FXFA_SAVEAS_XDP) { |
| 937 | if (flag == 0) |
| 938 | flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | |
| 939 | FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; |
| 940 | if (m_pPDFDoc == NULL) { |
| 941 | fileStream.Flush(); |
| 942 | return FALSE; |
| 943 | } |
| 944 | CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot(); |
| 945 | if (pRoot == NULL) { |
| 946 | fileStream.Flush(); |
| 947 | return FALSE; |
| 948 | } |
Wei Li | 9b76113 | 2016-01-29 15:44:20 -0800 | [diff] [blame] | 949 | CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 950 | if (NULL == pAcroForm) { |
| 951 | fileStream.Flush(); |
| 952 | return FALSE; |
| 953 | } |
| 954 | CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); |
| 955 | if (pXFA == NULL) { |
| 956 | fileStream.Flush(); |
| 957 | return FALSE; |
| 958 | } |
| 959 | if (!pXFA->IsArray()) { |
| 960 | fileStream.Flush(); |
| 961 | return FALSE; |
| 962 | } |
| 963 | CPDF_Array* pArray = pXFA->GetArray(); |
| 964 | if (NULL == pArray) { |
| 965 | fileStream.Flush(); |
| 966 | return FALSE; |
| 967 | } |
| 968 | int size = pArray->GetCount(); |
| 969 | for (int i = 1; i < size; i += 2) { |
| 970 | CPDF_Object* pPDFObj = pArray->GetElement(i); |
| 971 | CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1); |
| 972 | if (!pPrePDFObj->IsString()) |
| 973 | continue; |
| 974 | if (!pPDFObj->IsReference()) |
| 975 | continue; |
| 976 | CPDF_Object* pDirectObj = pPDFObj->GetDirect(); |
| 977 | if (!pDirectObj->IsStream()) |
| 978 | continue; |
| 979 | if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG)) |
| 980 | continue; |
| 981 | if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE)) |
| 982 | continue; |
| 983 | if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET)) |
| 984 | continue; |
| 985 | if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS)) |
| 986 | continue; |
| 987 | if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA)) |
| 988 | continue; |
| 989 | if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF)) |
| 990 | continue; |
| 991 | if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM)) |
| 992 | continue; |
| 993 | if (pPrePDFObj->GetString() == "form") { |
| 994 | CFX_WideString ws; |
| 995 | ws.FromLocal("form"); |
| 996 | pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); |
| 997 | } else if (pPrePDFObj->GetString() == "datasets") { |
| 998 | CFX_WideString ws; |
| 999 | ws.FromLocal("datasets"); |
| 1000 | pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream); |
| 1001 | } else { |
| 1002 | // PDF,creator. |
| 1003 | // TODO: |
| 1004 | } |
| 1005 | } |
| 1006 | } |
| 1007 | return TRUE; |
| 1008 | } |
| 1009 | |
| 1010 | void CPDFXFA_Document::_ClearChangeMark() { |
| 1011 | if (m_pSDKDoc) |
| 1012 | m_pSDKDoc->ClearChangeMark(); |
| 1013 | } |
| 1014 | |
| 1015 | void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent, |
| 1016 | FPDF_DWORD& flag) { |
| 1017 | if (csSrcContent.Find(L" config ", 0) != -1) |
| 1018 | flag |= FXFA_CONFIG; |
| 1019 | if (csSrcContent.Find(L" template ", 0) != -1) |
| 1020 | flag |= FXFA_TEMPLATE; |
| 1021 | if (csSrcContent.Find(L" localeSet ", 0) != -1) |
| 1022 | flag |= FXFA_LOCALESET; |
| 1023 | if (csSrcContent.Find(L" datasets ", 0) != -1) |
| 1024 | flag |= FXFA_DATASETS; |
| 1025 | if (csSrcContent.Find(L" xmpmeta ", 0) != -1) |
| 1026 | flag |= FXFA_XMPMETA; |
| 1027 | if (csSrcContent.Find(L" xfdf ", 0) != -1) |
| 1028 | flag |= FXFA_XFDF; |
| 1029 | if (csSrcContent.Find(L" form ", 0) != -1) |
| 1030 | flag |= FXFA_FORM; |
| 1031 | if (flag == 0) |
| 1032 | flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS | |
| 1033 | FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM; |
| 1034 | } |
| 1035 | FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL, |
| 1036 | CFX_WideString& csToAddress, |
| 1037 | CFX_WideString& csCCAddress, |
| 1038 | CFX_WideString& csBCCAddress, |
| 1039 | CFX_WideString& csSubject, |
| 1040 | CFX_WideString& csMsg) { |
| 1041 | CFX_WideString srcURL = csURL; |
| 1042 | srcURL.TrimLeft(); |
| 1043 | if (0 != srcURL.Left(7).CompareNoCase(L"mailto:")) |
| 1044 | return FALSE; |
| 1045 | int pos = srcURL.Find(L'?', 0); |
| 1046 | CFX_WideString tmp; |
| 1047 | if (pos == -1) { |
| 1048 | pos = srcURL.Find(L'@', 0); |
| 1049 | if (pos == -1) |
| 1050 | return FALSE; |
| 1051 | else { |
| 1052 | tmp = srcURL.Right(csURL.GetLength() - 7); |
| 1053 | tmp.TrimLeft(); |
| 1054 | tmp.TrimRight(); |
| 1055 | } |
| 1056 | } else { |
| 1057 | tmp = srcURL.Left(pos); |
| 1058 | tmp = tmp.Right(tmp.GetLength() - 7); |
| 1059 | tmp.TrimLeft(); |
| 1060 | tmp.TrimRight(); |
| 1061 | } |
| 1062 | |
| 1063 | csToAddress = tmp; |
| 1064 | |
| 1065 | srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1)); |
| 1066 | while (!srcURL.IsEmpty()) { |
| 1067 | srcURL.TrimLeft(); |
| 1068 | srcURL.TrimRight(); |
| 1069 | pos = srcURL.Find(L'&', 0); |
| 1070 | if (pos == -1) |
| 1071 | tmp = srcURL; |
| 1072 | else |
| 1073 | tmp = srcURL.Left(pos); |
| 1074 | |
| 1075 | tmp.TrimLeft(); |
| 1076 | tmp.TrimRight(); |
| 1077 | if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) { |
| 1078 | tmp = tmp.Right(tmp.GetLength() - 3); |
| 1079 | if (!csCCAddress.IsEmpty()) |
| 1080 | csCCAddress += L';'; |
| 1081 | csCCAddress += tmp; |
| 1082 | |
| 1083 | } else if (tmp.GetLength() >= 4 && |
| 1084 | 0 == tmp.Left(4).CompareNoCase(L"bcc=")) { |
| 1085 | tmp = tmp.Right(tmp.GetLength() - 4); |
| 1086 | if (!csBCCAddress.IsEmpty()) |
| 1087 | csBCCAddress += L';'; |
| 1088 | csBCCAddress += tmp; |
| 1089 | } else if (tmp.GetLength() >= 8 && |
| 1090 | 0 == tmp.Left(8).CompareNoCase(L"subject=")) { |
| 1091 | tmp = tmp.Right(tmp.GetLength() - 8); |
| 1092 | csSubject += tmp; |
| 1093 | } else if (tmp.GetLength() >= 5 && |
| 1094 | 0 == tmp.Left(5).CompareNoCase(L"body=")) { |
| 1095 | tmp = tmp.Right(tmp.GetLength() - 5); |
| 1096 | csMsg += tmp; |
| 1097 | } |
| 1098 | if (pos == -1) |
| 1099 | srcURL = L""; |
| 1100 | else |
| 1101 | srcURL = srcURL.Right(csURL.GetLength() - (pos + 1)); |
| 1102 | } |
| 1103 | csToAddress.Replace(L",", L";"); |
| 1104 | csCCAddress.Replace(L",", L";"); |
| 1105 | csBCCAddress.Replace(L",", L";"); |
| 1106 | return TRUE; |
| 1107 | } |
| 1108 | |
| 1109 | FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) { |
| 1110 | #ifdef PDF_ENABLE_XFA |
Jun Fang | ef86dcd | 2016-02-02 17:33:37 -0800 | [diff] [blame] | 1111 | CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv(); |
| 1112 | if (!pEnv) |
| 1113 | return FALSE; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1114 | CFX_WideStringC csURLC; |
| 1115 | submit.GetSubmitTarget(csURLC); |
| 1116 | CFX_WideString csURL = csURLC; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1117 | if (csURL.IsEmpty()) { |
| 1118 | CFX_WideString ws; |
| 1119 | ws.FromLocal("Submit cancelled."); |
| 1120 | CFX_ByteString bs = ws.UTF16LE_Encode(); |
| 1121 | int len = bs.GetLength() / sizeof(unsigned short); |
| 1122 | pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), |
| 1123 | (FPDF_WIDESTRING)L"", 0, 4); |
| 1124 | bs.ReleaseBuffer(len * sizeof(unsigned short)); |
| 1125 | return FALSE; |
| 1126 | } |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1127 | FPDF_BOOL bRet = TRUE; |
Jun Fang | ef86dcd | 2016-02-02 17:33:37 -0800 | [diff] [blame] | 1128 | FPDF_FILEHANDLER* pFileHandler = nullptr; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1129 | int fileFlag = -1; |
Jun Fang | ef86dcd | 2016-02-02 17:33:37 -0800 | [diff] [blame] | 1130 | switch (submit.GetSubmitFormat()) { |
| 1131 | case XFA_ATTRIBUTEENUM_Xdp: { |
| 1132 | CFX_WideStringC csContentC; |
| 1133 | submit.GetSubmitXDPContent(csContentC); |
| 1134 | CFX_WideString csContent; |
| 1135 | csContent = csContentC; |
| 1136 | csContent.TrimLeft(); |
| 1137 | csContent.TrimRight(); |
| 1138 | CFX_WideString space; |
| 1139 | space.FromLocal(" "); |
| 1140 | csContent = space + csContent + space; |
| 1141 | FPDF_DWORD flag = 0; |
| 1142 | if (submit.IsSubmitEmbedPDF()) |
| 1143 | flag |= FXFA_PDF; |
| 1144 | _ToXFAContentFlags(csContent, flag); |
| 1145 | pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb"); |
| 1146 | fileFlag = FXFA_SAVEAS_XDP; |
| 1147 | _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag); |
| 1148 | break; |
| 1149 | } |
| 1150 | case XFA_ATTRIBUTEENUM_Xml: |
| 1151 | pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, nullptr, "wb"); |
| 1152 | fileFlag = FXFA_SAVEAS_XML; |
| 1153 | _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); |
| 1154 | break; |
| 1155 | case XFA_ATTRIBUTEENUM_Pdf: |
| 1156 | break; |
| 1157 | case XFA_ATTRIBUTEENUM_Urlencoded: |
| 1158 | pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, nullptr, "wb"); |
| 1159 | fileFlag = FXFA_SAVEAS_XML; |
| 1160 | _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0); |
| 1161 | break; |
| 1162 | default: |
| 1163 | return false; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1164 | } |
Jun Fang | ef86dcd | 2016-02-02 17:33:37 -0800 | [diff] [blame] | 1165 | if (!pFileHandler) |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1166 | return FALSE; |
| 1167 | if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) { |
| 1168 | CFX_WideString csToAddress; |
| 1169 | CFX_WideString csCCAddress; |
| 1170 | CFX_WideString csBCCAddress; |
| 1171 | CFX_WideString csSubject; |
| 1172 | CFX_WideString csMsg; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1173 | bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject, |
| 1174 | csMsg); |
Jun Fang | ef86dcd | 2016-02-02 17:33:37 -0800 | [diff] [blame] | 1175 | if (!bRet) |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1176 | return FALSE; |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1177 | CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode(); |
| 1178 | CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode(); |
| 1179 | CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode(); |
| 1180 | CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode(); |
| 1181 | CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode(); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1182 | FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength()); |
| 1183 | FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength()); |
| 1184 | FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength()); |
| 1185 | FPDF_WIDESTRING pSubject = |
| 1186 | (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength()); |
| 1187 | FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength()); |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1188 | pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg); |
| 1189 | bsTo.ReleaseBuffer(); |
| 1190 | bsCC.ReleaseBuffer(); |
| 1191 | bsBcc.ReleaseBuffer(); |
| 1192 | bsSubject.ReleaseBuffer(); |
| 1193 | bsMsg.ReleaseBuffer(); |
| 1194 | } else { |
| 1195 | // http¡¢ftp |
| 1196 | CFX_WideString ws; |
| 1197 | CFX_ByteString bs = csURL.UTF16LE_Encode(); |
| 1198 | int len = bs.GetLength() / sizeof(unsigned short); |
| 1199 | pEnv->FFI_UploadTo( |
| 1200 | pFileHandler, fileFlag, |
| 1201 | (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short))); |
| 1202 | bs.ReleaseBuffer(len * sizeof(unsigned short)); |
| 1203 | } |
Lei Zhang | 9429368 | 2016-01-27 18:27:56 -0800 | [diff] [blame] | 1204 | return bRet; |
| 1205 | #else |
| 1206 | return TRUE; |
| 1207 | #endif |
| 1208 | } |
| 1209 | |
| 1210 | FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc, |
| 1211 | const CFX_ByteStringC& szPropName, |
| 1212 | FXJSE_HVALUE hValue) { |
| 1213 | if (hDoc != m_pXFADoc) |
| 1214 | return FALSE; |
| 1215 | |
| 1216 | if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime()) |
| 1217 | return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName, |
| 1218 | hValue); |
| 1219 | return FALSE; |
| 1220 | } |
| 1221 | FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc, |
| 1222 | const CFX_ByteStringC& utf8Name, |
| 1223 | FXJSE_HVALUE hValue) { |
| 1224 | if (hDoc != m_pXFADoc) |
| 1225 | return FALSE; |
| 1226 | |
| 1227 | if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) |
| 1228 | return FALSE; |
| 1229 | |
| 1230 | if (!m_pJSContext) { |
| 1231 | m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); |
| 1232 | m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); |
| 1233 | } |
| 1234 | |
| 1235 | return _GetHValueByName(utf8Name, hValue, |
| 1236 | m_pSDKDoc->GetEnv()->GetJSRuntime()); |
| 1237 | } |
| 1238 | FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc, |
| 1239 | const CFX_ByteStringC& szPropName, |
| 1240 | FXJSE_HVALUE hValue) { |
| 1241 | if (hDoc != m_pXFADoc) |
| 1242 | return FALSE; |
| 1243 | if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime()) |
| 1244 | return FALSE; |
| 1245 | |
| 1246 | if (!m_pJSContext) { |
| 1247 | m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc); |
| 1248 | m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext(); |
| 1249 | } |
| 1250 | |
| 1251 | return _GetHValueByName(szPropName, hValue, |
| 1252 | m_pSDKDoc->GetEnv()->GetJSRuntime()); |
| 1253 | } |
| 1254 | FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name, |
| 1255 | FXJSE_HVALUE hValue, |
| 1256 | IJS_Runtime* runTime) { |
| 1257 | return runTime->GetHValueByName(utf8Name, hValue); |
| 1258 | } |