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 <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index e0405e8..52ab4dd 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -76,6 +76,10 @@
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 df4e1a2..7ea7a0e 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.h
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.h
@@ -42,6 +42,7 @@
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 027527e..24643eb 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_baannothandler.cpp
@@ -193,6 +193,10 @@
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 7bf8034..2a03402 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.h
+++ b/fpdfsdk/cpdfsdk_baannothandler.h
@@ -36,6 +36,7 @@
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 c1b5221..b7f8cdf 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -240,6 +240,16 @@
}
#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 03f3ab6..9f846cf 100644
--- a/fpdfsdk/cpdfsdk_pageview.h
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -61,6 +61,7 @@
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 dcce7b6..6281058 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -281,10 +281,15 @@
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 f8aa7de..fbf9d2e 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.h
+++ b/fpdfsdk/cpdfsdk_widgethandler.h
@@ -37,6 +37,7 @@
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 e39f8ce..261c27c 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
@@ -100,6 +100,14 @@
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 e0dccbe..dbdb99b 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.h
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h
@@ -32,6 +32,7 @@
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 dcbe018..32bbcb7 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -219,6 +219,17 @@
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 0dfb0bb..a9d90ab 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -75,6 +75,7 @@
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 83b4257..5972d1d 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -511,6 +511,12 @@
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 94ca59d..bb0d223 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
@@ -82,6 +82,7 @@
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 912db87..7676463 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -427,6 +427,19 @@
}
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 @@
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 99a51fd..5dd4d1e 100644
--- a/fpdfsdk/fpdf_formfill_embeddertest.cpp
+++ b/fpdfsdk/fpdf_formfill_embeddertest.cpp
@@ -107,20 +107,30 @@
}
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(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 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 @@
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 @@
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 @@
// 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 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,
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 @@
CheckSelection(L"Foo");
SelectTextWithKeyboard(2, FWL_VKEY_Right, EditableFormBegin());
CheckSelection(L"Fo");
+ CheckFocusedFieldText(L"Foo");
}
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
@@ -782,17 +813,20 @@
// 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 @@
// 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 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 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 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 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 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(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, 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 @@
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 @@
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 @@
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 @@
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(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(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 @@
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 @@
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,
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 @@
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 fbfa71c..114693c 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -213,6 +213,7 @@
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 bffeac6..91fd5ce 100644
--- a/fpdfsdk/ipdfsdk_annothandler.h
+++ b/fpdfsdk/ipdfsdk_annothandler.h
@@ -35,6 +35,7 @@
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;