OLD | NEW |
---|---|
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" | 7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
11 #include "core/fpdfapi/parser/cpdf_array.h" | |
12 #include "core/fpdfdoc/cpdf_docjsactions.h" | |
11 #include "fpdfsdk/cpdfsdk_annothandlermgr.h" | 13 #include "fpdfsdk/cpdfsdk_annothandlermgr.h" |
12 #include "fpdfsdk/cpdfsdk_document.h" | 14 #include "fpdfsdk/cpdfsdk_interform.h" |
15 #include "fpdfsdk/cpdfsdk_pageview.h" | |
16 #include "fpdfsdk/cpdfsdk_widget.h" | |
13 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" | 17 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" |
14 #include "fpdfsdk/fsdk_actionhandler.h" | 18 #include "fpdfsdk/fsdk_actionhandler.h" |
15 #include "fpdfsdk/javascript/ijs_runtime.h" | 19 #include "fpdfsdk/javascript/ijs_runtime.h" |
16 #include "third_party/base/ptr_util.h" | 20 #include "third_party/base/ptr_util.h" |
17 | 21 |
18 #ifdef PDF_ENABLE_XFA | 22 #ifdef PDF_ENABLE_XFA |
19 #include "fpdfsdk/fpdfxfa/cpdfxfa_app.h" | 23 #include "fpdfsdk/fpdfxfa/cpdfxfa_app.h" |
20 #endif // PDF_ENABLE_XFA | 24 #endif // PDF_ENABLE_XFA |
21 | 25 |
22 namespace { | 26 namespace { |
23 | 27 |
24 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken | 28 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken |
25 // since modifying the result would impact |bsUTF16LE|. | 29 // since modifying the result would impact |bsUTF16LE|. |
26 FPDF_WIDESTRING AsFPDFWideString(CFX_ByteString* bsUTF16LE) { | 30 FPDF_WIDESTRING AsFPDFWideString(CFX_ByteString* bsUTF16LE) { |
27 return reinterpret_cast<FPDF_WIDESTRING>( | 31 return reinterpret_cast<FPDF_WIDESTRING>( |
28 bsUTF16LE->GetBuffer(bsUTF16LE->GetLength())); | 32 bsUTF16LE->GetBuffer(bsUTF16LE->GetLength())); |
29 } | 33 } |
30 | 34 |
31 } // namespace | 35 } // namespace |
32 | 36 |
33 CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment( | 37 CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment( |
34 UnderlyingDocumentType* pDoc, | 38 UnderlyingDocumentType* pDoc, |
35 FPDF_FORMFILLINFO* pFFinfo) | 39 FPDF_FORMFILLINFO* pFFinfo) |
36 : m_pInfo(pFFinfo), | 40 : m_pInfo(pFFinfo), |
37 m_pSDKDoc(new CPDFSDK_Document(pDoc, this)), | |
38 m_pUnderlyingDoc(pDoc), | 41 m_pUnderlyingDoc(pDoc), |
39 m_pSysHandler(new CFX_SystemHandler(this)) {} | 42 m_pSysHandler(new CFX_SystemHandler(this)), |
43 m_bChangeMask(FALSE), | |
44 m_bBeingDestroyed(FALSE) {} | |
40 | 45 |
41 CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() { | 46 CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() { |
47 m_bBeingDestroyed = TRUE; | |
48 | |
49 ClearAllFocusedAnnots(); | |
50 for (auto& it : m_pageMap) | |
Tom Sepez
2016/10/12 18:52:59
nit: map of unique_ptrs (keep .clear() if order im
dsinclair
2016/10/12 19:44:29
Done.
| |
51 delete it.second; | |
52 m_pageMap.clear(); | |
53 | |
42 // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| | 54 // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| |
43 // when it cleans up. So, we must make sure it is cleaned up before | 55 // when it cleans up. So, we must make sure it is cleaned up before |
44 // |m_pFormFiller|. | 56 // |m_pFormFiller|. |
45 m_pAnnotHandlerMgr.reset(); | 57 m_pAnnotHandlerMgr.reset(); |
46 | 58 |
47 // Must destroy the |m_pFormFiller| before the environment (|this|) | 59 // Must destroy the |m_pFormFiller| before the environment (|this|) |
48 // because any created form widgets hold a pointer to the environment. | 60 // because any created form widgets hold a pointer to the environment. |
49 // Those widgets may call things like KillTimer() as they are shutdown. | 61 // Those widgets may call things like KillTimer() as they are shutdown. |
50 m_pFormFiller.reset(); | 62 m_pFormFiller.reset(); |
51 | 63 |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
555 delete[] pbuff; | 567 delete[] pbuff; |
556 return wsRet; | 568 return wsRet; |
557 } | 569 } |
558 | 570 |
559 void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount, | 571 void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount, |
560 uint32_t dwEventType) const { | 572 uint32_t dwEventType) const { |
561 if (m_pInfo && m_pInfo->FFI_PageEvent) | 573 if (m_pInfo && m_pInfo->FFI_PageEvent) |
562 m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType); | 574 m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType); |
563 } | 575 } |
564 #endif // PDF_ENABLE_XFA | 576 #endif // PDF_ENABLE_XFA |
577 | |
578 void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() { | |
579 for (auto& it : m_pageMap) { | |
580 if (it.second->IsValidSDKAnnot(GetFocusAnnot())) | |
581 KillFocusAnnot(0); | |
582 } | |
583 } | |
584 | |
585 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView( | |
586 UnderlyingPageType* pUnderlyingPage, | |
587 bool ReNew) { | |
Tom Sepez
2016/10/12 18:52:59
nit: |renew| or |bRenew| (has bugged me for years
dsinclair
2016/10/12 19:44:29
Done.
| |
588 auto it = m_pageMap.find(pUnderlyingPage); | |
589 if (it != m_pageMap.end()) | |
590 return it->second; | |
591 | |
592 if (!ReNew) | |
593 return nullptr; | |
594 | |
595 CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage); | |
596 m_pageMap[pUnderlyingPage] = pPageView; | |
597 // Delay to load all the annotations, to avoid endless loop. | |
598 pPageView->LoadFXAnnots(); | |
599 return pPageView; | |
600 } | |
601 | |
602 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() { | |
603 UnderlyingPageType* pPage = | |
604 UnderlyingFromFPDFPage(GetCurrentPage(m_pUnderlyingDoc)); | |
605 return pPage ? GetPageView(pPage, true) : nullptr; | |
606 } | |
607 | |
608 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) { | |
609 UnderlyingPageType* pTempPage = | |
610 UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex)); | |
611 if (!pTempPage) | |
612 return nullptr; | |
613 | |
614 auto it = m_pageMap.find(pTempPage); | |
615 return it != m_pageMap.end() ? it->second : nullptr; | |
616 } | |
617 | |
618 void CPDFSDK_FormFillEnvironment::ProcJavascriptFun() { | |
619 CPDF_Document* pPDFDoc = GetPDFDocument(); | |
620 CPDF_DocJSActions docJS(pPDFDoc); | |
621 int iCount = docJS.CountJSActions(); | |
622 if (iCount < 1) | |
623 return; | |
624 for (int i = 0; i < iCount; i++) { | |
625 CFX_ByteString csJSName; | |
626 CPDF_Action jsAction = docJS.GetJSAction(i, csJSName); | |
627 if (GetActionHander()) { | |
628 GetActionHander()->DoAction_JavaScript( | |
629 jsAction, CFX_WideString::FromLocal(csJSName.AsStringC()), this); | |
630 } | |
631 } | |
632 } | |
633 | |
634 FX_BOOL CPDFSDK_FormFillEnvironment::ProcOpenAction() { | |
635 if (!m_pUnderlyingDoc) | |
636 return FALSE; | |
637 | |
638 CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot(); | |
639 if (!pRoot) | |
640 return FALSE; | |
641 | |
642 CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction"); | |
643 if (!pOpenAction) | |
644 pOpenAction = pRoot->GetArrayFor("OpenAction"); | |
645 | |
646 if (!pOpenAction) | |
647 return FALSE; | |
648 | |
649 if (pOpenAction->IsArray()) | |
650 return TRUE; | |
651 | |
652 if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) { | |
653 CPDF_Action action(pDict); | |
654 if (GetActionHander()) | |
655 GetActionHander()->DoAction_DocOpen(action, this); | |
656 return TRUE; | |
657 } | |
658 return FALSE; | |
659 } | |
660 | |
661 void CPDFSDK_FormFillEnvironment::RemovePageView( | |
662 UnderlyingPageType* pUnderlyingPage) { | |
663 auto it = m_pageMap.find(pUnderlyingPage); | |
664 if (it == m_pageMap.end()) | |
665 return; | |
666 | |
667 CPDFSDK_PageView* pPageView = it->second; | |
668 if (pPageView->IsLocked() || pPageView->IsBeingDestroyed()) | |
669 return; | |
670 | |
671 // Mark the page view so we do not come into |RemovePageView| a second | |
672 // time while we're in the process of removing. | |
673 pPageView->SetBeingDestroyed(); | |
674 | |
675 // This must happen before we remove |pPageView| from the map because | |
676 // |KillFocusAnnot| can call into the |GetPage| method which will | |
677 // look for this page view in the map, if it doesn't find it a new one will | |
678 // be created. We then have two page views pointing to the same page and | |
679 // bad things happen. | |
680 if (pPageView->IsValidSDKAnnot(GetFocusAnnot())) | |
681 KillFocusAnnot(0); | |
682 | |
683 // Remove the page from the map to make sure we don't accidentally attempt | |
684 // to use the |pPageView| while we're cleaning it up. | |
685 m_pageMap.erase(it); | |
686 | |
687 delete pPageView; | |
688 } | |
689 | |
690 UnderlyingPageType* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) { | |
691 return UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex)); | |
692 } | |
693 | |
694 CPDFSDK_InterForm* CPDFSDK_FormFillEnvironment::GetInterForm() { | |
695 if (!m_pInterForm) | |
696 m_pInterForm = pdfium::MakeUnique<CPDFSDK_InterForm>(this); | |
697 return m_pInterForm.get(); | |
698 } | |
699 | |
700 void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender, | |
701 CPDFSDK_Annot* pAnnot) { | |
702 for (const auto& it : m_pageMap) { | |
703 CPDFSDK_PageView* pPageView = it.second; | |
704 if (pPageView != pSender) | |
705 pPageView->UpdateView(pAnnot); | |
706 } | |
707 } | |
708 | |
709 FX_BOOL CPDFSDK_FormFillEnvironment::SetFocusAnnot( | |
710 CPDFSDK_Annot::ObservedPtr* pAnnot) { | |
711 if (m_bBeingDestroyed) | |
712 return FALSE; | |
713 if (m_pFocusAnnot == *pAnnot) | |
714 return TRUE; | |
715 if (m_pFocusAnnot && !KillFocusAnnot(0)) | |
716 return FALSE; | |
717 if (!*pAnnot) | |
718 return FALSE; | |
719 | |
720 #ifdef PDF_ENABLE_XFA | |
721 CPDFSDK_Annot::ObservedPtr pLastFocusAnnot(m_pFocusAnnot.Get()); | |
722 #endif // PDF_ENABLE_XFA | |
723 CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView(); | |
724 if (pPageView && pPageView->IsValid()) { | |
725 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr(); | |
726 if (!m_pFocusAnnot) { | |
727 #ifdef PDF_ENABLE_XFA | |
728 if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot)) | |
729 return FALSE; | |
730 #endif // PDF_ENABLE_XFA | |
731 if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0)) | |
732 return FALSE; | |
733 if (!m_pFocusAnnot) { | |
734 m_pFocusAnnot.Reset(pAnnot->Get()); | |
735 return TRUE; | |
736 } | |
737 } | |
738 } | |
739 return FALSE; | |
740 } | |
741 | |
742 FX_BOOL CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) { | |
743 if (m_pFocusAnnot) { | |
744 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr(); | |
745 CPDFSDK_Annot::ObservedPtr pFocusAnnot(m_pFocusAnnot.Get()); | |
746 m_pFocusAnnot.Reset(); | |
747 | |
748 #ifdef PDF_ENABLE_XFA | |
749 CPDFSDK_Annot::ObservedPtr pNull; | |
750 if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot)) | |
751 return FALSE; | |
752 #endif // PDF_ENABLE_XFA | |
753 | |
754 if (pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) { | |
755 if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) { | |
756 CPDFSDK_Widget* pWidget = | |
757 static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get()); | |
758 int nFieldType = pWidget->GetFieldType(); | |
759 if (FIELDTYPE_TEXTFIELD == nFieldType || | |
760 FIELDTYPE_COMBOBOX == nFieldType) { | |
761 OnSetFieldInputFocus(nullptr, 0, FALSE); | |
762 } | |
763 } | |
764 if (!m_pFocusAnnot) | |
765 return TRUE; | |
766 } else { | |
767 m_pFocusAnnot.Reset(pFocusAnnot.Get()); | |
768 } | |
769 } | |
770 return FALSE; | |
771 } | |
772 | |
773 FX_BOOL CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) { | |
774 return GetPDFDocument()->GetUserPermissions() & nFlag; | |
775 } | |
OLD | NEW |