summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Gage <drgage@google.com>2017-07-28 17:07:39 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-07-31 21:43:06 +0000
commitab3909796cf2e9fa192040bcd7cb9da7bb3328a5 (patch)
treec4b3d336aa8d3539794ec0a9740cb9d78a7b0af8
parent47c9e6d1a151c7c8b0649712a91e04f12177b7b9 (diff)
downloadpdfium-ab3909796cf2e9fa192040bcd7cb9da7bb3328a5.tar.xz
Add FORM_ReplaceSelection() and embedder tests.
This method replaces the selected text in a user-editable form text area with another text string (which can be empty or non-empty). If there is no selected text, FORM_ReplaceSelection() will append the replacement text after the current caret position. BUG=chromium:59266 Change-Id: I76448ef757d107888c33ebd5656457ebac93b952 Reviewed-on: https://pdfium-review.googlesource.com/8812 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Diana Gage <drgage@google.com>
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.cpp6
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.h3
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.cpp3
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.h3
-rw-r--r--fpdfsdk/cpdfsdk_pageview.cpp4
-rw-r--r--fpdfsdk/cpdfsdk_pageview.h2
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.cpp5
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.h3
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.cpp7
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.h3
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.cpp5
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.h2
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.cpp5
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.h2
-rw-r--r--fpdfsdk/fpdfformfill.cpp11
-rw-r--r--fpdfsdk/fpdfformfill_embeddertest.cpp647
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c2
-rw-r--r--fpdfsdk/ipdfsdk_annothandler.h3
-rw-r--r--fpdfsdk/pwl/cpwl_combo_box.cpp4
-rw-r--r--fpdfsdk/pwl/cpwl_combo_box.h2
-rw-r--r--fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp97
-rw-r--r--fpdfsdk/pwl/cpwl_edit_ctrl.cpp9
-rw-r--r--fpdfsdk/pwl/cpwl_edit_ctrl.h2
-rw-r--r--fpdfsdk/pwl/cpwl_edit_embeddertest.cpp232
-rw-r--r--fpdfsdk/pwl/cpwl_wnd.cpp2
-rw-r--r--fpdfsdk/pwl/cpwl_wnd.h2
-rw-r--r--public/fpdf_formfill.h16
-rw-r--r--testing/resources/text_form_multiple.in16
-rw-r--r--testing/resources/text_form_multiple.pdf39
29 files changed, 1044 insertions, 93 deletions
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index fd77a73460..a1ac14cc69 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -81,8 +81,10 @@ CFX_WideString CPDFSDK_AnnotHandlerMgr::Annot_GetSelectedText(
return GetAnnotHandler(pAnnot)->GetSelectedText(pAnnot);
}
-void CPDFSDK_AnnotHandlerMgr::Annot_DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
- GetAnnotHandler(pAnnot)->DeleteSelectedText(pAnnot);
+void CPDFSDK_AnnotHandlerMgr::Annot_ReplaceSelection(
+ CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {
+ GetAnnotHandler(pAnnot)->ReplaceSelection(pAnnot, text);
}
IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h
index 93c552bbfb..96765e5ef1 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.h
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.h
@@ -44,7 +44,8 @@ class CPDFSDK_AnnotHandlerMgr {
void Annot_OnLoad(CPDFSDK_Annot* pAnnot);
CFX_WideString Annot_GetSelectedText(CPDFSDK_Annot* pAnnot);
- void Annot_DeleteSelectedText(CPDFSDK_Annot* pAnnot);
+ void Annot_ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text);
IPDFSDK_AnnotHandler* GetAnnotHandler(CPDFSDK_Annot* pAnnot) const;
void Annot_OnDraw(CPDFSDK_PageView* pPageView,
diff --git a/fpdfsdk/cpdfsdk_baannothandler.cpp b/fpdfsdk/cpdfsdk_baannothandler.cpp
index cf09d2bbcb..029df85bd7 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_baannothandler.cpp
@@ -197,7 +197,8 @@ CFX_WideString CPDFSDK_BAAnnotHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return CFX_WideString();
}
-void CPDFSDK_BAAnnotHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {}
+void CPDFSDK_BAAnnotHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {}
bool CPDFSDK_BAAnnotHandler::HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h
index 7db9a4d7d7..86f7b937e8 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.h
+++ b/fpdfsdk/cpdfsdk_baannothandler.h
@@ -38,7 +38,8 @@ class CPDFSDK_BAAnnotHandler : public IPDFSDK_AnnotHandler {
CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot) override;
CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override;
- void DeleteSelectedText(CPDFSDK_Annot* pAnnot) override;
+ void ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) override;
bool HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) override;
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
index 84a60fa42f..209e8de482 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -253,11 +253,11 @@ CFX_WideString CPDFSDK_PageView::GetSelectedText() {
return CFX_WideString();
}
-void CPDFSDK_PageView::DeleteSelectedText() {
+void CPDFSDK_PageView::ReplaceSelection(const CFX_WideString& text) {
if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
m_pFormFillEnv->GetAnnotHandlerMgr();
- pAnnotHandlerMgr->Annot_DeleteSelectedText(pAnnot);
+ pAnnotHandlerMgr->Annot_ReplaceSelection(pAnnot, text);
}
}
diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h
index d4b7721575..c525bfc457 100644
--- a/fpdfsdk/cpdfsdk_pageview.h
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -61,7 +61,7 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
}
CFX_WideString GetSelectedText();
- void DeleteSelectedText();
+ void ReplaceSelection(const CFX_WideString& text);
bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag);
bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag);
diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp
index 1c802a3ba7..f5cd802001 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -287,9 +287,10 @@ CFX_WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return CFX_WideString();
}
-void CPDFSDK_WidgetHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+void CPDFSDK_WidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {
if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
- m_pFormFiller->DeleteSelectedText(pAnnot);
+ m_pFormFiller->ReplaceSelection(pAnnot, text);
}
bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h
index 2d33ff5686..60bfd834a2 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.h
+++ b/fpdfsdk/cpdfsdk_widgethandler.h
@@ -39,7 +39,8 @@ class CPDFSDK_WidgetHandler : public IPDFSDK_AnnotHandler {
CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot) override;
CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override;
- void DeleteSelectedText(CPDFSDK_Annot* pAnnot) override;
+ void ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) override;
bool HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) override;
diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
index 746d1ca763..e7bf702966 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
@@ -97,16 +97,17 @@ CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
return rcWidget;
}
-// TODO(crbug.com/62400): Implement so selected text can be obtained from XFA
+// TODO(bug 840): Implement so selected text can be obtained from XFA
// fields.
CFX_WideString CPDFSDK_XFAWidgetHandler::GetSelectedText(
CPDFSDK_Annot* pAnnot) {
return CFX_WideString();
}
-// TODO(crbug.com/62400): Implement so selected text can be deleted from XFA
+// TODO(bug 840): Implement so text can be inserted into and deleted from XFA
// fields.
-void CPDFSDK_XFAWidgetHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {}
+void CPDFSDK_XFAWidgetHandler::ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {}
bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.h b/fpdfsdk/cpdfsdk_xfawidgethandler.h
index 3d06948116..26e991d6ed 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.h
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h
@@ -34,7 +34,8 @@ class CPDFSDK_XFAWidgetHandler : public IPDFSDK_AnnotHandler {
CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot) override;
CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot) override;
- void DeleteSelectedText(CPDFSDK_Annot* pAnnot) override;
+ void ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) override;
bool HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) override;
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
index a37a7501d0..e0af8955ac 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -245,7 +245,8 @@ CFX_WideString CFFL_FormFiller::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return pWnd ? pWnd->GetSelectedText() : CFX_WideString();
}
-void CFFL_FormFiller::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+void CFFL_FormFiller::ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {
if (!IsValid())
return;
@@ -256,7 +257,7 @@ void CFFL_FormFiller::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
if (!pWnd)
return;
- pWnd->DeleteSelectedText();
+ pWnd->ReplaceSelection(text);
}
void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
index 96b7a69b29..4769716be5 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -75,7 +75,7 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler {
virtual bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags);
CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot);
- void DeleteSelectedText(CPDFSDK_Annot* pAnnot);
+ void ReplaceSelection(CPDFSDK_Annot* pAnnot, const CFX_WideString& text);
void SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag);
void KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag);
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
index 24bfd3c3b2..6d250408f0 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -523,13 +523,14 @@ CFX_WideString CFFL_InteractiveFormFiller::GetSelectedText(
return pFormFiller ? pFormFiller->GetSelectedText(pAnnot) : CFX_WideString();
}
-void CFFL_InteractiveFormFiller::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+void CFFL_InteractiveFormFiller::ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) {
ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false);
if (!pFormFiller)
return;
- pFormFiller->DeleteSelectedText(pAnnot);
+ pFormFiller->ReplaceSelection(pAnnot, text);
}
void CFFL_InteractiveFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
index 17e9407924..b71f3a6ef7 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
@@ -84,7 +84,7 @@ class CFFL_InteractiveFormFiller : public IPWL_Filler_Notify {
void RemoveFormFiller(CPDFSDK_Annot* pAnnot);
CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot);
- void DeleteSelectedText(CPDFSDK_Annot* pAnnot);
+ void ReplaceSelection(CPDFSDK_Annot* pAnnot, const CFX_WideString& text);
static bool IsVisible(CPDFSDK_Widget* pWidget);
static bool IsReadOnly(CPDFSDK_Widget* pWidget);
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
index e541b81cc3..7f4e3dfd69 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -383,12 +383,17 @@ DLLEXPORT unsigned long STDCALL FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
return form_text_len;
}
-DLLEXPORT void STDCALL FORM_DeleteSelectedText(FPDF_FORMHANDLE hHandle,
- FPDF_PAGE page) {
+DLLEXPORT void STDCALL FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,
+ FPDF_PAGE page,
+ FPDF_WIDESTRING wsText) {
CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
if (!pPageView)
return;
- pPageView->DeleteSelectedText();
+
+ FX_STRSIZE len = CFX_WideString::WStringLength(wsText);
+ CFX_WideString wide_str_text = CFX_WideString::FromUTF16LE(wsText, len);
+
+ pPageView->ReplaceSelection(wide_str_text);
}
DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
diff --git a/fpdfsdk/fpdfformfill_embeddertest.cpp b/fpdfsdk/fpdfformfill_embeddertest.cpp
index 1505fdc390..13d5f08d56 100644
--- a/fpdfsdk/fpdfformfill_embeddertest.cpp
+++ b/fpdfsdk/fpdfformfill_embeddertest.cpp
@@ -656,7 +656,8 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldEntireSelection) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
+
SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
CheckSelection(page, CFX_WideString());
@@ -676,7 +677,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionMiddle) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
CheckSelection(page, CFX_WideString(L"ABCJKL"));
@@ -696,7 +697,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionLeft) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
CheckSelection(page, CFX_WideString(L"EFGHIJKL"));
@@ -716,7 +717,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionRight) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
CheckSelection(page, CFX_WideString(L"ABCDEFGH"));
@@ -734,7 +735,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEmptyTextFieldSelection) {
CheckSelection(page, CFX_WideString());
// Test that attempt to delete empty text selection has no effect.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
@@ -754,7 +755,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxEntireSelection) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithMouse(page, 178.0, 102.0, 62.0);
CheckSelection(page, CFX_WideString());
@@ -774,7 +775,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionMiddle) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithMouse(page, 178.0, 102.0, 62.0);
CheckSelection(page, CFX_WideString(L"ABCIJ"));
@@ -794,7 +795,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionLeft) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithMouse(page, 178.0, 102.0, 62.0);
CheckSelection(page, CFX_WideString(L"EFGHIJ"));
@@ -814,7 +815,7 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionRight) {
// Test deleting current text selection. Select what remains after deletion to
// check that remaining text is as expected.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithMouse(page, 178.0, 102.0, 62.0);
CheckSelection(page, CFX_WideString(L"ABCDEF"));
@@ -832,9 +833,635 @@ TEST_F(FPDFFormFillEmbeddertest, DeleteEmptyEditableComboBoxSelection) {
CheckSelection(page, CFX_WideString());
// Test that attempt to delete empty text selection has no effect.
- FORM_DeleteSelectedText(form_handle(), page);
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
SelectTextWithMouse(page, 178.0, 102.0, 62.0);
CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
UnloadPage(page);
}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInEmptyTextField) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ ClickOnFormFieldAtPoint(page, 120.0, 120.0);
+
+ // 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"Hello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedTextFieldLeft) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 8, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Click on the leftmost part of the text field.
+ ClickOnFormFieldAtPoint(page, 102.0, 115.5);
+
+ // 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"HelloABCDEFGH"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedTextFieldMiddle) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 8, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Click on the middle of the text field.
+ ClickOnFormFieldAtPoint(page, 134.0, 115.5);
+
+ // Test inserting text in the middle 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDHelloEFGH"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedTextFieldRight) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 8, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Click on the rightmost part of the text field.
+ ClickOnFormFieldAtPoint(page, 166.0, 115.5);
+
+ // Test inserting text behind 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHHello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldWhole) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select entire string in text field.
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 195.0, 115.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"Hello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldLeft) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select left portion of string in text field.
+ SelectTextWithKeyboard(page, 6, FWL_VKEY_Left, 148.0, 115.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEF"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"HelloGHIJKL"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select middle portion of string in text field.
+ SelectTextWithKeyboard(page, 6, FWL_VKEY_Left, 171.0, 115.0);
+ CheckSelection(page, CFX_WideString(L"DEFGHI"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCHelloJKL"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldRight) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select right portion of string in text field.
+ SelectTextWithKeyboard(page, 6, FWL_VKEY_Left, 195.0, 115.0);
+ CheckSelection(page, CFX_WideString(L"GHIJKL"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDEFHello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInEmptyEditableComboBox) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ ClickOnFormFieldAtPoint(page, 102.0, 62.0);
+
+ // 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());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"Hello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedEditableComboBoxLeft) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 6, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Click on the leftmost part of the user-editable combobox.
+ ClickOnFormFieldAtPoint(page, 102.0, 62.0);
+
+ // Test inserting text in front of existing text in 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());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"HelloABCDEF"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedEditableComboBoxMiddle) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 6, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Click on the middle of the user-editable combobox.
+ ClickOnFormFieldAtPoint(page, 126.0, 62.0);
+
+ // Test inserting text in the middle of existing text in 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());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCHelloDEF"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedEditableComboBoxRight) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 6, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Click on the rightmost part of the user-editable combobox.
+ ClickOnFormFieldAtPoint(page, 150.0, 62.0);
+
+ // Test inserting text behind existing text in 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());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEFHello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Select entire string in user-editable combobox.
+ SelectTextWithKeyboard(page, 10, FWL_VKEY_Left, 183.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"Hello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Select left portion of string in user-editable combobox.
+ SelectTextWithKeyboard(page, 5, FWL_VKEY_Left, 142.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCDE"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"HelloFGHIJ"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Select middle portion of string in user-editable combobox.
+ SelectTextWithKeyboard(page, 5, FWL_VKEY_Left, 167.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCHelloIJ"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+ // Select right portion of string in user-editable combobox.
+ SelectTextWithKeyboard(page, 5, FWL_VKEY_Left, 183.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"FGHIJ"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hello");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of user-editable combobox text field to check that
+ // insertion worked as expected.
+ SelectTextWithMouse(page, 183.0, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEHello"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInEmptyCharLimitTextFieldOverflow) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Click on the textfield.
+ ClickOnFormFieldAtPoint(page, 195.0, 60.0);
+
+ // Delete pre-filled contents of text field with char limit.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Elephant"));
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
+
+ // 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Hippopotam"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInEmptyCharLimitTextFieldFit) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Click on the textfield.
+ ClickOnFormFieldAtPoint(page, 195.0, 60.0);
+
+ // Delete pre-filled contents of text field with char limit.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Elephant"));
+ FORM_ReplaceSelection(form_handle(), page, nullptr);
+
+ // 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"Zebra");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Zebra"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedCharLimitTextFieldLeft) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Click on the leftmost part of the text field.
+ ClickOnFormFieldAtPoint(page, 102.0, 60.0);
+
+ // Test inserting text in front 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"HiElephant"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextInPopulatedCharLimitTextFieldMiddle) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 8, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Click on the middle of the text field.
+ ClickOnFormFieldAtPoint(page, 134.0, 60.0);
+
+ // 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"ElephHiant"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, InsertTextInPopulatedCharLimitTextFieldRight) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 8, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Click on the rightmost part of the text field.
+ ClickOnFormFieldAtPoint(page, 166.0, 60.0);
+
+ // Test inserting text behind 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());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"ElephantHi"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select entire string in text field.
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 195.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Elephant"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hippopotamus");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Hippopotam"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select left portion of string in text field.
+ SelectTextWithKeyboard(page, 4, FWL_VKEY_Left, 122.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Elep"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hippopotamus");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"Hippophant"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select middle portion of string in text field.
+ SelectTextWithKeyboard(page, 4, FWL_VKEY_Left, 136.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"epha"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hippopotamus");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"ElHippopnt"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight) {
+ // Open file with form text field with a character limit of 10.
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+
+ // Select right portion of string in text field.
+ SelectTextWithKeyboard(page, 4, FWL_VKEY_Left, 152.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"hant"));
+
+ // Test replacing text selection with text to be inserted.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
+ GetFPDFWideString(L"Hippopotamus");
+ FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
+
+ // Select entire contents of text field to check that insertion worked
+ // as expected.
+ SelectTextWithMouse(page, 195.0, 102.0, 60.0);
+ CheckSelection(page, CFX_WideString(L"ElepHippop"));
+
+ UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index 95a0175999..7d42be8792 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -182,7 +182,7 @@ int CheckPDFiumCApi() {
CHK(FORM_OnKeyUp);
CHK(FORM_OnChar);
CHK(FORM_GetSelectedText);
- CHK(FORM_DeleteSelectedText);
+ CHK(FORM_ReplaceSelection);
CHK(FORM_ForceToKillFocus);
CHK(FPDFPage_HasFormFieldAtPoint);
CHK(FPDFPage_FormFieldZOrderAtPoint);
diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h
index 5340978308..3a35cdc8ff 100644
--- a/fpdfsdk/ipdfsdk_annothandler.h
+++ b/fpdfsdk/ipdfsdk_annothandler.h
@@ -37,7 +37,8 @@ class IPDFSDK_AnnotHandler {
virtual CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot) = 0;
virtual CFX_WideString GetSelectedText(CPDFSDK_Annot* pAnnot) = 0;
- virtual void DeleteSelectedText(CPDFSDK_Annot* pAnnot) = 0;
+ virtual void ReplaceSelection(CPDFSDK_Annot* pAnnot,
+ const CFX_WideString& text) = 0;
virtual bool HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) = 0;
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 9514e55646..49254b8171 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -184,9 +184,9 @@ CFX_WideString CPWL_ComboBox::GetSelectedText() {
return CFX_WideString();
}
-void CPWL_ComboBox::DeleteSelectedText() {
+void CPWL_ComboBox::ReplaceSelection(const CFX_WideString& text) {
if (m_pEdit)
- m_pEdit->DeleteSelectedText();
+ m_pEdit->ReplaceSelection(text);
}
CFX_WideString CPWL_ComboBox::GetText() const {
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
index a50c4cee37..81e4256e18 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.h
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
@@ -63,7 +63,7 @@ class CPWL_ComboBox : public CPWL_Wnd {
void SetFocus() override;
void KillFocus() override;
CFX_WideString GetSelectedText() override;
- void DeleteSelectedText() override;
+ void ReplaceSelection(const CFX_WideString& text) override;
void SetFillerNotify(IPWL_Filler_Notify* pNotify);
diff --git a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
index 30fe32bc53..308ee4ac40 100644
--- a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
@@ -211,7 +211,7 @@ TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEntireTextSelection) {
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLComboBox()->GetSelectedText().c_str());
- GetCPWLComboBox()->DeleteSelectedText();
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString());
EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
}
@@ -222,7 +222,7 @@ TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionMiddle) {
GetCPWLComboBox()->SetEditSelection(12, 23);
EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
- GetCPWLComboBox()->DeleteSelectedText();
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLComboBox()->GetText().c_str());
}
@@ -234,7 +234,7 @@ TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionLeft) {
GetCPWLComboBox()->SetEditSelection(0, 5);
EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
- GetCPWLComboBox()->DeleteSelectedText();
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLComboBox()->GetText().c_str());
}
@@ -246,7 +246,7 @@ TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionRight) {
GetCPWLComboBox()->SetEditSelection(45, 50);
EXPECT_STREQ(L"nopqr", GetCPWLComboBox()->GetSelectedText().c_str());
- GetCPWLComboBox()->DeleteSelectedText();
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
GetCPWLComboBox()->GetText().c_str());
}
@@ -255,7 +255,94 @@ TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEmptyTextSelection) {
FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
TypeTextIntoTextField(50);
- GetCPWLComboBox()->DeleteSelectedText();
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLComboBox()->GetText().c_str());
}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, InsertTextInEmptyEditableComboBox) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"Hello", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextInPopulatedEditableComboBoxLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ // Move cursor to beginning of user-editable combobox text field.
+ EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotUserEditable(),
+ FWL_VKEY_Home, 0));
+
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"HelloABCDEFGHIJ", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextInPopulatedEditableComboBoxMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ // Move cursor to middle of user-editable combobox text field.
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotUserEditable(),
+ FWL_VKEY_Left, 0));
+ }
+
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEHelloFGHIJ", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextInPopulatedEditableComboBoxRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEFGHIJHello", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ GetCPWLComboBox()->SetEditSelection(0, -1);
+ EXPECT_STREQ(L"ABCDEFGHIJ", GetCPWLComboBox()->GetSelectedText().c_str());
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"Hello", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ GetCPWLComboBox()->SetEditSelection(0, 5);
+ EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"HelloFGHIJ", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ GetCPWLComboBox()->SetEditSelection(2, 7);
+ EXPECT_STREQ(L"CDEFG", GetCPWLComboBox()->GetSelectedText().c_str());
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABHelloHIJ", GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ TypeTextIntoTextField(10);
+
+ GetCPWLComboBox()->SetEditSelection(5, 10);
+ EXPECT_STREQ(L"FGHIJ", GetCPWLComboBox()->GetSelectedText().c_str());
+ GetCPWLComboBox()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEHello", GetCPWLComboBox()->GetText().c_str());
+}
diff --git a/fpdfsdk/pwl/cpwl_edit_ctrl.cpp b/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
index a852cb6231..1a7b0e4c49 100644
--- a/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
+++ b/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
@@ -59,9 +59,12 @@ CFX_WideString CPWL_EditCtrl::GetSelectedText() {
return CFX_WideString();
}
-void CPWL_EditCtrl::DeleteSelectedText() {
- if (m_pEdit)
- m_pEdit->ClearSelection();
+void CPWL_EditCtrl::ReplaceSelection(const CFX_WideString& text) {
+ if (!m_pEdit)
+ return;
+
+ m_pEdit->ClearSelection();
+ m_pEdit->InsertText(text, FX_CHARSET_Default);
}
void CPWL_EditCtrl::RePosChildWnd() {
diff --git a/fpdfsdk/pwl/cpwl_edit_ctrl.h b/fpdfsdk/pwl/cpwl_edit_ctrl.h
index 4fb86fab62..03dc4be1e1 100644
--- a/fpdfsdk/pwl/cpwl_edit_ctrl.h
+++ b/fpdfsdk/pwl/cpwl_edit_ctrl.h
@@ -61,7 +61,7 @@ class CPWL_EditCtrl : public CPWL_Wnd {
float GetFontSize() const override;
void SetCursor() override;
CFX_WideString GetSelectedText() override;
- void DeleteSelectedText() override;
+ void ReplaceSelection(const CFX_WideString& text) override;
void SetCaret(bool bVisible,
const CFX_PointF& ptHead,
diff --git a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
index 98cc44ab86..34569b2491 100644
--- a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
+++ b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
@@ -24,35 +24,44 @@ class CPWLEditEmbeddertest : public EmbedderTest {
}
void CreateAndInitializeFormPDF() {
- EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ EXPECT_TRUE(OpenDocument("text_form_multiple.pdf"));
m_page = LoadPage(0);
ASSERT_TRUE(m_page);
- CPDFSDK_FormFillEnvironment* pFormFillEnv =
- static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
-
- {
- CBA_AnnotIterator iter(pFormFillEnv->GetPageView(0),
- CPDF_Annot::Subtype::WIDGET);
- m_pAnnot = iter.GetFirstAnnot();
- CPDFSDK_Annot* pLastAnnot = iter.GetLastAnnot();
- ASSERT_EQ(m_pAnnot, pLastAnnot);
- ASSERT_TRUE(m_pAnnot);
- ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnot->GetAnnotSubtype());
- }
+ m_pFormFillEnv = static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+ CBA_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
+ CPDF_Annot::Subtype::WIDGET);
+ // Normal text field.
+ m_pAnnot = iter.GetFirstAnnot();
+ ASSERT_TRUE(m_pAnnot);
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnot->GetAnnotSubtype());
+
+ // Read-only text field.
+ CPDFSDK_Annot* pAnnotReadOnly = iter.GetNextAnnot(m_pAnnot);
+
+ // Pre-filled text field with char limit of 10.
+ m_pAnnotCharLimit = iter.GetNextAnnot(pAnnotReadOnly);
+ ASSERT_TRUE(m_pAnnotCharLimit);
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
+ m_pAnnotCharLimit->GetAnnotSubtype());
+ CPDFSDK_Annot* pLastAnnot = iter.GetLastAnnot();
+ ASSERT_EQ(m_pAnnotCharLimit, pLastAnnot);
+ }
+ void FormFillerAndWindowSetup(CPDFSDK_Annot* pAnnotTextField) {
CFFL_InteractiveFormFiller* pInteractiveFormFiller =
- pFormFillEnv->GetInteractiveFormFiller();
+ m_pFormFillEnv->GetInteractiveFormFiller();
{
- CPDFSDK_Annot::ObservedPtr pObserved(m_pAnnot);
+ CPDFSDK_Annot::ObservedPtr pObserved(pAnnotTextField);
EXPECT_TRUE(pInteractiveFormFiller->OnSetFocus(&pObserved, 0));
}
- m_pFormFiller = pInteractiveFormFiller->GetFormFiller(m_pAnnot, false);
+ m_pFormFiller =
+ pInteractiveFormFiller->GetFormFiller(pAnnotTextField, false);
ASSERT_TRUE(m_pFormFiller);
CPWL_Wnd* pWindow =
- m_pFormFiller->GetPDFWindow(pFormFillEnv->GetPageView(0), false);
+ m_pFormFiller->GetPDFWindow(m_pFormFillEnv->GetPageView(0), false);
ASSERT_TRUE(pWindow);
ASSERT_EQ(PWL_CLASSNAME_EDIT, pWindow->GetClassName());
@@ -70,15 +79,19 @@ class CPWLEditEmbeddertest : public EmbedderTest {
CPWL_Edit* GetCPWLEdit() { return m_pEdit; }
CFFL_FormFiller* GetCFFLFormFiller() { return m_pFormFiller; }
CPDFSDK_Annot* GetCPDFSDKAnnot() { return m_pAnnot; }
+ CPDFSDK_Annot* GetCPDFSDKAnnotCharLimit() { return m_pAnnotCharLimit; }
private:
FPDF_PAGE m_page;
CPWL_Edit* m_pEdit;
CFFL_FormFiller* m_pFormFiller;
CPDFSDK_Annot* m_pAnnot;
+ CPDFSDK_Annot* m_pAnnotCharLimit;
+ CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
};
TEST_F(CPWLEditEmbeddertest, TypeText) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
EXPECT_TRUE(GetCPWLEdit()->GetText().IsEmpty());
EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), 'a', 0));
EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), 'b', 0));
@@ -88,6 +101,7 @@ TEST_F(CPWLEditEmbeddertest, TypeText) {
}
TEST_F(CPWLEditEmbeddertest, GetSelectedTextEmptyAndBasic) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
// Attempt to set selection before text has been typed to test that
// selection is identified as empty.
//
@@ -104,6 +118,7 @@ TEST_F(CPWLEditEmbeddertest, GetSelectedTextEmptyAndBasic) {
}
TEST_F(CPWLEditEmbeddertest, GetSelectedTextFragments) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
GetCPWLEdit()->SetSelection(0, 0);
@@ -133,53 +148,226 @@ TEST_F(CPWLEditEmbeddertest, GetSelectedTextFragments) {
}
TEST_F(CPWLEditEmbeddertest, DeleteEntireTextSelection) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
GetCPWLEdit()->SetSelection(0, -1);
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLEdit()->GetSelectedText().c_str());
- GetCPWLEdit()->DeleteSelectedText();
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
EXPECT_TRUE(GetCPWLEdit()->GetText().IsEmpty());
}
TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
GetCPWLEdit()->SetSelection(12, 23);
EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLEdit()->GetSelectedText().c_str());
- GetCPWLEdit()->DeleteSelectedText();
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLEdit()->GetText().c_str());
}
TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
GetCPWLEdit()->SetSelection(0, 5);
EXPECT_STREQ(L"ABCDE", GetCPWLEdit()->GetSelectedText().c_str());
- GetCPWLEdit()->DeleteSelectedText();
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLEdit()->GetText().c_str());
}
TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
GetCPWLEdit()->SetSelection(45, 50);
EXPECT_STREQ(L"nopqr", GetCPWLEdit()->GetSelectedText().c_str());
- GetCPWLEdit()->DeleteSelectedText();
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
GetCPWLEdit()->GetText().c_str());
}
TEST_F(CPWLEditEmbeddertest, DeleteEmptyTextSelection) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
TypeTextIntoTextField(50);
- GetCPWLEdit()->DeleteSelectedText();
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
GetCPWLEdit()->GetText().c_str());
}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInEmptyTextField) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"Hello", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedTextFieldLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ // Move cursor to beginning of text field.
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnot(), FWL_VKEY_Home, 0));
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"HelloABCDEFGHIJ", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedTextFieldMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ // Move cursor to middle of text field.
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnot(), FWL_VKEY_Left, 0));
+ }
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEHelloFGHIJ", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedTextFieldRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEFGHIJHello", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldWhole) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ GetCPWLEdit()->SetSelection(0, -1);
+ EXPECT_STREQ(L"ABCDEFGHIJ", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"Hello", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ GetCPWLEdit()->SetSelection(0, 5);
+ EXPECT_STREQ(L"ABCDE", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"HelloFGHIJ", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ GetCPWLEdit()->SetSelection(2, 7);
+ EXPECT_STREQ(L"CDEFG", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABHelloHIJ", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedTextFieldRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnot());
+ TypeTextIntoTextField(10);
+
+ GetCPWLEdit()->SetSelection(5, 10);
+ EXPECT_STREQ(L"FGHIJ", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hello"));
+ EXPECT_STREQ(L"ABCDEHello", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInEmptyCharLimitTextFieldOverflow) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(0, -1);
+ EXPECT_STREQ(L"Elephant", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"Hippopotam", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInEmptyCharLimitTextFieldFit) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(0, -1);
+ EXPECT_STREQ(L"Elephant", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString());
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Zebra"));
+ EXPECT_STREQ(L"Zebra", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedCharLimitTextFieldLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"HiElephant", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedCharLimitTextFieldMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ // Move cursor to middle of text field.
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotCharLimit(),
+ FWL_VKEY_Right, 0));
+ }
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"ElephHiant", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, InsertTextInPopulatedCharLimitTextFieldRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ // Move cursor to end of text field.
+ EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotCharLimit(),
+ FWL_VKEY_End, 0));
+
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"ElephantHi", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(0, -1);
+ EXPECT_STREQ(L"Elephant", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"Hippopotam", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(0, 4);
+ EXPECT_STREQ(L"Elep", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"Hippophant", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(2, 6);
+ EXPECT_STREQ(L"epha", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"ElHippopnt", GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest,
+ InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCharLimit());
+ GetCPWLEdit()->SetSelection(4, 8);
+ EXPECT_STREQ(L"hant", GetCPWLEdit()->GetSelectedText().c_str());
+ GetCPWLEdit()->ReplaceSelection(CFX_WideString(L"Hippopotamus"));
+ EXPECT_STREQ(L"ElepHippop", GetCPWLEdit()->GetText().c_str());
+}
diff --git a/fpdfsdk/pwl/cpwl_wnd.cpp b/fpdfsdk/pwl/cpwl_wnd.cpp
index 2269162260..c7bf23ce60 100644
--- a/fpdfsdk/pwl/cpwl_wnd.cpp
+++ b/fpdfsdk/pwl/cpwl_wnd.cpp
@@ -369,7 +369,7 @@ CFX_WideString CPWL_Wnd::GetSelectedText() {
return CFX_WideString();
}
-void CPWL_Wnd::DeleteSelectedText() {}
+void CPWL_Wnd::ReplaceSelection(const CFX_WideString& text) {}
bool CPWL_Wnd::OnMouseWheel(short zDelta,
const CFX_PointF& point,
diff --git a/fpdfsdk/pwl/cpwl_wnd.h b/fpdfsdk/pwl/cpwl_wnd.h
index 7c93216a58..15487a3c07 100644
--- a/fpdfsdk/pwl/cpwl_wnd.h
+++ b/fpdfsdk/pwl/cpwl_wnd.h
@@ -202,7 +202,7 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable<CPWL_Wnd> {
virtual float GetFontSize() const;
virtual CFX_WideString GetSelectedText();
- virtual void DeleteSelectedText();
+ virtual void ReplaceSelection(const CFX_WideString& text);
virtual CFX_FloatRect GetFocusRect() const;
virtual CFX_FloatRect GetClientRect() const;
diff --git a/public/fpdf_formfill.h b/public/fpdf_formfill.h
index 83a4e58bdc..617bc34b17 100644
--- a/public/fpdf_formfill.h
+++ b/public/fpdf_formfill.h
@@ -1378,20 +1378,24 @@ DLLEXPORT unsigned long STDCALL FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
unsigned long buflen);
/**
- * Function: FORM_DeleteSelectedText
- * You can call this function to delete the current text selection in
- * a form text field or user-editable form combobox text field. If
- * there is no selected text, this function does nothing.
+ * Function: FORM_ReplaceSelection
+ * You can call this function to replace the selected text in a form
+ * text field or user-editable form combobox text field with another
+ * text string (which can be empty or non-empty). If there is no
+ * selected text, this function will append the replacement text after
+ * the current caret position.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
* FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
* function.
+ * wsText - The text to be inserted, in UTF-16LE format.
* Return Value:
* None.
**/
-DLLEXPORT void STDCALL FORM_DeleteSelectedText(FPDF_FORMHANDLE hHandle,
- FPDF_PAGE page);
+DLLEXPORT void STDCALL FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,
+ FPDF_PAGE page,
+ FPDF_WIDESTRING wsText);
/**
* Function: FORM_ForceToKillFocus.
diff --git a/testing/resources/text_form_multiple.in b/testing/resources/text_form_multiple.in
index 43919eb200..576e15597c 100644
--- a/testing/resources/text_form_multiple.in
+++ b/testing/resources/text_form_multiple.in
@@ -3,7 +3,7 @@
<<
/Type /Catalog
/Pages 2 0 R
- /AcroForm << /Fields [ 4 0 R 9 0 R ] /DR 5 0 R >>
+ /AcroForm << /Fields [ 4 0 R 9 0 R 10 0 R ] /DR 5 0 R >>
>>
endobj
{{object 2 0}}
@@ -16,7 +16,7 @@ endobj
/Resources 5 0 R
/MediaBox [ 0 0 300 300 ]
/Contents 8 0 R
- /Annots [ 4 0 R 9 0 R ]
+ /Annots [ 4 0 R 9 0 R 10 0 R ]
>>
endobj
{{object 4 0}}
@@ -63,6 +63,18 @@ endobj
/Subtype /Widget
>>
endobj
+{{object 10 0}}
+<<
+ /Type /Annot
+ /FT /Tx
+ /T (CharLimit)
+ /MaxLen 10
+ /DA (0 0 0 rg /F1 12 Tf)
+ /V (Elephant)
+ /Rect [ 100 50 200 75 ]
+ /Subtype /Widget
+>>
+endobj
{{xref}}
{{trailer}}
{{startxref}}
diff --git a/testing/resources/text_form_multiple.pdf b/testing/resources/text_form_multiple.pdf
index 6b14cefa82..172ab5e864 100644
--- a/testing/resources/text_form_multiple.pdf
+++ b/testing/resources/text_form_multiple.pdf
@@ -4,7 +4,7 @@
<<
/Type /Catalog
/Pages 2 0 R
- /AcroForm << /Fields [ 4 0 R 9 0 R ] /DR 5 0 R >>
+ /AcroForm << /Fields [ 4 0 R 9 0 R 10 0 R ] /DR 5 0 R >>
>>
endobj
2 0 obj
@@ -17,7 +17,7 @@ endobj
/Resources 5 0 R
/MediaBox [ 0 0 300 300 ]
/Contents 8 0 R
- /Annots [ 4 0 R 9 0 R ]
+ /Annots [ 4 0 R 9 0 R 10 0 R ]
>>
endobj
4 0 obj
@@ -64,19 +64,32 @@ endobj
/Subtype /Widget
>>
endobj
+10 0 obj
+<<
+ /Type /Annot
+ /FT /Tx
+ /T (CharLimit)
+ /MaxLen 10
+ /DA (0 0 0 rg /F1 12 Tf)
+ /V (Elephant)
+ /Rect [ 100 50 200 75 ]
+ /Subtype /Widget
+>>
+endobj
xref
-0 10
+0 11
0000000000 65535 f
0000000015 00000 n
-0000000120 00000 n
-0000000179 00000 n
-0000000321 00000 n
-0000000457 00000 n
-0000000490 00000 n
-0000000521 00000 n
-0000000597 00000 n
-0000000697 00000 n
-trailer<< /Root 1 0 R /Size 10 >>
+0000000127 00000 n
+0000000186 00000 n
+0000000335 00000 n
+0000000471 00000 n
+0000000504 00000 n
+0000000535 00000 n
+0000000611 00000 n
+0000000711 00000 n
+0000000855 00000 n
+trailer<< /Root 1 0 R /Size 11 >>
startxref
-841
+1020
%%EOF