• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "fpdfsdk/cpdfsdk_annot.h"
6 #include "fpdfsdk/cpdfsdk_annotiterator.h"
7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
8 #include "fpdfsdk/cpdfsdk_helpers.h"
9 #include "fpdfsdk/formfiller/cffl_formfiller.h"
10 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
11 #include "fpdfsdk/pwl/cpwl_combo_box.h"
12 #include "fpdfsdk/pwl/cpwl_wnd.h"
13 #include "public/fpdf_fwlevent.h"
14 #include "testing/embedder_test.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 class CPWLComboBoxEditEmbedderTest : public EmbedderTest {
18  protected:
SetUp()19   void SetUp() override {
20     EmbedderTest::SetUp();
21     CreateAndInitializeFormComboboxPDF();
22   }
23 
TearDown()24   void TearDown() override {
25     UnloadPage(GetPage());
26     EmbedderTest::TearDown();
27   }
28 
CreateAndInitializeFormComboboxPDF()29   void CreateAndInitializeFormComboboxPDF() {
30     EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
31     m_page = LoadPage(0);
32     ASSERT_TRUE(m_page);
33 
34     m_pFormFillEnv =
35         CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
36     CPDFSDK_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
37                                CPDF_Annot::Subtype::WIDGET);
38 
39     // User editable combobox.
40     m_pAnnotEditable = iter.GetFirstAnnot();
41     ASSERT_TRUE(m_pAnnotEditable);
42     ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotEditable->GetAnnotSubtype());
43 
44     // Normal combobox with pre-selected value.
45     m_pAnnotNormal = iter.GetNextAnnot(m_pAnnotEditable);
46     ASSERT_TRUE(m_pAnnotNormal);
47     ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotNormal->GetAnnotSubtype());
48 
49     // Read-only combobox.
50     CPDFSDK_Annot* pAnnotReadOnly = iter.GetNextAnnot(m_pAnnotNormal);
51     CPDFSDK_Annot* pLastAnnot = iter.GetLastAnnot();
52     ASSERT_EQ(pAnnotReadOnly, pLastAnnot);
53   }
54 
FormFillerAndWindowSetup(CPDFSDK_Annot * pAnnotCombobox)55   void FormFillerAndWindowSetup(CPDFSDK_Annot* pAnnotCombobox) {
56     CFFL_InteractiveFormFiller* pInteractiveFormFiller =
57         m_pFormFillEnv->GetInteractiveFormFiller();
58     {
59       ObservedPtr<CPDFSDK_Annot> pObserved(pAnnotCombobox);
60       EXPECT_TRUE(pInteractiveFormFiller->OnSetFocus(&pObserved, 0));
61     }
62 
63     m_pFormFiller =
64         pInteractiveFormFiller->GetFormFillerForTesting(pAnnotCombobox);
65     ASSERT_TRUE(m_pFormFiller);
66 
67     CPWL_Wnd* pWindow =
68         m_pFormFiller->GetPWLWindow(m_pFormFillEnv->GetPageView(0), false);
69     ASSERT_TRUE(pWindow);
70     m_pComboBox = static_cast<CPWL_ComboBox*>(pWindow);
71   }
72 
TypeTextIntoTextField(int num_chars)73   void TypeTextIntoTextField(int num_chars) {
74     // Type text starting with 'A' to as many chars as specified by |num_chars|.
75     for (int i = 0; i < num_chars; ++i) {
76       EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(),
77                                               i + 'A', 0));
78     }
79   }
80 
GetPage() const81   FPDF_PAGE GetPage() const { return m_page; }
GetCPWLComboBox() const82   CPWL_ComboBox* GetCPWLComboBox() const { return m_pComboBox; }
GetCFFLFormFiller() const83   CFFL_FormFiller* GetCFFLFormFiller() const { return m_pFormFiller; }
GetCPDFSDKAnnotNormal() const84   CPDFSDK_Annot* GetCPDFSDKAnnotNormal() const { return m_pAnnotNormal; }
GetCPDFSDKAnnotUserEditable() const85   CPDFSDK_Annot* GetCPDFSDKAnnotUserEditable() const {
86     return m_pAnnotEditable;
87   }
GetCPDFSDKFormFillEnv() const88   CPDFSDK_FormFillEnvironment* GetCPDFSDKFormFillEnv() const {
89     return m_pFormFillEnv;
90   }
91 
92  private:
93   FPDF_PAGE m_page;
94   CPWL_ComboBox* m_pComboBox;
95   CFFL_FormFiller* m_pFormFiller;
96   CPDFSDK_Annot* m_pAnnotNormal;
97   CPDFSDK_Annot* m_pAnnotEditable;
98   CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
99 };
100 
TEST_F(CPWLComboBoxEditEmbedderTest,GetSelectedTextEmptyAndBasicNormal)101 TEST_F(CPWLComboBoxEditEmbedderTest, GetSelectedTextEmptyAndBasicNormal) {
102   FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
103 
104   // Automatically pre-filled with "Banana".
105   EXPECT_FALSE(GetCPWLComboBox()->GetText().IsEmpty());
106   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
107 
108   // Check that selection is intially empty, then select entire word.
109   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
110   GetCPWLComboBox()->SetSelectText();
111   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
112 
113   // Select other options.
114   GetCPWLComboBox()->SetSelect(0);
115   EXPECT_STREQ(L"Apple", GetCPWLComboBox()->GetSelectedText().c_str());
116   GetCPWLComboBox()->SetSelect(2);
117   EXPECT_STREQ(L"Cherry", GetCPWLComboBox()->GetSelectedText().c_str());
118 
119   // Verify that combobox text cannot be edited.
120   EXPECT_FALSE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotNormal(), 'a', 0));
121 }
122 
TEST_F(CPWLComboBoxEditEmbedderTest,GetSelectedTextFragmentsNormal)123 TEST_F(CPWLComboBoxEditEmbedderTest, GetSelectedTextFragmentsNormal) {
124   FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
125   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
126 
127   GetCPWLComboBox()->SetEditSelection(0, 0);
128   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
129 
130   GetCPWLComboBox()->SetEditSelection(0, 1);
131   EXPECT_STREQ(L"B", GetCPWLComboBox()->GetSelectedText().c_str());
132 
133   GetCPWLComboBox()->SetEditSelection(0, -1);
134   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
135 
136   GetCPWLComboBox()->SetEditSelection(-8, -1);
137   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
138 
139   GetCPWLComboBox()->SetEditSelection(4, 1);
140   EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
141 
142   GetCPWLComboBox()->SetEditSelection(1, 4);
143   EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
144 
145   GetCPWLComboBox()->SetEditSelection(5, 6);
146   EXPECT_STREQ(L"a", GetCPWLComboBox()->GetSelectedText().c_str());
147 }
148 
TEST_F(CPWLComboBoxEditEmbedderTest,GetSelectedTextEmptyAndBasicEditable)149 TEST_F(CPWLComboBoxEditEmbedderTest, GetSelectedTextEmptyAndBasicEditable) {
150   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
151   EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
152 
153   // Check selection is intially empty, then select a provided option.
154   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
155   GetCPWLComboBox()->SetSelect(0);
156   GetCPWLComboBox()->SetSelectText();
157   EXPECT_STREQ(L"Foo", GetCPWLComboBox()->GetSelectedText().c_str());
158 
159   // Select another option and then select last char of that option.
160   GetCPWLComboBox()->SetSelect(1);
161   EXPECT_STREQ(L"Bar", GetCPWLComboBox()->GetSelectedText().c_str());
162   GetCPWLComboBox()->SetEditSelection(2, 3);
163   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
164 
165   // Type into editable combobox text field and select new text.
166   EXPECT_TRUE(
167       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'a', 0));
168   EXPECT_TRUE(
169       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'b', 0));
170   EXPECT_TRUE(
171       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'c', 0));
172 
173   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
174   GetCPWLComboBox()->SetEditSelection(0, 5);
175   EXPECT_STREQ(L"Baabc", GetCPWLComboBox()->GetSelectedText().c_str());
176 }
177 
TEST_F(CPWLComboBoxEditEmbedderTest,GetSelectedTextFragmentsEditable)178 TEST_F(CPWLComboBoxEditEmbedderTest, GetSelectedTextFragmentsEditable) {
179   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
180   TypeTextIntoTextField(50);
181 
182   GetCPWLComboBox()->SetEditSelection(0, 0);
183   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
184 
185   GetCPWLComboBox()->SetEditSelection(0, 1);
186   EXPECT_STREQ(L"A", GetCPWLComboBox()->GetSelectedText().c_str());
187 
188   GetCPWLComboBox()->SetEditSelection(0, -1);
189   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
190                GetCPWLComboBox()->GetSelectedText().c_str());
191 
192   GetCPWLComboBox()->SetEditSelection(-8, -1);
193   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
194 
195   GetCPWLComboBox()->SetEditSelection(23, 12);
196   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
197 
198   GetCPWLComboBox()->SetEditSelection(12, 23);
199   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
200 
201   GetCPWLComboBox()->SetEditSelection(49, 50);
202   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
203 
204   GetCPWLComboBox()->SetEditSelection(49, 55);
205   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
206 }
207 
TEST_F(CPWLComboBoxEditEmbedderTest,DeleteEntireTextSelection)208 TEST_F(CPWLComboBoxEditEmbedderTest, DeleteEntireTextSelection) {
209   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
210   TypeTextIntoTextField(50);
211 
212   GetCPWLComboBox()->SetEditSelection(0, -1);
213   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
214                GetCPWLComboBox()->GetSelectedText().c_str());
215 
216   GetCPWLComboBox()->ReplaceSelection(L"");
217   EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
218 }
219 
TEST_F(CPWLComboBoxEditEmbedderTest,DeleteTextSelectionMiddle)220 TEST_F(CPWLComboBoxEditEmbedderTest, DeleteTextSelectionMiddle) {
221   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
222   TypeTextIntoTextField(50);
223 
224   GetCPWLComboBox()->SetEditSelection(12, 23);
225   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
226 
227   GetCPWLComboBox()->ReplaceSelection(L"");
228   EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
229                GetCPWLComboBox()->GetText().c_str());
230 }
231 
TEST_F(CPWLComboBoxEditEmbedderTest,DeleteTextSelectionLeft)232 TEST_F(CPWLComboBoxEditEmbedderTest, DeleteTextSelectionLeft) {
233   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
234   TypeTextIntoTextField(50);
235 
236   GetCPWLComboBox()->SetEditSelection(0, 5);
237   EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
238 
239   GetCPWLComboBox()->ReplaceSelection(L"");
240   EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
241                GetCPWLComboBox()->GetText().c_str());
242 }
243 
TEST_F(CPWLComboBoxEditEmbedderTest,DeleteTextSelectionRight)244 TEST_F(CPWLComboBoxEditEmbedderTest, DeleteTextSelectionRight) {
245   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
246   TypeTextIntoTextField(50);
247 
248   GetCPWLComboBox()->SetEditSelection(45, 50);
249   EXPECT_STREQ(L"nopqr", GetCPWLComboBox()->GetSelectedText().c_str());
250 
251   GetCPWLComboBox()->ReplaceSelection(L"");
252   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
253                GetCPWLComboBox()->GetText().c_str());
254 }
255 
TEST_F(CPWLComboBoxEditEmbedderTest,DeleteEmptyTextSelection)256 TEST_F(CPWLComboBoxEditEmbedderTest, DeleteEmptyTextSelection) {
257   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
258   TypeTextIntoTextField(50);
259 
260   GetCPWLComboBox()->ReplaceSelection(L"");
261   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
262                GetCPWLComboBox()->GetText().c_str());
263 }
264 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextInEmptyEditableComboBox)265 TEST_F(CPWLComboBoxEditEmbedderTest, InsertTextInEmptyEditableComboBox) {
266   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
267   GetCPWLComboBox()->ReplaceSelection(L"Hello");
268   EXPECT_STREQ(L"Hello", GetCPWLComboBox()->GetText().c_str());
269 }
270 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextInPopulatedEditableComboBoxLeft)271 TEST_F(CPWLComboBoxEditEmbedderTest,
272        InsertTextInPopulatedEditableComboBoxLeft) {
273   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
274   TypeTextIntoTextField(10);
275 
276   // Move cursor to beginning of user-editable combobox text field.
277   EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(FWL_VKEY_Home, 0));
278 
279   GetCPWLComboBox()->ReplaceSelection(L"Hello");
280   EXPECT_STREQ(L"HelloABCDEFGHIJ", GetCPWLComboBox()->GetText().c_str());
281 }
282 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextInPopulatedEditableComboBoxMiddle)283 TEST_F(CPWLComboBoxEditEmbedderTest,
284        InsertTextInPopulatedEditableComboBoxMiddle) {
285   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
286   TypeTextIntoTextField(10);
287 
288   // Move cursor to middle of user-editable combobox text field.
289   for (int i = 0; i < 5; ++i) {
290     EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(FWL_VKEY_Left, 0));
291   }
292 
293   GetCPWLComboBox()->ReplaceSelection(L"Hello");
294   EXPECT_STREQ(L"ABCDEHelloFGHIJ", GetCPWLComboBox()->GetText().c_str());
295 }
296 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextInPopulatedEditableComboBoxRight)297 TEST_F(CPWLComboBoxEditEmbedderTest,
298        InsertTextInPopulatedEditableComboBoxRight) {
299   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
300   TypeTextIntoTextField(10);
301 
302   GetCPWLComboBox()->ReplaceSelection(L"Hello");
303   EXPECT_STREQ(L"ABCDEFGHIJHello", GetCPWLComboBox()->GetText().c_str());
304 }
305 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole)306 TEST_F(CPWLComboBoxEditEmbedderTest,
307        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
308   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
309   TypeTextIntoTextField(10);
310 
311   GetCPWLComboBox()->SetEditSelection(0, -1);
312   EXPECT_STREQ(L"ABCDEFGHIJ", GetCPWLComboBox()->GetSelectedText().c_str());
313   GetCPWLComboBox()->ReplaceSelection(L"Hello");
314   EXPECT_STREQ(L"Hello", GetCPWLComboBox()->GetText().c_str());
315 }
316 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft)317 TEST_F(CPWLComboBoxEditEmbedderTest,
318        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
319   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
320   TypeTextIntoTextField(10);
321 
322   GetCPWLComboBox()->SetEditSelection(0, 5);
323   EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
324   GetCPWLComboBox()->ReplaceSelection(L"Hello");
325   EXPECT_STREQ(L"HelloFGHIJ", GetCPWLComboBox()->GetText().c_str());
326 }
327 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle)328 TEST_F(CPWLComboBoxEditEmbedderTest,
329        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
330   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
331   TypeTextIntoTextField(10);
332 
333   GetCPWLComboBox()->SetEditSelection(2, 7);
334   EXPECT_STREQ(L"CDEFG", GetCPWLComboBox()->GetSelectedText().c_str());
335   GetCPWLComboBox()->ReplaceSelection(L"Hello");
336   EXPECT_STREQ(L"ABHelloHIJ", GetCPWLComboBox()->GetText().c_str());
337 }
338 
TEST_F(CPWLComboBoxEditEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight)339 TEST_F(CPWLComboBoxEditEmbedderTest,
340        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
341   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
342   TypeTextIntoTextField(10);
343 
344   GetCPWLComboBox()->SetEditSelection(5, 10);
345   EXPECT_STREQ(L"FGHIJ", GetCPWLComboBox()->GetSelectedText().c_str());
346   GetCPWLComboBox()->ReplaceSelection(L"Hello");
347   EXPECT_STREQ(L"ABCDEHello", GetCPWLComboBox()->GetText().c_str());
348 }
349