summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.cpp4
-rw-r--r--fpdfsdk/cpdfsdk_annothandlermgr.h1
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.cpp2
-rw-r--r--fpdfsdk/cpdfsdk_baannothandler.h1
-rw-r--r--fpdfsdk/cpdfsdk_pageview.cpp8
-rw-r--r--fpdfsdk/cpdfsdk_pageview.h1
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.cpp5
-rw-r--r--fpdfsdk/cpdfsdk_widgethandler.h1
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.cpp6
-rw-r--r--fpdfsdk/cpdfsdk_xfawidgethandler.h1
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.cpp14
-rw-r--r--fpdfsdk/formfiller/cffl_formfiller.h1
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.cpp9
-rw-r--r--fpdfsdk/formfiller/cffl_interactiveformfiller.h1
-rw-r--r--fpdfsdk/fpdfformfill.cpp8
-rw-r--r--fpdfsdk/fpdfformfill_embeddertest.cpp224
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c1
-rw-r--r--fpdfsdk/ipdfsdk_annothandler.h1
-rw-r--r--fpdfsdk/pdfwindow/cpwl_combo_box.cpp5
-rw-r--r--fpdfsdk/pdfwindow/cpwl_combo_box.h1
-rw-r--r--fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp72
-rw-r--r--fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp5
-rw-r--r--fpdfsdk/pdfwindow/cpwl_edit_ctrl.h1
-rw-r--r--fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp62
-rw-r--r--fpdfsdk/pdfwindow/cpwl_wnd.cpp2
-rw-r--r--fpdfsdk/pdfwindow/cpwl_wnd.h1
-rw-r--r--public/fpdf_formfill.h16
27 files changed, 440 insertions, 14 deletions
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index 9e649f6dc6..fd77a73460 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -81,6 +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);
+}
+
IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
CPDFSDK_Annot* pAnnot) const {
return GetAnnotHandler(pAnnot->GetAnnotSubtype());
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h
index ff2556f9dc..93c552bbfb 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.h
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.h
@@ -44,6 +44,7 @@ class CPDFSDK_AnnotHandlerMgr {
void Annot_OnLoad(CPDFSDK_Annot* pAnnot);
CFX_WideString Annot_GetSelectedText(CPDFSDK_Annot* pAnnot);
+ void Annot_DeleteSelectedText(CPDFSDK_Annot* pAnnot);
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 4984ee93cc..cf09d2bbcb 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.cpp
+++ b/fpdfsdk/cpdfsdk_baannothandler.cpp
@@ -197,6 +197,8 @@ CFX_WideString CPDFSDK_BAAnnotHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return CFX_WideString();
}
+void CPDFSDK_BAAnnotHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {}
+
bool CPDFSDK_BAAnnotHandler::HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) {
diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h
index 2af2f3ee99..7db9a4d7d7 100644
--- a/fpdfsdk/cpdfsdk_baannothandler.h
+++ b/fpdfsdk/cpdfsdk_baannothandler.h
@@ -38,6 +38,7 @@ 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;
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 06761a5806..84a60fa42f 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -253,6 +253,14 @@ CFX_WideString CPDFSDK_PageView::GetSelectedText() {
return CFX_WideString();
}
+void CPDFSDK_PageView::DeleteSelectedText() {
+ if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+ m_pFormFillEnv->GetAnnotHandlerMgr();
+ pAnnotHandlerMgr->Annot_DeleteSelectedText(pAnnot);
+ }
+}
+
bool CPDFSDK_PageView::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point));
if (!pAnnot) {
diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h
index 9eebb6e424..d4b7721575 100644
--- a/fpdfsdk/cpdfsdk_pageview.h
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -61,6 +61,7 @@ class CPDFSDK_PageView final : public CPDF_Page::View {
}
CFX_WideString GetSelectedText();
+ void DeleteSelectedText();
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 d916567bdd..1c802a3ba7 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -287,6 +287,11 @@ CFX_WideString CPDFSDK_WidgetHandler::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return CFX_WideString();
}
+void CPDFSDK_WidgetHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+ if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
+ m_pFormFiller->DeleteSelectedText(pAnnot);
+}
+
bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) {
diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h
index aac3619a44..2d33ff5686 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.h
+++ b/fpdfsdk/cpdfsdk_widgethandler.h
@@ -39,6 +39,7 @@ 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;
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 aa4c0f170a..746d1ca763 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
@@ -97,11 +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
+// 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
+// fields.
+void CPDFSDK_XFAWidgetHandler::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {}
+
bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) {
diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.h b/fpdfsdk/cpdfsdk_xfawidgethandler.h
index 65e5e452d2..3d06948116 100644
--- a/fpdfsdk/cpdfsdk_xfawidgethandler.h
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h
@@ -34,6 +34,7 @@ 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;
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 edbd671f29..a37a7501d0 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -245,6 +245,20 @@ CFX_WideString CFFL_FormFiller::GetSelectedText(CPDFSDK_Annot* pAnnot) {
return pWnd ? pWnd->GetSelectedText() : CFX_WideString();
}
+void CFFL_FormFiller::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+ if (!IsValid())
+ return;
+
+ CPDFSDK_PageView* pPageView = GetCurPageView(true);
+ ASSERT(pPageView);
+
+ CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
+ if (!pWnd)
+ return;
+
+ pWnd->DeleteSelectedText();
+}
+
void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
index 3eedebea47..96b7a69b29 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -75,6 +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 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 8a81f4c40d..24bfd3c3b2 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -523,6 +523,15 @@ CFX_WideString CFFL_InteractiveFormFiller::GetSelectedText(
return pFormFiller ? pFormFiller->GetSelectedText(pAnnot) : CFX_WideString();
}
+void CFFL_InteractiveFormFiller::DeleteSelectedText(CPDFSDK_Annot* pAnnot) {
+ ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+ CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false);
+ if (!pFormFiller)
+ return;
+
+ pFormFiller->DeleteSelectedText(pAnnot);
+}
+
void CFFL_InteractiveFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
auto it = m_Maps.find(pAnnot);
if (it == m_Maps.end())
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
index fb141e17a4..744d522fbc 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
@@ -84,6 +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);
static bool IsVisible(CPDFSDK_Widget* pWidget);
static bool IsReadOnly(CPDFSDK_Widget* pWidget);
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
index 24cd64efa1..627bd0a925 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -383,6 +383,14 @@ DLLEXPORT unsigned long STDCALL FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
return form_text_len;
}
+DLLEXPORT void STDCALL FORM_DeleteSelectedText(FPDF_FORMHANDLE hHandle,
+ FPDF_PAGE page) {
+ CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+ if (!pPageView)
+ return;
+ pPageView->DeleteSelectedText();
+}
+
DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
CPDFSDK_FormFillEnvironment* pFormFillEnv =
HandleToCPDFSDKEnvironment(hHandle);
diff --git a/fpdfsdk/fpdfformfill_embeddertest.cpp b/fpdfsdk/fpdfformfill_embeddertest.cpp
index 70899276b3..d0fd6de94d 100644
--- a/fpdfsdk/fpdfformfill_embeddertest.cpp
+++ b/fpdfsdk/fpdfformfill_embeddertest.cpp
@@ -22,7 +22,7 @@ using testing::Return;
class FPDFFormFillEmbeddertest : public EmbedderTest {
protected:
- void TypeTextIntoTextfield(FPDF_PAGE page,
+ void TypeTextIntoTextField(FPDF_PAGE page,
int num_chars,
int form_type,
double x,
@@ -380,10 +380,10 @@ TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicKeyboard) {
ASSERT_TRUE(page);
// Test empty selection.
- CheckSelection(page, CFX_WideString(L""));
+ CheckSelection(page, CFX_WideString());
// Test basic selection.
- TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ TypeTextIntoTextField(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
SelectTextWithKeyboard(page, 3, FWL_VKEY_Left, 123.0, 115.5);
CheckSelection(page, CFX_WideString(L"ABC"));
@@ -397,10 +397,10 @@ TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicMouse) {
ASSERT_TRUE(page);
// Test empty selection.
- CheckSelection(page, CFX_WideString(L""));
+ CheckSelection(page, CFX_WideString());
// Test basic selection.
- TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ TypeTextIntoTextField(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
SelectTextWithMouse(page, 125.0, 102.0, 115.5);
CheckSelection(page, CFX_WideString(L"ABC"));
@@ -413,7 +413,7 @@ TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextFragmentsKeyBoard) {
FPDF_PAGE page = LoadPage(0);
ASSERT_TRUE(page);
- TypeTextIntoTextfield(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
// Test selecting first character in forward direction.
SelectTextWithKeyboard(page, 1, FWL_VKEY_Right, 102.0, 115.5);
@@ -444,7 +444,7 @@ TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextFragmentsMouse) {
FPDF_PAGE page = LoadPage(0);
ASSERT_TRUE(page);
- TypeTextIntoTextfield(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
// Test selecting first character in forward direction.
SelectTextWithMouse(page, 102.0, 106.0, 115.5);
@@ -476,7 +476,7 @@ TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicNormalComboBox) {
ASSERT_TRUE(page);
// Test empty selection.
- CheckSelection(page, CFX_WideString(L""));
+ CheckSelection(page, CFX_WideString());
// Test basic selection of text within normal, non-editable combobox.
// Click on normal combobox text field.
@@ -502,10 +502,10 @@ TEST_F(FPDFFormFillEmbeddertest,
ASSERT_TRUE(page);
// Test empty selection.
- CheckSelection(page, CFX_WideString(L""));
+ CheckSelection(page, CFX_WideString());
// Test basic selection of text within user editable combobox using keyboard.
- TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ TypeTextIntoTextField(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
SelectTextWithKeyboard(page, 3, FWL_VKEY_Left, 128.0, 63.0);
CheckSelection(page, CFX_WideString(L"ABC"));
@@ -524,10 +524,10 @@ TEST_F(FPDFFormFillEmbeddertest,
ASSERT_TRUE(page);
// Test empty selection.
- CheckSelection(page, CFX_WideString(L""));
+ CheckSelection(page, CFX_WideString());
// Test basic selection of text within user editable combobox using mouse.
- TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ TypeTextIntoTextField(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
SelectTextWithMouse(page, 128.0, 103.0, 63.0);
CheckSelection(page, CFX_WideString(L"ABC"));
@@ -584,7 +584,7 @@ TEST_F(FPDFFormFillEmbeddertest,
FPDF_PAGE page = LoadPage(0);
ASSERT_TRUE(page);
- TypeTextIntoTextfield(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
// Test selecting first character in forward direction.
SelectTextWithKeyboard(page, 1, FWL_VKEY_Right, 102.0, 63.0);
@@ -622,7 +622,7 @@ TEST_F(FPDFFormFillEmbeddertest,
FPDF_PAGE page = LoadPage(0);
ASSERT_TRUE(page);
- TypeTextIntoTextfield(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
// Test selecting first character in forward direction.
SelectTextWithMouse(page, 102.0, 107.0, 63.0);
@@ -646,3 +646,199 @@ TEST_F(FPDFFormFillEmbeddertest,
UnloadPage(page);
}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldEntireSelection) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select entire contents of text field.
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ SelectTextWithMouse(page, 191.0, 102.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
+ CheckSelection(page, CFX_WideString());
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionMiddle) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select middle section of text.
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ SelectTextWithMouse(page, 170.0, 125.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"DEFGHI"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCJKL"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionLeft) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select first few characters of text.
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ SelectTextWithMouse(page, 102.0, 132.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCD"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"EFGHIJKL"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteTextFieldSelectionRight) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select last few characters of text.
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ SelectTextWithMouse(page, 191.0, 165.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"IJKL"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGH"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEmptyTextFieldSelection) {
+ // Open file with form text field.
+ EXPECT_TRUE(OpenDocument("text_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Do not select text.
+ TypeTextIntoTextField(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
+ CheckSelection(page, CFX_WideString());
+
+ // Test that attempt to delete empty text selection has no effect.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxEntireSelection) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select entire contents of user-editable combobox text field.
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString());
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionMiddle) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select middle section of text.
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ SelectTextWithMouse(page, 168.0, 127.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"ABCIJ"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionLeft) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select first few characters of text.
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ SelectTextWithMouse(page, 102.0, 132.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"ABCD"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"EFGHIJ"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEditableComboBoxSelectionRight) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Select last few characters of text.
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ SelectTextWithMouse(page, 178.0, 152.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"GHIJ"));
+
+ // Test deleting current text selection. Select what remains after deletion to
+ // check that remaining text is as expected.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEF"));
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, DeleteEmptyEditableComboBoxSelection) {
+ // Open file with form comboboxes.
+ EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Do not select text.
+ TypeTextIntoTextField(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+ CheckSelection(page, CFX_WideString());
+
+ // Test that attempt to delete empty text selection has no effect.
+ FORM_DeleteSelectedText(form_handle(), page);
+ SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+ CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
+
+ UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index 546ae47512..97bacbba54 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -179,6 +179,7 @@ int CheckPDFiumCApi() {
CHK(FORM_OnKeyUp);
CHK(FORM_OnChar);
CHK(FORM_GetSelectedText);
+ CHK(FORM_DeleteSelectedText);
CHK(FORM_ForceToKillFocus);
CHK(FPDFPage_HasFormFieldAtPoint);
CHK(FPDFPage_FormFieldZOrderAtPoint);
diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h
index 08008eb996..5340978308 100644
--- a/fpdfsdk/ipdfsdk_annothandler.h
+++ b/fpdfsdk/ipdfsdk_annothandler.h
@@ -37,6 +37,7 @@ 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 bool HitTest(CPDFSDK_PageView* pPageView,
CPDFSDK_Annot* pAnnot,
const CFX_PointF& point) = 0;
diff --git a/fpdfsdk/pdfwindow/cpwl_combo_box.cpp b/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
index 8de2f1e733..90c8cc6dc0 100644
--- a/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_combo_box.cpp
@@ -184,6 +184,11 @@ CFX_WideString CPWL_ComboBox::GetSelectedText() {
return CFX_WideString();
}
+void CPWL_ComboBox::DeleteSelectedText() {
+ if (m_pEdit)
+ m_pEdit->DeleteSelectedText();
+}
+
CFX_WideString CPWL_ComboBox::GetText() const {
if (m_pEdit) {
return m_pEdit->GetText();
diff --git a/fpdfsdk/pdfwindow/cpwl_combo_box.h b/fpdfsdk/pdfwindow/cpwl_combo_box.h
index 12c0fe9878..530ff0a07e 100644
--- a/fpdfsdk/pdfwindow/cpwl_combo_box.h
+++ b/fpdfsdk/pdfwindow/cpwl_combo_box.h
@@ -63,6 +63,7 @@ class CPWL_ComboBox : public CPWL_Wnd {
void SetFocus() override;
void KillFocus() override;
CFX_WideString GetSelectedText() override;
+ void DeleteSelectedText() override;
void SetFillerNotify(IPWL_Filler_Notify* pNotify);
diff --git a/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp b/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp
index 9ca994f2e1..3224284ee2 100644
--- a/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp
@@ -194,3 +194,75 @@ TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextFragmentsEditable) {
GetCPWLComboBox()->SetEditSelection(49, 50);
EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEntireTextSelection) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+ }
+
+ GetCPWLComboBox()->SetEditSelection(0, -1);
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLComboBox()->GetSelectedText().c_str());
+
+ GetCPWLComboBox()->DeleteSelectedText();
+ EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionMiddle) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+ }
+
+ GetCPWLComboBox()->SetEditSelection(12, 23);
+ EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
+
+ GetCPWLComboBox()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionLeft) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+ }
+
+ GetCPWLComboBox()->SetEditSelection(0, 5);
+ EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
+
+ GetCPWLComboBox()->DeleteSelectedText();
+ EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionRight) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+ }
+
+ GetCPWLComboBox()->SetEditSelection(45, 50);
+ EXPECT_STREQ(L"nopqr", GetCPWLComboBox()->GetSelectedText().c_str());
+
+ GetCPWLComboBox()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
+ GetCPWLComboBox()->GetText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEmptyTextSelection) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(
+ GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+ }
+
+ GetCPWLComboBox()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLComboBox()->GetText().c_str());
+}
diff --git a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
index c7e1f14499..a3aac19e20 100644
--- a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp
@@ -59,6 +59,11 @@ CFX_WideString CPWL_EditCtrl::GetSelectedText() {
return CFX_WideString();
}
+void CPWL_EditCtrl::DeleteSelectedText() {
+ if (m_pEdit)
+ m_pEdit->ClearSelection();
+}
+
void CPWL_EditCtrl::RePosChildWnd() {
m_pEdit->SetPlateRect(GetClientRect());
}
diff --git a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
index ef6989e637..30c2d63419 100644
--- a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
+++ b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h
@@ -61,6 +61,7 @@ class CPWL_EditCtrl : public CPWL_Wnd {
float GetFontSize() const override;
void SetCursor() override;
CFX_WideString GetSelectedText() override;
+ void DeleteSelectedText() override;
void SetCaret(bool bVisible,
const CFX_PointF& ptHead,
diff --git a/fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp b/fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp
index 9b15ad887d..2b1bbd4445 100644
--- a/fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp
@@ -123,3 +123,65 @@ TEST_F(CPWLEditEmbeddertest, GetSelectedTextFragments) {
GetCPWLEdit()->SetSelection(49, 50);
EXPECT_STREQ(L"r", GetCPWLEdit()->GetSelectedText().c_str());
}
+
+TEST_F(CPWLEditEmbeddertest, DeleteEntireTextSelection) {
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), i + 'A', 0));
+ }
+
+ GetCPWLEdit()->SetSelection(0, -1);
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLEdit()->GetSelectedText().c_str());
+
+ GetCPWLEdit()->DeleteSelectedText();
+ EXPECT_TRUE(GetCPWLEdit()->GetText().IsEmpty());
+}
+
+TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionMiddle) {
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), i + 'A', 0));
+ }
+
+ GetCPWLEdit()->SetSelection(12, 23);
+ EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLEdit()->GetSelectedText().c_str());
+
+ GetCPWLEdit()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionLeft) {
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), i + 'A', 0));
+ }
+
+ GetCPWLEdit()->SetSelection(0, 5);
+ EXPECT_STREQ(L"ABCDE", GetCPWLEdit()->GetSelectedText().c_str());
+
+ GetCPWLEdit()->DeleteSelectedText();
+ EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, DeleteTextSelectionRight) {
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), i + 'A', 0));
+ }
+
+ GetCPWLEdit()->SetSelection(45, 50);
+ EXPECT_STREQ(L"nopqr", GetCPWLEdit()->GetSelectedText().c_str());
+
+ GetCPWLEdit()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
+ GetCPWLEdit()->GetText().c_str());
+}
+
+TEST_F(CPWLEditEmbeddertest, DeleteEmptyTextSelection) {
+ for (int i = 0; i < 50; ++i) {
+ EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnot(), i + 'A', 0));
+ }
+
+ GetCPWLEdit()->DeleteSelectedText();
+ EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+ GetCPWLEdit()->GetText().c_str());
+}
diff --git a/fpdfsdk/pdfwindow/cpwl_wnd.cpp b/fpdfsdk/pdfwindow/cpwl_wnd.cpp
index 663a763e3c..58824afdbd 100644
--- a/fpdfsdk/pdfwindow/cpwl_wnd.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_wnd.cpp
@@ -369,6 +369,8 @@ CFX_WideString CPWL_Wnd::GetSelectedText() {
return CFX_WideString();
}
+void CPWL_Wnd::DeleteSelectedText() {}
+
bool CPWL_Wnd::OnMouseWheel(short zDelta,
const CFX_PointF& point,
uint32_t nFlag) {
diff --git a/fpdfsdk/pdfwindow/cpwl_wnd.h b/fpdfsdk/pdfwindow/cpwl_wnd.h
index b22c5dba21..d56369cb52 100644
--- a/fpdfsdk/pdfwindow/cpwl_wnd.h
+++ b/fpdfsdk/pdfwindow/cpwl_wnd.h
@@ -202,6 +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 CFX_FloatRect GetFocusRect() const;
virtual CFX_FloatRect GetClientRect() const;
diff --git a/public/fpdf_formfill.h b/public/fpdf_formfill.h
index 5a15cd9a02..83a4e58bdc 100644
--- a/public/fpdf_formfill.h
+++ b/public/fpdf_formfill.h
@@ -1378,6 +1378,22 @@ 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.
+ * Parameters:
+ * hHandle - Handle to the form fill module. Returned by
+ * FPDFDOC_InitFormFillEnvironment.
+ * page - Handle to the page. Returned by FPDF_LoadPage
+ * function.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FORM_DeleteSelectedText(FPDF_FORMHANDLE hHandle,
+ FPDF_PAGE page);
+
+/**
* Function: FORM_ForceToKillFocus.
* You can call this member function to force to kill the focus of the
*form field which got focus.