diff options
Diffstat (limited to 'fpdfsdk')
-rw-r--r-- | fpdfsdk/cpdfsdk_annothandlermgr.cpp | 4 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_annothandlermgr.h | 1 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_baannothandler.cpp | 4 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_baannothandler.h | 1 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_pageview.cpp | 10 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_pageview.h | 1 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_widgethandler.cpp | 7 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_widgethandler.h | 1 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_xfawidgethandler.cpp | 8 | ||||
-rw-r--r-- | fpdfsdk/cpdfsdk_xfawidgethandler.h | 1 | ||||
-rw-r--r-- | fpdfsdk/formfiller/cffl_formfiller.cpp | 11 | ||||
-rw-r--r-- | fpdfsdk/formfiller/cffl_formfiller.h | 1 | ||||
-rw-r--r-- | fpdfsdk/formfiller/cffl_interactiveformfiller.cpp | 6 | ||||
-rw-r--r-- | fpdfsdk/formfiller/cffl_interactiveformfiller.h | 1 | ||||
-rw-r--r-- | fpdfsdk/fpdf_formfill.cpp | 23 | ||||
-rw-r--r-- | fpdfsdk/fpdf_formfill_embeddertest.cpp | 192 | ||||
-rw-r--r-- | fpdfsdk/fpdf_view_c_api_test.c | 1 | ||||
-rw-r--r-- | fpdfsdk/ipdfsdk_annothandler.h | 1 |
18 files changed, 254 insertions, 20 deletions
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp index e0405e84f9..52ab4dd2c6 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp +++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp @@ -76,6 +76,10 @@ void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) { GetAnnotHandler(pAnnot)->OnLoad(pAnnot); } +WideString CPDFSDK_AnnotHandlerMgr::Annot_GetText(CPDFSDK_Annot* pAnnot) { + return GetAnnotHandler(pAnnot)->GetText(pAnnot); +} + WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText( CPDFSDK_Annot* pAnnot) { return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot); diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h index df4e1a224c..7ea7a0e4f9 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.h +++ b/fpdfsdk/cpdfsdk_annothandlermgr.h @@ -42,6 +42,7 @@ class CPDFSDK_AnnotHandlerMgr { void Annot_OnCreate(CPDFSDK_Annot* pAnnot); void Annot_OnLoad(CPDFSDK_Annot* pAnnot); + WideString Annot_GetText(CPDFSDK_Annot* pAnnot); WideString Annot_GetSelectedText(CPDFSDK_Annot* pAnnot); void Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text); diff --git a/fpdfsdk/cpdfsdk_baannothandler.cpp b/fpdfsdk/cpdfsdk_baannothandler.cpp index 027527ec5f..24643eb70e 100644 --- a/fpdfsdk/cpdfsdk_baannothandler.cpp +++ b/fpdfsdk/cpdfsdk_baannothandler.cpp @@ -193,6 +193,10 @@ CFX_FloatRect CPDFSDK_BAAnnotHandler::GetViewBBox(CPDFSDK_PageView* pPageView, return pAnnot->GetRect(); } +WideString CPDFSDK_BAAnnotHandler::GetText(CPDFSDK_Annot* pAnnot) { + return WideString(); +} + WideString CPDFSDK_BAAnnotHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) { return WideString(); } diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h index 7bf8034a54..2a03402fa5 100644 --- a/fpdfsdk/cpdfsdk_baannothandler.h +++ b/fpdfsdk/cpdfsdk_baannothandler.h @@ -36,6 +36,7 @@ class CPDFSDK_BAAnnotHandler : public IPDFSDK_AnnotHandler { void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override; CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) override; + WideString GetText(CPDFSDK_Annot* pAnnot) override; WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override; void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text) override; bool HitTest(CPDFSDK_PageView* pPageView, diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp index c1b5221235..b7f8cdfe10 100644 --- a/fpdfsdk/cpdfsdk_pageview.cpp +++ b/fpdfsdk/cpdfsdk_pageview.cpp @@ -240,6 +240,16 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) { } #endif // PDF_ENABLE_XFA +WideString CPDFSDK_PageView::GetFocusedFormText() { + if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) { + CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = + m_pFormFillEnv->GetAnnotHandlerMgr(); + return pAnnotHandlerMgr->Annot_GetText(pAnnot); + } + + return WideString(); +} + WideString CPDFSDK_PageView::GetSelectedText() { if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) { CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h index 03f3ab6318..9f846cf2a4 100644 --- a/fpdfsdk/cpdfsdk_pageview.h +++ b/fpdfsdk/cpdfsdk_pageview.h @@ -61,6 +61,7 @@ class CPDFSDK_PageView final : public CPDF_Page::View { return m_pFormFillEnv.Get(); } + WideString GetFocusedFormText(); WideString GetSelectedText(); void ReplaceSelection(const WideString& text); diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp index dcce7b6017..6281058059 100644 --- a/fpdfsdk/cpdfsdk_widgethandler.cpp +++ b/fpdfsdk/cpdfsdk_widgethandler.cpp @@ -281,10 +281,15 @@ CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, return CFX_FloatRect(); } +WideString CPDFSDK_WidgetHandler::GetText(CPDFSDK_Annot* pAnnot) { + if (!pAnnot->IsSignatureWidget() && m_pFormFiller) + return m_pFormFiller->GetText(pAnnot); + return WideString(); +} + WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) { if (!pAnnot->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->GetSelectedText(pAnnot); - return WideString(); } diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h index f8aa7de5bd..fbf9d2e906 100644 --- a/fpdfsdk/cpdfsdk_widgethandler.h +++ b/fpdfsdk/cpdfsdk_widgethandler.h @@ -37,6 +37,7 @@ class CPDFSDK_WidgetHandler : public IPDFSDK_AnnotHandler { void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override; CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) override; + WideString GetText(CPDFSDK_Annot* pAnnot) override; WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override; void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text) override; bool HitTest(CPDFSDK_PageView* pPageView, diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp index e39f8ceda2..261c27c384 100644 --- a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp +++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp @@ -100,6 +100,14 @@ CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, return rcWidget; } +WideString CPDFSDK_XFAWidgetHandler::GetText(CPDFSDK_Annot* pAnnot) { + if (!pAnnot) + return WideString(); + + CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot); + return pWidgetHandler->GetText(pAnnot->GetXFAWidget()); +} + WideString CPDFSDK_XFAWidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) { if (!pAnnot) return WideString(); diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.h b/fpdfsdk/cpdfsdk_xfawidgethandler.h index e0dccbe685..dbdb99bada 100644 --- a/fpdfsdk/cpdfsdk_xfawidgethandler.h +++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h @@ -32,6 +32,7 @@ class CPDFSDK_XFAWidgetHandler : public IPDFSDK_AnnotHandler { void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override; CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) override; + WideString GetText(CPDFSDK_Annot* pAnnot) override; WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override; void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text) override; bool HitTest(CPDFSDK_PageView* pPageView, diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp index dcbe0181f3..32bbcb73d2 100644 --- a/fpdfsdk/formfiller/cffl_formfiller.cpp +++ b/fpdfsdk/formfiller/cffl_formfiller.cpp @@ -219,6 +219,17 @@ bool CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot, return pWnd && pWnd->OnChar(nChar, nFlags); } +WideString CFFL_FormFiller::GetText(CPDFSDK_Annot* pAnnot) { + if (!IsValid()) + return WideString(); + + CPDFSDK_PageView* pPageView = GetCurPageView(true); + ASSERT(pPageView); + + CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false); + return pWnd ? pWnd->GetText() : WideString(); +} + WideString CFFL_FormFiller::GetSelectedText(CPDFSDK_Annot* pAnnot) { if (!IsValid()) return WideString(); diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h index 0dfb0bb177..a9d90ab902 100644 --- a/fpdfsdk/formfiller/cffl_formfiller.h +++ b/fpdfsdk/formfiller/cffl_formfiller.h @@ -75,6 +75,7 @@ class CFFL_FormFiller : public CPWL_Wnd::ProviderIface, uint32_t nFlags); virtual bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags); + WideString GetText(CPDFSDK_Annot* pAnnot); WideString GetSelectedText(CPDFSDK_Annot* pAnnot); void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text); diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp index 83b425725a..5972d1dd67 100644 --- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp +++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp @@ -511,6 +511,12 @@ CFFL_FormFiller* CFFL_InteractiveFormFiller::GetFormFiller( return pFormFiller; } +WideString CFFL_InteractiveFormFiller::GetText(CPDFSDK_Annot* pAnnot) { + ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); + CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false); + return pFormFiller ? pFormFiller->GetText(pAnnot) : WideString(); +} + WideString CFFL_InteractiveFormFiller::GetSelectedText(CPDFSDK_Annot* pAnnot) { ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false); diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h index 94ca59d284..bb0d2233fc 100644 --- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h +++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h @@ -82,6 +82,7 @@ class CFFL_InteractiveFormFiller : public IPWL_Filler_Notify { CFFL_FormFiller* GetFormFiller(CPDFSDK_Annot* pAnnot, bool bRegister); + WideString GetText(CPDFSDK_Annot* pAnnot); WideString GetSelectedText(CPDFSDK_Annot* pAnnot); void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text); diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp index 912db878f8..7676463edc 100644 --- a/fpdfsdk/fpdf_formfill.cpp +++ b/fpdfsdk/fpdf_formfill.cpp @@ -427,6 +427,19 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, } FPDF_EXPORT unsigned long FPDF_CALLCONV +FORM_GetFocusedText(FPDF_FORMHANDLE hHandle, + FPDF_PAGE page, + void* buffer, + unsigned long buflen) { + CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); + if (!pPageView) + return 0; + + return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetFocusedFormText(), + buffer, buflen); +} + +FPDF_EXPORT unsigned long FPDF_CALLCONV FORM_GetSelectedText(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, void* buffer, @@ -435,14 +448,8 @@ FORM_GetSelectedText(FPDF_FORMHANDLE hHandle, if (!pPageView) return 0; - WideString wide_str_form_text = pPageView->GetSelectedText(); - ByteString encoded_form_text = wide_str_form_text.UTF16LE_Encode(); - unsigned long form_text_len = encoded_form_text.GetLength(); - - if (buffer && buflen >= form_text_len) - memcpy(buffer, encoded_form_text.c_str(), form_text_len); - - return form_text_len; + return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetSelectedText(), + buffer, buflen); } FPDF_EXPORT void FPDF_CALLCONV FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle, diff --git a/fpdfsdk/fpdf_formfill_embeddertest.cpp b/fpdfsdk/fpdf_formfill_embeddertest.cpp index 99a51fd4a4..5dd4d1e1c1 100644 --- a/fpdfsdk/fpdf_formfill_embeddertest.cpp +++ b/fpdfsdk/fpdf_formfill_embeddertest.cpp @@ -107,20 +107,30 @@ class FPDFFormFillInteractiveEmbeddertest : public FPDFFormFillEmbeddertest { } void CheckSelection(const WideStringView& expected_string) { - // Calculate expected length for selected text. - int num_chars = expected_string.GetLength(); - - // Check actual selection against expected selection. - const unsigned long expected_length = - sizeof(unsigned short) * (num_chars + 1); - unsigned long sel_text_len = + unsigned long actual_len = FORM_GetSelectedText(form_handle(), page_, nullptr, 0); - ASSERT_EQ(expected_length, sel_text_len); + ASSERT_NE(actual_len, 0U); + ASSERT_LT(actual_len, 1000U); - std::vector<unsigned short> buf(sel_text_len); - EXPECT_EQ(expected_length, FORM_GetSelectedText(form_handle(), page_, - buf.data(), sel_text_len)); + std::vector<unsigned short> buf(actual_len); + ASSERT_EQ(actual_len, FORM_GetSelectedText(form_handle(), page_, buf.data(), + actual_len)); + int num_chars = (actual_len / sizeof(unsigned short)) - 1; + EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars)); + } + + void CheckFocusedFieldText(const WideStringView& expected_string) { + unsigned long actual_len = + FORM_GetFocusedText(form_handle(), page_, nullptr, 0); + ASSERT_NE(actual_len, 0U); + ASSERT_LT(actual_len, 1000U); + + std::vector<unsigned short> buf(actual_len); + ASSERT_EQ(actual_len, FORM_GetFocusedText(form_handle(), page_, buf.data(), + actual_len)); + + int num_chars = (actual_len / sizeof(unsigned short)) - 1; EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars)); } @@ -589,26 +599,31 @@ TEST_F(FPDFFormFillEmbeddertest, HasFormInfoXFAForeground) { TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicKeyboard) { // Test empty selection. + CheckFocusedFieldText(L""); CheckSelection(L""); // Test basic selection. TypeTextIntoTextField(3, RegularFormBegin()); + CheckFocusedFieldText(L"ABC"); SelectTextWithKeyboard(3, FWL_VKEY_Left, RegularFormAtX(123.0)); CheckSelection(L"ABC"); } TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicMouse) { // Test empty selection. + CheckFocusedFieldText(L""); CheckSelection(L""); // Test basic selection. TypeTextIntoTextField(3, RegularFormBegin()); + CheckFocusedFieldText(L"ABC"); SelectTextWithMouse(RegularFormAtX(125.0), RegularFormBegin()); CheckSelection(L"ABC"); } TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsKeyBoard) { TypeTextIntoTextField(12, RegularFormBegin()); + CheckFocusedFieldText(L"ABCDEFGHIJKL"); // Test selecting first character in forward direction. SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin()); @@ -629,6 +644,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsKeyBoard) { // Test selecting last character in backwards direction. SelectTextWithKeyboard(1, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L"L"); + CheckFocusedFieldText(L"ABCDEFGHIJKL"); } TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsMouse) { @@ -659,13 +675,16 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, GetSelectedTextEmptyAndBasicNormalComboBox) { // Test empty selection. CheckSelection(L""); + CheckFocusedFieldText(L""); // Non-editable comboboxes don't allow selection with keyboard. SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(142.0)); + CheckFocusedFieldText(L"Banana"); CheckSelection(L"Banana"); // Select other another provided option. SelectNonEditableFormOption(0); + CheckFocusedFieldText(L"Apple"); CheckSelection(L"Apple"); } @@ -673,15 +692,18 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard) { // Test empty selection. CheckSelection(L""); + CheckFocusedFieldText(L""); // Test basic selection of text within user editable combobox using keyboard. TypeTextIntoTextField(3, EditableFormBegin()); + CheckFocusedFieldText(L"ABC"); SelectTextWithKeyboard(3, FWL_VKEY_Left, EditableFormAtX(128.0)); CheckSelection(L"ABC"); // Select a provided option. SelectEditableFormOption(1); CheckSelection(L"Bar"); + CheckFocusedFieldText(L"Bar"); } TEST_F(FPDFFormFillComboBoxFormEmbeddertest, @@ -696,13 +718,17 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, // Select a provided option. SelectEditableFormOption(2); + CheckFocusedFieldText(L"Qux"); CheckSelection(L"Qux"); } TEST_F(FPDFFormFillComboBoxFormEmbeddertest, GetSelectedTextFragmentsNormalComboBox) { + CheckFocusedFieldText(L""); + // Test selecting first character in forward direction. SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(107.0)); + CheckFocusedFieldText(L"Banana"); CheckSelection(L"B"); // Test selecting entire string in backwards direction. @@ -720,9 +746,11 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, // Test selecting last character in backwards direction. SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormAtX(138.0)); CheckSelection(L"a"); + CheckFocusedFieldText(L"Banana"); // Select another option and then reset selection as first three chars. SelectNonEditableFormOption(2); + CheckFocusedFieldText(L"Cherry"); CheckSelection(L"Cherry"); SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(122.0)); CheckSelection(L"Che"); @@ -730,7 +758,9 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, TEST_F(FPDFFormFillComboBoxFormEmbeddertest, GetSelectedTextFragmentsEditableComboBoxKeyboard) { + CheckFocusedFieldText(L""); TypeTextIntoTextField(10, EditableFormBegin()); + CheckFocusedFieldText(L"ABCDEFGHIJ"); // Test selecting first character in forward direction. SelectTextWithKeyboard(1, FWL_VKEY_Right, EditableFormBegin()); @@ -757,6 +787,7 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, CheckSelection(L"Foo"); SelectTextWithKeyboard(2, FWL_VKEY_Right, EditableFormBegin()); CheckSelection(L"Fo"); + CheckFocusedFieldText(L"Foo"); } TEST_F(FPDFFormFillComboBoxFormEmbeddertest, @@ -782,17 +813,20 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, // Test selecting last character in backwards direction. SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(174.0)); CheckSelection(L"J"); + CheckFocusedFieldText(L"ABCDEFGHIJ"); } TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldEntireSelection) { // Select entire contents of text field. TypeTextIntoTextField(12, RegularFormBegin()); SelectAllRegularFormTextWithMouse(); + CheckFocusedFieldText(L"ABCDEFGHIJKL"); CheckSelection(L"ABCDEFGHIJKL"); // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L""); SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L""); @@ -802,11 +836,13 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionMiddle) { // Select middle section of text. TypeTextIntoTextField(12, RegularFormBegin()); SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0)); + CheckFocusedFieldText(L"ABCDEFGHIJKL"); CheckSelection(L"DEFGHI"); // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L"ABCJKL"); SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L"ABCJKL"); } @@ -820,6 +856,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionLeft) { // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L"EFGHIJKL"); SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L"EFGHIJKL"); } @@ -833,6 +870,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionRight) { // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L"ABCDEFGH"); SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L"ABCDEFGH"); } @@ -844,6 +882,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteEmptyTextFieldSelection) { // Test that attempt to delete empty text selection has no effect. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L"ABCDEFGHIJKL"); SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd()); CheckSelection(L"ABCDEFGHIJKL"); } @@ -858,6 +897,7 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L""); SelectAllEditableFormTextWithMouse(); CheckSelection(L""); } @@ -872,6 +912,7 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, // Test deleting current text selection. Select what remains after deletion to // check that remaining text is as expected. FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L"ABCIJ"); SelectAllEditableFormTextWithMouse(); CheckSelection(L"ABCIJ"); } @@ -917,12 +958,15 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, } TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyTextField) { + CheckFocusedFieldText(L""); ClickOnFormFieldAtPoint(RegularFormBegin()); + CheckFocusedFieldText(L""); // Test inserting text into empty text field. std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"Hello"); // Select entire contents of text field to check that insertion worked // as expected. @@ -932,14 +976,17 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyTextField) { TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldLeft) { TypeTextIntoTextField(8, RegularFormBegin()); + CheckFocusedFieldText(L"ABCDEFGH"); // Click on the leftmost part of the text field. ClickOnFormFieldAtPoint(RegularFormBegin()); + CheckFocusedFieldText(L"ABCDEFGH"); // Test inserting text in front of existing text in text field. std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"HelloABCDEFGH"); // Select entire contents of text field to check that insertion worked // as expected. @@ -957,6 +1004,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldMiddle) { std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"ABCDHelloEFGH"); // Select entire contents of text field to check that insertion worked // as expected. @@ -974,6 +1022,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldRight) { std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"ABCDEFGHHello"); // Select entire contents of text field to check that insertion worked // as expected. @@ -993,6 +1042,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"Hello"); // Select entire contents of text field to check that insertion worked // as expected. @@ -1012,6 +1062,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"HelloGHIJKL"); // Select entire contents of text field to check that insertion worked // as expected. @@ -1060,11 +1111,13 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, TEST_F(FPDFFormFillComboBoxFormEmbeddertest, InsertTextInEmptyEditableComboBox) { ClickOnFormFieldAtPoint(EditableFormBegin()); + CheckFocusedFieldText(L""); // Test inserting text into empty user-editable combobox. std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hello"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"Hello"); // Select entire contents of user-editable combobox text field to check that // insertion worked as expected. @@ -1206,18 +1259,22 @@ TEST_F(FPDFFormFillComboBoxFormEmbeddertest, TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyCharLimitTextFieldOverflow) { // Click on the textfield. + CheckFocusedFieldText(L""); ClickOnFormFieldAtPoint(CharLimitFormEnd()); + CheckFocusedFieldText(L"Elephant"); // Delete pre-filled contents of text field with char limit. SelectAllCharLimitFormTextWithMouse(); CheckSelection(L"Elephant"); FORM_ReplaceSelection(form_handle(), page(), nullptr); + CheckFocusedFieldText(L""); // Test inserting text into now empty text field so text to be inserted // exceeds the char limit and is cut off. std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hippopotamus"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"Hippopotam"); // Select entire contents of text field to check that insertion worked // as expected. @@ -1229,6 +1286,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyCharLimitTextFieldFit) { // Click on the textfield. ClickOnFormFieldAtPoint(CharLimitFormEnd()); + CheckFocusedFieldText(L"Elephant"); // Delete pre-filled contents of text field with char limit. SelectAllCharLimitFormTextWithMouse(); @@ -1240,6 +1298,7 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Zebra"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"Zebra"); // Select entire contents of text field to check that insertion worked // as expected. @@ -1265,15 +1324,19 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedCharLimitTextFieldMiddle) { + CheckFocusedFieldText(L""); TypeTextIntoTextField(8, RegularFormBegin()); + CheckFocusedFieldText(L"ABCDEFGH"); // Click on the middle of the text field. ClickOnFormFieldAtPoint(CharLimitFormAtX(134.0)); + CheckFocusedFieldText(L"Elephant"); // Test inserting text in the middle of existing text in text field. std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert = GetFPDFWideString(L"Hippopotamus"); FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get()); + CheckFocusedFieldText(L"ElephHiant"); // Select entire contents of text field to check that insertion worked // as expected. @@ -1374,3 +1437,110 @@ TEST_F(FPDFFormFillTextFormEmbeddertest, SelectAllCharLimitFormTextWithMouse(); CheckSelection(L"ElepHippop"); } + +TEST_F(FPDFFormFillTextFormEmbeddertest, FocusChanges) { + static const CFX_PointF kNonFormPoint(1, 1); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(CharLimitFormEnd()); + CheckFocusedFieldText(L"Elephant"); + ClickOnFormFieldAtPoint(RegularFormBegin()); + CheckFocusedFieldText(L""); + TypeTextIntoTextField(3, CharLimitFormBegin()); + CheckFocusedFieldText(L"ABElephant"); + TypeTextIntoTextField(5, RegularFormBegin()); + CheckFocusedFieldText(L"ABCDE"); + ClickOnFormFieldAtPoint(CharLimitFormEnd()); + CheckFocusedFieldText(L"ABElephant"); + ClickOnFormFieldAtPoint(kNonFormPoint); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(kNonFormPoint); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(CharLimitFormBegin()); + CheckFocusedFieldText(L"ABElephant"); + ClickOnFormFieldAtPoint(CharLimitFormEnd()); + CheckFocusedFieldText(L"ABElephant"); + ClickOnFormFieldAtPoint(RegularFormEnd()); + CheckFocusedFieldText(L"ABCDE"); + ClickOnFormFieldAtPoint(RegularFormBegin()); + CheckFocusedFieldText(L"ABCDE"); + ClickOnFormFieldAtPoint(RegularFormBegin()); + CheckFocusedFieldText(L"ABCDE"); + ClickOnFormFieldAtPoint(CharLimitFormBegin()); + CheckFocusedFieldText(L"ABElephant"); + FORM_ForceToKillFocus(form_handle()); + CheckFocusedFieldText(L""); +} + +TEST_F(FPDFFormFillComboBoxFormEmbeddertest, FocusChanges) { + static const CFX_PointF kNonFormPoint(1, 1); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(NonEditableFormBegin()); + CheckFocusedFieldText(L"Banana"); + ClickOnFormFieldAtPoint(EditableFormBegin()); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(NonEditableFormEnd()); + CheckFocusedFieldText(L"Banana"); + ClickOnFormFieldAtPoint(NonEditableFormBegin()); + CheckFocusedFieldText(L"Banana"); + FORM_ForceToKillFocus(form_handle()); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(EditableFormBegin()); + CheckFocusedFieldText(L""); + TypeTextIntoTextField(3, EditableFormBegin()); + CheckFocusedFieldText(L"ABC"); + ClickOnFormFieldAtPoint(kNonFormPoint); + CheckFocusedFieldText(L""); + TypeTextIntoTextField(3, EditableFormEnd()); + CheckFocusedFieldText(L"ABCABC"); + ClickOnFormFieldAtPoint(kNonFormPoint); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(EditableFormDropDown()); + CheckFocusedFieldText(L"ABCABC"); + FORM_ForceToKillFocus(form_handle()); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(NonEditableFormDropDown()); + CheckFocusedFieldText(L"Banana"); + ClickOnFormFieldAtPoint(kNonFormPoint); + CheckFocusedFieldText(L""); + ClickOnFormFieldAtPoint(NonEditableFormEnd()); + CheckFocusedFieldText(L"Banana"); + + // Typing into non-editable field results in selecting a different option. + TypeTextIntoTextField(1, NonEditableFormEnd()); + CheckFocusedFieldText(L"Apple"); + TypeTextIntoTextField(3, NonEditableFormEnd()); + CheckFocusedFieldText(L"Cherry"); + TypeTextIntoTextField(2, NonEditableFormEnd()); + CheckFocusedFieldText(L"Banana"); + + SelectEditableFormOption(0); + CheckFocusedFieldText(L"Foo"); + SelectEditableFormOption(1); + CheckFocusedFieldText(L"Bar"); + SelectEditableFormOption(2); + CheckFocusedFieldText(L"Qux"); + SelectNonEditableFormOption(1); + CheckFocusedFieldText(L"Banana"); + SelectNonEditableFormOption(0); + CheckFocusedFieldText(L"Apple"); + SelectNonEditableFormOption(2); + CheckFocusedFieldText(L"Cherry"); + + // Typing into an editable field changes the text in the option. + SelectEditableFormOption(0); + CheckFocusedFieldText(L"Foo"); + TypeTextIntoTextField(5, EditableFormBegin()); + CheckFocusedFieldText(L"ABCDEFoo"); + SelectEditableFormOption(2); + CheckFocusedFieldText(L"Qux"); + TypeTextIntoTextField(2, EditableFormEnd()); + CheckFocusedFieldText(L"QuxAB"); + + // But a previously edited option is reset when selected again. + SelectEditableFormOption(0); + CheckFocusedFieldText(L"Foo"); + TypeTextIntoTextField(1, EditableFormBegin()); + CheckFocusedFieldText(L"AFoo"); + SelectEditableFormOption(0); + CheckFocusedFieldText(L"Foo"); +} diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c index fbfa71cf70..114693c43e 100644 --- a/fpdfsdk/fpdf_view_c_api_test.c +++ b/fpdfsdk/fpdf_view_c_api_test.c @@ -213,6 +213,7 @@ int CheckPDFiumCApi() { CHK(FORM_OnKeyDown); CHK(FORM_OnKeyUp); CHK(FORM_OnChar); + CHK(FORM_GetFocusedText); CHK(FORM_GetSelectedText); CHK(FORM_ReplaceSelection); CHK(FORM_ForceToKillFocus); diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h index bffeac658b..91fd5ceee8 100644 --- a/fpdfsdk/ipdfsdk_annothandler.h +++ b/fpdfsdk/ipdfsdk_annothandler.h @@ -35,6 +35,7 @@ class IPDFSDK_AnnotHandler { virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot) = 0; virtual CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) = 0; + virtual WideString GetText(CPDFSDK_Annot* pAnnot) = 0; virtual WideString GetSelectedText(CPDFSDK_Annot* pAnnot) = 0; virtual void ReplaceSelection(CPDFSDK_Annot* pAnnot, const WideString& text) = 0; |