• 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/cba_annotiterator.h"
6 #include "fpdfsdk/cpdfsdk_annot.h"
7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
8 #include "fpdfsdk/formfiller/cffl_formfiller.h"
9 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
10 #include "fpdfsdk/pwl/cpwl_combo_box.h"
11 #include "fpdfsdk/pwl/cpwl_wnd.h"
12 #include "testing/embedder_test.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 class CPWLComboBoxEditEmbeddertest : public EmbedderTest {
16  protected:
SetUp()17   void SetUp() override {
18     EmbedderTest::SetUp();
19     CreateAndInitializeFormComboboxPDF();
20   }
21 
TearDown()22   void TearDown() override {
23     UnloadPage(GetPage());
24     EmbedderTest::TearDown();
25   }
26 
CreateAndInitializeFormComboboxPDF()27   void CreateAndInitializeFormComboboxPDF() {
28     EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
29     m_page = LoadPage(0);
30     ASSERT_TRUE(m_page);
31 
32     m_pFormFillEnv = static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
33     CBA_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
34                            CPDF_Annot::Subtype::WIDGET);
35 
36     // User editable combobox.
37     m_pAnnotEditable = iter.GetFirstAnnot();
38     ASSERT_TRUE(m_pAnnotEditable);
39     ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotEditable->GetAnnotSubtype());
40 
41     // Normal combobox with pre-selected value.
42     m_pAnnotNormal = iter.GetNextAnnot(m_pAnnotEditable);
43     ASSERT_TRUE(m_pAnnotNormal);
44     ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotNormal->GetAnnotSubtype());
45 
46     // Read-only combobox.
47     CPDFSDK_Annot* pAnnotReadOnly = iter.GetNextAnnot(m_pAnnotNormal);
48     CPDFSDK_Annot* pLastAnnot = iter.GetLastAnnot();
49     ASSERT_EQ(pAnnotReadOnly, pLastAnnot);
50   }
51 
FormFillerAndWindowSetup(CPDFSDK_Annot * pAnnotCombobox)52   void FormFillerAndWindowSetup(CPDFSDK_Annot* pAnnotCombobox) {
53     CFFL_InteractiveFormFiller* pInteractiveFormFiller =
54         m_pFormFillEnv->GetInteractiveFormFiller();
55     {
56       CPDFSDK_Annot::ObservedPtr pObserved(pAnnotCombobox);
57       EXPECT_TRUE(pInteractiveFormFiller->OnSetFocus(&pObserved, 0));
58     }
59 
60     m_pFormFiller =
61         pInteractiveFormFiller->GetFormFiller(pAnnotCombobox, false);
62     ASSERT_TRUE(m_pFormFiller);
63 
64     CPWL_Wnd* pWindow =
65         m_pFormFiller->GetPDFWindow(m_pFormFillEnv->GetPageView(0), false);
66     ASSERT_TRUE(pWindow);
67     ASSERT_EQ("CPWL_ComboBox", pWindow->GetClassName());
68     m_pComboBox = static_cast<CPWL_ComboBox*>(pWindow);
69   }
70 
TypeTextIntoTextField(int num_chars)71   void TypeTextIntoTextField(int num_chars) {
72     // Type text starting with 'A' to as many chars as specified by |num_chars|.
73     for (int i = 0; i < num_chars; ++i) {
74       EXPECT_TRUE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(),
75                                               i + 'A', 0));
76     }
77   }
78 
GetPage() const79   FPDF_PAGE GetPage() const { return m_page; }
GetCPWLComboBox() const80   CPWL_ComboBox* GetCPWLComboBox() const { return m_pComboBox; }
GetCFFLFormFiller() const81   CFFL_FormFiller* GetCFFLFormFiller() const { return m_pFormFiller; }
GetCPDFSDKAnnotNormal() const82   CPDFSDK_Annot* GetCPDFSDKAnnotNormal() const { return m_pAnnotNormal; }
GetCPDFSDKAnnotUserEditable() const83   CPDFSDK_Annot* GetCPDFSDKAnnotUserEditable() const {
84     return m_pAnnotEditable;
85   }
GetCPDFSDKFormFillEnv() const86   CPDFSDK_FormFillEnvironment* GetCPDFSDKFormFillEnv() const {
87     return m_pFormFillEnv;
88   }
89 
90  private:
91   FPDF_PAGE m_page;
92   CPWL_ComboBox* m_pComboBox;
93   CFFL_FormFiller* m_pFormFiller;
94   CPDFSDK_Annot* m_pAnnotNormal;
95   CPDFSDK_Annot* m_pAnnotEditable;
96   CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
97 };
98 
TEST_F(CPWLComboBoxEditEmbeddertest,GetSelectedTextEmptyAndBasicNormal)99 TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextEmptyAndBasicNormal) {
100   FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
101 
102   // Automatically pre-filled with "Banana".
103   EXPECT_FALSE(GetCPWLComboBox()->GetText().IsEmpty());
104   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
105 
106   // Check that selection is intially empty, then select entire word.
107   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
108   GetCPWLComboBox()->SetSelectText();
109   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
110 
111   // Select other options.
112   GetCPWLComboBox()->SetSelect(0);
113   EXPECT_STREQ(L"Apple", GetCPWLComboBox()->GetSelectedText().c_str());
114   GetCPWLComboBox()->SetSelect(2);
115   EXPECT_STREQ(L"Cherry", GetCPWLComboBox()->GetSelectedText().c_str());
116 
117   // Verify that combobox text cannot be edited.
118   EXPECT_FALSE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotNormal(), 'a', 0));
119 }
120 
TEST_F(CPWLComboBoxEditEmbeddertest,GetSelectedTextFragmentsNormal)121 TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextFragmentsNormal) {
122   FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
123   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
124 
125   GetCPWLComboBox()->SetEditSelection(0, 0);
126   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
127 
128   GetCPWLComboBox()->SetEditSelection(0, 1);
129   EXPECT_STREQ(L"B", GetCPWLComboBox()->GetSelectedText().c_str());
130 
131   GetCPWLComboBox()->SetEditSelection(0, -1);
132   EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
133 
134   GetCPWLComboBox()->SetEditSelection(-8, -1);
135   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
136 
137   GetCPWLComboBox()->SetEditSelection(4, 1);
138   EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
139 
140   GetCPWLComboBox()->SetEditSelection(1, 4);
141   EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
142 
143   GetCPWLComboBox()->SetEditSelection(5, 6);
144   EXPECT_STREQ(L"a", GetCPWLComboBox()->GetSelectedText().c_str());
145 }
146 
TEST_F(CPWLComboBoxEditEmbeddertest,GetSelectedTextEmptyAndBasicEditable)147 TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextEmptyAndBasicEditable) {
148   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
149   EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
150 
151   // Check selection is intially empty, then select a provided option.
152   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
153   GetCPWLComboBox()->SetSelect(0);
154   GetCPWLComboBox()->SetSelectText();
155   EXPECT_STREQ(L"Foo", GetCPWLComboBox()->GetSelectedText().c_str());
156 
157   // Select another option and then select last char of that option.
158   GetCPWLComboBox()->SetSelect(1);
159   EXPECT_STREQ(L"Bar", GetCPWLComboBox()->GetSelectedText().c_str());
160   GetCPWLComboBox()->SetEditSelection(2, 3);
161   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
162 
163   // Type into editable combobox text field and select new text.
164   EXPECT_TRUE(
165       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'a', 0));
166   EXPECT_TRUE(
167       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'b', 0));
168   EXPECT_TRUE(
169       GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'c', 0));
170 
171   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
172   GetCPWLComboBox()->SetEditSelection(0, 5);
173   EXPECT_STREQ(L"Baabc", GetCPWLComboBox()->GetSelectedText().c_str());
174 }
175 
TEST_F(CPWLComboBoxEditEmbeddertest,GetSelectedTextFragmentsEditable)176 TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextFragmentsEditable) {
177   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
178   TypeTextIntoTextField(50);
179 
180   GetCPWLComboBox()->SetEditSelection(0, 0);
181   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
182 
183   GetCPWLComboBox()->SetEditSelection(0, 1);
184   EXPECT_STREQ(L"A", GetCPWLComboBox()->GetSelectedText().c_str());
185 
186   GetCPWLComboBox()->SetEditSelection(0, -1);
187   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
188                GetCPWLComboBox()->GetSelectedText().c_str());
189 
190   GetCPWLComboBox()->SetEditSelection(-8, -1);
191   EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
192 
193   GetCPWLComboBox()->SetEditSelection(23, 12);
194   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
195 
196   GetCPWLComboBox()->SetEditSelection(12, 23);
197   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
198 
199   GetCPWLComboBox()->SetEditSelection(49, 50);
200   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
201 
202   GetCPWLComboBox()->SetEditSelection(49, 55);
203   EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
204 }
205 
TEST_F(CPWLComboBoxEditEmbeddertest,DeleteEntireTextSelection)206 TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEntireTextSelection) {
207   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
208   TypeTextIntoTextField(50);
209 
210   GetCPWLComboBox()->SetEditSelection(0, -1);
211   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
212                GetCPWLComboBox()->GetSelectedText().c_str());
213 
214   GetCPWLComboBox()->ReplaceSelection(L"");
215   EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
216 }
217 
TEST_F(CPWLComboBoxEditEmbeddertest,DeleteTextSelectionMiddle)218 TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionMiddle) {
219   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
220   TypeTextIntoTextField(50);
221 
222   GetCPWLComboBox()->SetEditSelection(12, 23);
223   EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
224 
225   GetCPWLComboBox()->ReplaceSelection(L"");
226   EXPECT_STREQ(L"ABCDEFGHIJKLXYZ[\\]^_`abcdefghijklmnopqr",
227                GetCPWLComboBox()->GetText().c_str());
228 }
229 
TEST_F(CPWLComboBoxEditEmbeddertest,DeleteTextSelectionLeft)230 TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionLeft) {
231   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
232   TypeTextIntoTextField(50);
233 
234   GetCPWLComboBox()->SetEditSelection(0, 5);
235   EXPECT_STREQ(L"ABCDE", GetCPWLComboBox()->GetSelectedText().c_str());
236 
237   GetCPWLComboBox()->ReplaceSelection(L"");
238   EXPECT_STREQ(L"FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
239                GetCPWLComboBox()->GetText().c_str());
240 }
241 
TEST_F(CPWLComboBoxEditEmbeddertest,DeleteTextSelectionRight)242 TEST_F(CPWLComboBoxEditEmbeddertest, DeleteTextSelectionRight) {
243   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
244   TypeTextIntoTextField(50);
245 
246   GetCPWLComboBox()->SetEditSelection(45, 50);
247   EXPECT_STREQ(L"nopqr", GetCPWLComboBox()->GetSelectedText().c_str());
248 
249   GetCPWLComboBox()->ReplaceSelection(L"");
250   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm",
251                GetCPWLComboBox()->GetText().c_str());
252 }
253 
TEST_F(CPWLComboBoxEditEmbeddertest,DeleteEmptyTextSelection)254 TEST_F(CPWLComboBoxEditEmbeddertest, DeleteEmptyTextSelection) {
255   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
256   TypeTextIntoTextField(50);
257 
258   GetCPWLComboBox()->ReplaceSelection(L"");
259   EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
260                GetCPWLComboBox()->GetText().c_str());
261 }
262 
TEST_F(CPWLComboBoxEditEmbeddertest,InsertTextInEmptyEditableComboBox)263 TEST_F(CPWLComboBoxEditEmbeddertest, InsertTextInEmptyEditableComboBox) {
264   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
265   GetCPWLComboBox()->ReplaceSelection(L"Hello");
266   EXPECT_STREQ(L"Hello", GetCPWLComboBox()->GetText().c_str());
267 }
268 
TEST_F(CPWLComboBoxEditEmbeddertest,InsertTextInPopulatedEditableComboBoxLeft)269 TEST_F(CPWLComboBoxEditEmbeddertest,
270        InsertTextInPopulatedEditableComboBoxLeft) {
271   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
272   TypeTextIntoTextField(10);
273 
274   // Move cursor to beginning of user-editable combobox text field.
275   EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotUserEditable(),
276                                              FWL_VKEY_Home, 0));
277 
278   GetCPWLComboBox()->ReplaceSelection(L"Hello");
279   EXPECT_STREQ(L"HelloABCDEFGHIJ", GetCPWLComboBox()->GetText().c_str());
280 }
281 
TEST_F(CPWLComboBoxEditEmbeddertest,InsertTextInPopulatedEditableComboBoxMiddle)282 TEST_F(CPWLComboBoxEditEmbeddertest,
283        InsertTextInPopulatedEditableComboBoxMiddle) {
284   FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
285   TypeTextIntoTextField(10);
286 
287   // Move cursor to middle of user-editable combobox text field.
288   for (int i = 0; i < 5; ++i) {
289     EXPECT_TRUE(GetCFFLFormFiller()->OnKeyDown(GetCPDFSDKAnnotUserEditable(),
290                                                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