From a4c7ac479d291fc3373b9c2f8f25302ecd53b0d5 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 17 Apr 2018 15:12:58 +0000 Subject: Implement FORM_GetFocusedText() API. If there is a focused form field, get its text. BUG=chromium:753216 Change-Id: I05294f14d05c1c86769055f6c9eaf9177787d9fd Reviewed-on: https://pdfium-review.googlesource.com/12072 Commit-Queue: Lei Zhang Reviewed-by: dsinclair --- fpdfsdk/cpdfsdk_annothandlermgr.cpp | 4 + fpdfsdk/cpdfsdk_annothandlermgr.h | 1 + fpdfsdk/cpdfsdk_baannothandler.cpp | 4 + fpdfsdk/cpdfsdk_baannothandler.h | 1 + fpdfsdk/cpdfsdk_pageview.cpp | 10 ++ fpdfsdk/cpdfsdk_pageview.h | 1 + fpdfsdk/cpdfsdk_widgethandler.cpp | 7 +- fpdfsdk/cpdfsdk_widgethandler.h | 1 + fpdfsdk/cpdfsdk_xfawidgethandler.cpp | 8 + fpdfsdk/cpdfsdk_xfawidgethandler.h | 1 + fpdfsdk/formfiller/cffl_formfiller.cpp | 11 ++ fpdfsdk/formfiller/cffl_formfiller.h | 1 + fpdfsdk/formfiller/cffl_interactiveformfiller.cpp | 6 + fpdfsdk/formfiller/cffl_interactiveformfiller.h | 1 + fpdfsdk/fpdf_formfill.cpp | 23 ++- fpdfsdk/fpdf_formfill_embeddertest.cpp | 192 ++++++++++++++++++++-- fpdfsdk/fpdf_view_c_api_test.c | 1 + fpdfsdk/ipdfsdk_annothandler.h | 1 + public/fpdf_formfill.h | 34 +++- xfa/fxfa/cxfa_ffcombobox.cpp | 25 ++- xfa/fxfa/cxfa_ffcombobox.h | 3 + xfa/fxfa/cxfa_fftextedit.cpp | 12 +- xfa/fxfa/cxfa_fftextedit.h | 1 + xfa/fxfa/cxfa_ffwidget.cpp | 4 + xfa/fxfa/cxfa_ffwidget.h | 1 + xfa/fxfa/cxfa_ffwidgethandler.cpp | 4 + xfa/fxfa/cxfa_ffwidgethandler.h | 1 + 27 files changed, 322 insertions(+), 37 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 @@ -426,6 +426,19 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, return pPageView->OnChar(nChar, modifier); } +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, @@ -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 buf(sel_text_len); - EXPECT_EQ(expected_length, FORM_GetSelectedText(form_handle(), page_, - buf.data(), sel_text_len)); + std::vector 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 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 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 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 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 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 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 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 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 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 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 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; diff --git a/public/fpdf_formfill.h b/public/fpdf_formfill.h index 6cf2fcea0c..ff87d99ab5 100644 --- a/public/fpdf_formfill.h +++ b/public/fpdf_formfill.h @@ -1383,6 +1383,30 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, int nChar, int modifier); +/** + * Experimental API + * Function: FORM_GetFocusedText + * You can call this function to obtain the text within the current + * focused field, if any. + * Parameters: + * hHandle - Handle to the form fill module. Returned by + * FPDFDOC_InitFormFillEnvironment. + * page - Handle to the page. Returned by FPDF_LoadPage + * function. + * buffer - Buffer for holding the form text, encoded in + * UTF16-LE. If NULL, |buffer| is not modified. + * buflen - Length of |buffer| in bytes. If |buflen| is less + than the length of the form text string, |buffer| is + not modified. + * Return Value: + * Length in bytes for the text in the focused field. + **/ +FPDF_EXPORT unsigned long FPDF_CALLCONV +FORM_GetFocusedText(FPDF_FORMHANDLE hHandle, + FPDF_PAGE page, + void* buffer, + unsigned long buflen); + /** * Function: FORM_GetSelectedText * You can call this function to obtain selected text within @@ -1392,11 +1416,11 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle, * FPDFDOC_InitFormFillEnvironment. * page - Handle to the page. Returned by FPDF_LoadPage * function. - * buffer - Buffer for holding the selected text, encoded - * in UTF16-LE. If NULL, |buffer| is not modified. - * buflen - Length of |buffer| in bytes. If |buflen| - is less than the length of the selected text - string, |buffer| is not modified. + * buffer - Buffer for holding the selected text, encoded in + * UTF16-LE. If NULL, |buffer| is not modified. + * buflen - Length of |buffer| in bytes. If |buflen| is less + than the length of the selected text string, + |buffer| is not modified. * Return Value: * Length in bytes of selected text in form text field or form combobox * text field. diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp index 268d1da2b4..e4de85c517 100644 --- a/xfa/fxfa/cxfa_ffcombobox.cpp +++ b/xfa/fxfa/cxfa_ffcombobox.cpp @@ -116,14 +116,7 @@ bool CXFA_FFComboBox::CommitData() { } bool CXFA_FFComboBox::IsDataChanged() { - auto* pFWLcombobox = ToComboBox(m_pNormalWidget.get()); - WideString wsText = pFWLcombobox->GetEditText(); - int32_t iCursel = pFWLcombobox->GetCurSel(); - if (iCursel >= 0) { - WideString wsSel = pFWLcombobox->GetTextByIndex(iCursel); - if (wsSel == wsText) - wsText = m_pNode->GetChoiceListItem(iCursel, true).value_or(L""); - } + WideString wsText = GetCurrentText(); if (m_pNode->GetValue(XFA_VALUEPICTURE_Raw) == wsText) return false; @@ -138,6 +131,18 @@ void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam) { m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, pParam); } +WideString CXFA_FFComboBox::GetCurrentText() const { + auto* pFWLcombobox = ToComboBox(m_pNormalWidget.get()); + WideString wsText = pFWLcombobox->GetEditText(); + int32_t iCursel = pFWLcombobox->GetCurSel(); + if (iCursel >= 0) { + WideString wsSel = pFWLcombobox->GetTextByIndex(iCursel); + if (wsSel == wsText) + wsText = m_pNode->GetChoiceListItem(iCursel, true).value_or(L""); + } + return wsText; +} + uint32_t CXFA_FFComboBox::GetAlignment() { CXFA_Para* para = m_pNode->GetParaIfExists(); if (!para) @@ -259,6 +264,10 @@ void CXFA_FFComboBox::DeSelect() { ToComboBox(m_pNormalWidget.get())->EditDeSelect(); } +WideString CXFA_FFComboBox::GetText() { + return GetCurrentText(); +} + FormFieldType CXFA_FFComboBox::GetFormFieldType() { return FormFieldType::kXFA_ComboBox; } diff --git a/xfa/fxfa/cxfa_ffcombobox.h b/xfa/fxfa/cxfa_ffcombobox.h index 5daab781a6..66f92b2557 100644 --- a/xfa/fxfa/cxfa_ffcombobox.h +++ b/xfa/fxfa/cxfa_ffcombobox.h @@ -37,6 +37,7 @@ class CXFA_FFComboBox : public CXFA_FFDropDown { void SelectAll() override; void Delete() override; void DeSelect() override; + WideString GetText() override; FormFieldType GetFormFieldType() override; // IFWL_WidgetDelegate @@ -67,6 +68,8 @@ class CXFA_FFComboBox : public CXFA_FFDropDown { uint32_t GetAlignment(); void FWLEventSelChange(CXFA_EventParam* pParam); + WideString GetCurrentText() const; + WideString m_wsNewValue; IFWL_WidgetDelegate* m_pOldDelegate; }; diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp index fd2cfb76cc..d8de8a028f 100644 --- a/xfa/fxfa/cxfa_fftextedit.cpp +++ b/xfa/fxfa/cxfa_fftextedit.cpp @@ -63,7 +63,7 @@ bool CXFA_FFTextEdit::LoadWidget() { } void CXFA_FFTextEdit::UpdateWidgetProperty() { - CFWL_Edit* pWidget = static_cast(m_pNormalWidget.get()); + CFWL_Edit* pWidget = ToEdit(m_pNormalWidget.get()); if (!pWidget) return; @@ -185,7 +185,7 @@ bool CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) { } bool CXFA_FFTextEdit::CommitData() { - WideString wsText = static_cast(m_pNormalWidget.get())->GetText(); + WideString wsText = ToEdit(m_pNormalWidget.get())->GetText(); if (m_pNode->SetValue(XFA_VALUEPICTURE_Edit, wsText)) { m_pNode->UpdateUIDisplay(GetDoc()->GetDocView(), this); return true; @@ -255,7 +255,7 @@ bool CXFA_FFTextEdit::UpdateFWLData() { if (!m_pNormalWidget) return false; - CFWL_Edit* pEdit = static_cast(m_pNormalWidget.get()); + CFWL_Edit* pEdit = ToEdit(m_pNormalWidget.get()); XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display; if (IsFocused()) eType = XFA_VALUEPICTURE_Edit; @@ -305,7 +305,7 @@ void CXFA_FFTextEdit::OnTextChanged(CFWL_Widget* pWidget, eParam.m_wsChange = wsChanged; eParam.m_pTarget = m_pNode.Get(); eParam.m_wsPrevText = wsPrevText; - CFWL_Edit* pEdit = static_cast(m_pNormalWidget.get()); + CFWL_Edit* pEdit = ToEdit(m_pNormalWidget.get()); if (m_pNode->GetFFWidgetType() == XFA_FFWidgetType::kDateTimeEdit) { CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit; eParam.m_wsNewText = pDateTime->GetEditText(); @@ -417,6 +417,10 @@ void CXFA_FFTextEdit::DeSelect() { ToEdit(m_pNormalWidget.get())->ClearSelection(); } +WideString CXFA_FFTextEdit::GetText() { + return ToEdit(m_pNormalWidget.get())->GetText(); +} + FormFieldType CXFA_FFTextEdit::GetFormFieldType() { return FormFieldType::kXFA_TextField; } diff --git a/xfa/fxfa/cxfa_fftextedit.h b/xfa/fxfa/cxfa_fftextedit.h index 36251e152a..7c19444ae6 100644 --- a/xfa/fxfa/cxfa_fftextedit.h +++ b/xfa/fxfa/cxfa_fftextedit.h @@ -58,6 +58,7 @@ class CXFA_FFTextEdit : public CXFA_FFField { void SelectAll() override; void Delete() override; void DeSelect() override; + WideString GetText() override; FormFieldType GetFormFieldType() override; protected: diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp index f9a4807099..553612ea87 100644 --- a/xfa/fxfa/cxfa_ffwidget.cpp +++ b/xfa/fxfa/cxfa_ffwidget.cpp @@ -499,6 +499,10 @@ void CXFA_FFWidget::Delete() {} void CXFA_FFWidget::DeSelect() {} +WideString CXFA_FFWidget::GetText() { + return WideString(); +} + FormFieldType CXFA_FFWidget::GetFormFieldType() { return FormFieldType::kXFA; } diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h index a16b27a88f..0381a0c913 100644 --- a/xfa/fxfa/cxfa_ffwidget.h +++ b/xfa/fxfa/cxfa_ffwidget.h @@ -140,6 +140,7 @@ class CXFA_FFWidget : public CXFA_ContentLayoutItem { virtual void SelectAll(); virtual void Delete(); virtual void DeSelect(); + virtual WideString GetText(); virtual FormFieldType GetFormFieldType(); diff --git a/xfa/fxfa/cxfa_ffwidgethandler.cpp b/xfa/fxfa/cxfa_ffwidgethandler.cpp index f2bce57ea4..c3efd60b1d 100644 --- a/xfa/fxfa/cxfa_ffwidgethandler.cpp +++ b/xfa/fxfa/cxfa_ffwidgethandler.cpp @@ -147,6 +147,10 @@ bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget, return bRet; } +WideString CXFA_FFWidgetHandler::GetText(CXFA_FFWidget* widget) { + return widget->GetText(); +} + WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) { if (!widget->CanCopy()) return WideString(); diff --git a/xfa/fxfa/cxfa_ffwidgethandler.h b/xfa/fxfa/cxfa_ffwidgethandler.h index 378a442409..ba6a5a26ca 100644 --- a/xfa/fxfa/cxfa_ffwidgethandler.h +++ b/xfa/fxfa/cxfa_ffwidgethandler.h @@ -54,6 +54,7 @@ class CXFA_FFWidgetHandler { uint32_t dwFlags, const CFX_PointF& point); + WideString GetText(CXFA_FFWidget* widget); WideString GetSelectedText(CXFA_FFWidget* widget); void PasteText(CXFA_FFWidget* widget, const WideString& text); -- cgit v1.2.3