summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2018-04-17 15:12:58 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-04-17 15:12:58 +0000
commita4c7ac479d291fc3373b9c2f8f25302ecd53b0d5 (patch)
tree6403f92adcae02ef51897ad932ffc585c2422655 /fpdfsdk
parent3900ddb64f30f36fd6696bd2927cf8f151e6ede9 (diff)
downloadpdfium-a4c7ac479d291fc3373b9c2f8f25302ecd53b0d5.tar.xz
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>
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.cpp4
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.h1
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.cpp4
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.h1
-rw-r--r--fpdfsdk/cpdfsdk_pageview.cpp10
-rw-r--r--fpdfsdk/cpdfsdk_pageview.h1
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.cpp7
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.h1
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.cpp8
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.h1
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.cpp11
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.h1
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.cpp6
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.h1
-rw-r--r--fpdfsdk/fpdf_formfill.cpp23
-rw-r--r--fpdfsdk/fpdf_formfill_embeddertest.cpp192
-rw-r--r--fpdfsdk/fpdf_view_c_api_test.c1
-rw-r--r--fpdfsdk/ipdfsdk_annothandler.h1
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;