File indexing completed on 2024-05-12 04:33:27
0001 /* 0002 SPDX-FileCopyrightText: 2013 Jon Mease <jon.mease@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QTest> 0008 0009 #include "../settings_core.h" 0010 #include "core/document.h" 0011 #include <QMimeDatabase> 0012 #include <QMimeType> 0013 #include <core/form.h> 0014 #include <core/page.h> 0015 0016 class EditFormsTest : public QObject 0017 { 0018 Q_OBJECT 0019 0020 private Q_SLOTS: 0021 void initTestCase(); 0022 void cleanupTestCase(); 0023 void init(); 0024 void cleanup(); 0025 0026 void testRadioButtonForm(); 0027 void testCheckBoxForm(); 0028 void testTextLineForm(); 0029 void testTextAreaForm(); 0030 void testFileEditForm(); 0031 void testComboEditForm(); 0032 void testListSingleEdit(); 0033 void testListMultiEdit(); 0034 0035 // helper methods 0036 void verifyRadioButtonStates(bool state1, bool state2, bool state3); 0037 void setRadioButtonStates(bool state1, bool state2, bool state3); 0038 void verifyTextForm(Okular::FormFieldText *form); 0039 0040 private: 0041 Okular::Document *m_document; 0042 QList<Okular::FormFieldButton *> m_radioButtonForms; 0043 QList<Okular::FormFieldButton *> m_checkBoxForms; 0044 Okular::FormFieldText *m_textLineForm; 0045 Okular::FormFieldText *m_textAreaForm; 0046 Okular::FormFieldText *m_fileEditForm; 0047 Okular::FormFieldChoice *m_comboEdit; 0048 Okular::FormFieldChoice *m_listSingleEdit; 0049 Okular::FormFieldChoice *m_listMultiEdit; 0050 }; 0051 0052 void EditFormsTest::initTestCase() 0053 { 0054 Okular::SettingsCore::instance(QStringLiteral("editformstest")); 0055 m_document = new Okular::Document(nullptr); 0056 } 0057 0058 void EditFormsTest::cleanupTestCase() 0059 { 0060 delete m_document; 0061 } 0062 0063 void EditFormsTest::init() 0064 { 0065 const QString testFile = QStringLiteral(KDESRCDIR "data/formSamples.pdf"); 0066 QMimeDatabase db; 0067 const QMimeType mime = db.mimeTypeForFile(testFile); 0068 QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); 0069 0070 // Undo and Redo should be unavailable when docuemnt is first opened. 0071 QVERIFY(!m_document->canUndo()); 0072 QVERIFY(!m_document->canRedo()); 0073 0074 const Okular::Page *page = m_document->page(0); 0075 const QList<Okular::FormField *> pageFields = page->formFields(); 0076 0077 // Clear lists 0078 m_checkBoxForms.clear(); 0079 m_radioButtonForms.clear(); 0080 0081 // Collect forms of the various types 0082 for (Okular::FormField *ff : pageFields) { 0083 ff->type(); 0084 0085 switch (ff->type()) { 0086 case Okular::FormField::FormButton: { 0087 Okular::FormFieldButton *ffb = static_cast<Okular::FormFieldButton *>(ff); 0088 switch (ffb->buttonType()) { 0089 case Okular::FormFieldButton::Push: 0090 break; 0091 case Okular::FormFieldButton::CheckBox: 0092 m_checkBoxForms.append(ffb); 0093 break; 0094 case Okular::FormFieldButton::Radio: 0095 m_radioButtonForms.append(ffb); 0096 break; 0097 default:; 0098 } 0099 break; 0100 } 0101 case Okular::FormField::FormText: { 0102 Okular::FormFieldText *fft = static_cast<Okular::FormFieldText *>(ff); 0103 switch (fft->textType()) { 0104 case Okular::FormFieldText::Multiline: 0105 m_textAreaForm = fft; 0106 break; 0107 case Okular::FormFieldText::Normal: 0108 m_textLineForm = fft; 0109 break; 0110 case Okular::FormFieldText::FileSelect: 0111 m_fileEditForm = fft; 0112 break; 0113 } 0114 break; 0115 } 0116 case Okular::FormField::FormChoice: { 0117 Okular::FormFieldChoice *ffc = static_cast<Okular::FormFieldChoice *>(ff); 0118 switch (ffc->choiceType()) { 0119 case Okular::FormFieldChoice::ListBox: 0120 if (ffc->multiSelect()) { 0121 m_listMultiEdit = ffc; 0122 } else { 0123 m_listSingleEdit = ffc; 0124 } 0125 break; 0126 case Okular::FormFieldChoice::ComboBox: 0127 m_comboEdit = ffc; 0128 break; 0129 } 0130 break; 0131 } 0132 default:; 0133 } 0134 } 0135 } 0136 0137 void EditFormsTest::cleanup() 0138 { 0139 m_document->closeDocument(); 0140 } 0141 0142 void EditFormsTest::testRadioButtonForm() 0143 { 0144 // Initially the first radio button is checked 0145 verifyRadioButtonStates(true, false, false); 0146 0147 // Set the second radio to checked and make sure the first 0148 // is now unchecked and that an undo action is available 0149 setRadioButtonStates(false, true, false); 0150 verifyRadioButtonStates(false, true, false); 0151 QVERIFY(m_document->canUndo()); 0152 0153 // Now undo the action 0154 m_document->undo(); 0155 verifyRadioButtonStates(true, false, false); 0156 QVERIFY(!m_document->canUndo()); 0157 QVERIFY(m_document->canRedo()); 0158 0159 // Now redo the action 0160 m_document->redo(); 0161 verifyRadioButtonStates(false, true, false); 0162 QVERIFY(m_document->canUndo()); 0163 QVERIFY(!m_document->canRedo()); 0164 } 0165 0166 void EditFormsTest::testCheckBoxForm() 0167 { 0168 // Examine the first and second checkboxes 0169 // Initially both checkboxes are unchecked 0170 QVERIFY(m_checkBoxForms[0]->state() == false); 0171 QVERIFY(m_checkBoxForms[1]->state() == false); 0172 0173 // Set checkbox 1 to true 0174 m_document->editFormButtons(0, QList<Okular::FormFieldButton *>() << m_checkBoxForms[0], QList<bool>() << true); 0175 QVERIFY(m_checkBoxForms[0]->state() == true); 0176 QVERIFY(m_checkBoxForms[1]->state() == false); 0177 QVERIFY(m_document->canUndo()); 0178 0179 // Set checkbox 2 to true 0180 m_document->editFormButtons(0, QList<Okular::FormFieldButton *>() << m_checkBoxForms[1], QList<bool>() << true); 0181 QVERIFY(m_checkBoxForms[0]->state() == true); 0182 QVERIFY(m_checkBoxForms[1]->state() == true); 0183 QVERIFY(m_document->canUndo()); 0184 0185 // Undo checking of second checkbox 0186 m_document->undo(); 0187 QVERIFY(m_checkBoxForms[0]->state() == true); 0188 QVERIFY(m_checkBoxForms[1]->state() == false); 0189 QVERIFY(m_document->canUndo()); 0190 QVERIFY(m_document->canRedo()); 0191 0192 // Undo checking of first checkbox 0193 m_document->undo(); 0194 QVERIFY(m_checkBoxForms[0]->state() == false); 0195 QVERIFY(m_checkBoxForms[1]->state() == false); 0196 QVERIFY(!m_document->canUndo()); 0197 QVERIFY(m_document->canRedo()); 0198 0199 // Redo checking of first checkbox 0200 m_document->redo(); 0201 QVERIFY(m_checkBoxForms[0]->state() == true); 0202 QVERIFY(m_checkBoxForms[1]->state() == false); 0203 QVERIFY(m_document->canUndo()); 0204 QVERIFY(m_document->canRedo()); 0205 } 0206 0207 void EditFormsTest::testTextLineForm() 0208 { 0209 verifyTextForm(m_textLineForm); 0210 } 0211 0212 void EditFormsTest::testTextAreaForm() 0213 { 0214 verifyTextForm(m_textAreaForm); 0215 } 0216 0217 void EditFormsTest::testFileEditForm() 0218 { 0219 verifyTextForm(m_fileEditForm); 0220 } 0221 0222 void EditFormsTest::testComboEditForm() 0223 { 0224 // Editable combo with predefined choices: 0225 // - combo1 0226 // - combo2 0227 // - combo3 0228 0229 // Initially no choice is selected 0230 QCOMPARE(m_comboEdit->currentChoices().length(), 0); 0231 QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); 0232 0233 // Select first choice 0234 m_document->editFormCombo(0, m_comboEdit, QStringLiteral("combo1"), 0, 0, 0); 0235 QCOMPARE(m_comboEdit->currentChoices().length(), 1); 0236 QCOMPARE(m_comboEdit->currentChoices().constFirst(), 0); 0237 QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); 0238 QVERIFY(m_document->canUndo()); 0239 QVERIFY(!m_document->canRedo()); 0240 0241 // Select third choice 0242 m_document->editFormCombo(0, m_comboEdit, QStringLiteral("combo3"), 0, 0, 0); 0243 QCOMPARE(m_comboEdit->currentChoices().length(), 1); 0244 QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); 0245 QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); 0246 QVERIFY(m_document->canUndo()); 0247 QVERIFY(!m_document->canRedo()); 0248 0249 // Undo and verify that first choice is selected 0250 m_document->undo(); 0251 QCOMPARE(m_comboEdit->currentChoices().length(), 1); 0252 QCOMPARE(m_comboEdit->currentChoices().constFirst(), 0); 0253 QVERIFY(m_document->canUndo()); 0254 QVERIFY(m_document->canRedo()); 0255 0256 // Redo and verify that third choice is selected 0257 m_document->redo(); 0258 QCOMPARE(m_comboEdit->currentChoices().length(), 1); 0259 QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); 0260 QVERIFY(m_document->canUndo()); 0261 QVERIFY(!m_document->canRedo()); 0262 0263 // Select a custom choice and verify that no predefined choices are selected 0264 m_document->editFormCombo(0, m_comboEdit, QStringLiteral("comboEdit"), 0, 0, 0); 0265 QCOMPARE(m_comboEdit->currentChoices().length(), 0); 0266 QCOMPARE(m_comboEdit->editChoice(), QStringLiteral("comboEdit")); 0267 QVERIFY(m_document->canUndo()); 0268 QVERIFY(!m_document->canRedo()); 0269 0270 // Undo and verify that third choice is selected 0271 m_document->undo(); 0272 QCOMPARE(m_comboEdit->currentChoices().length(), 1); 0273 QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); 0274 QVERIFY(m_document->canUndo()); 0275 QVERIFY(m_document->canRedo()); 0276 } 0277 0278 void EditFormsTest::testListSingleEdit() 0279 { 0280 // A list with three items that allows only single selections 0281 // Initially no choice is selected 0282 QCOMPARE(m_listSingleEdit->currentChoices().length(), 0); 0283 0284 // Select first item 0285 m_document->editFormList(0, m_listSingleEdit, QList<int>() << 0); 0286 QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); 0287 QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 0); 0288 QVERIFY(m_document->canUndo()); 0289 QVERIFY(!m_document->canRedo()); 0290 0291 // Select second item 0292 m_document->editFormList(0, m_listSingleEdit, QList<int>() << 1); 0293 QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); 0294 QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 1); 0295 QVERIFY(m_document->canUndo()); 0296 QVERIFY(!m_document->canRedo()); 0297 0298 // Undo and verify that first item is selected 0299 m_document->undo(); 0300 QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); 0301 QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 0); 0302 QVERIFY(m_document->canUndo()); 0303 QVERIFY(m_document->canRedo()); 0304 0305 // Redo and verify that second item is selected 0306 m_document->redo(); 0307 QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); 0308 QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 1); 0309 QVERIFY(m_document->canUndo()); 0310 QVERIFY(!m_document->canRedo()); 0311 } 0312 0313 void EditFormsTest::testListMultiEdit() 0314 { 0315 // A list with three items that allows for multiple selections 0316 // Initially no choice is selected 0317 QCOMPARE(m_listMultiEdit->currentChoices().length(), 0); 0318 0319 // Select first item 0320 m_document->editFormList(0, m_listMultiEdit, QList<int>() << 0); 0321 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0); 0322 QVERIFY(m_document->canUndo()); 0323 QVERIFY(!m_document->canRedo()); 0324 0325 // Select first and third items 0326 m_document->editFormList(0, m_listMultiEdit, QList<int>() << 0 << 2); 0327 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0 << 2); 0328 QVERIFY(m_document->canUndo()); 0329 QVERIFY(!m_document->canRedo()); 0330 0331 // Select all three items 0332 m_document->editFormList(0, m_listMultiEdit, QList<int>() << 0 << 1 << 2); 0333 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0 << 1 << 2); 0334 QVERIFY(m_document->canUndo()); 0335 QVERIFY(!m_document->canRedo()); 0336 0337 // Undo and verify that first and third items are selected 0338 m_document->undo(); 0339 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0 << 2); 0340 QVERIFY(m_document->canUndo()); 0341 QVERIFY(m_document->canRedo()); 0342 0343 // Undo and verify that first item is selected 0344 m_document->undo(); 0345 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0); 0346 QVERIFY(m_document->canUndo()); 0347 QVERIFY(m_document->canRedo()); 0348 0349 // Redo and verify that first and third items are selected 0350 m_document->redo(); 0351 QCOMPARE(m_listMultiEdit->currentChoices(), QList<int>() << 0 << 2); 0352 QVERIFY(m_document->canUndo()); 0353 QVERIFY(m_document->canRedo()); 0354 } 0355 0356 // helper methods 0357 void EditFormsTest::verifyRadioButtonStates(bool state1, bool state2, bool state3) 0358 { 0359 QVERIFY(m_radioButtonForms[0]->state() == state1); 0360 QVERIFY(m_radioButtonForms[1]->state() == state2); 0361 QVERIFY(m_radioButtonForms[2]->state() == state3); 0362 } 0363 0364 void EditFormsTest::setRadioButtonStates(bool state1, bool state2, bool state3) 0365 { 0366 QList<bool> newButtonStates; 0367 newButtonStates.append(state1); 0368 newButtonStates.append(state2); 0369 newButtonStates.append(state3); 0370 m_document->editFormButtons(0, m_radioButtonForms, newButtonStates); 0371 } 0372 0373 void EditFormsTest::verifyTextForm(Okular::FormFieldText *form) 0374 { 0375 // Text in form is initially empty 0376 QCOMPARE(form->text(), QLatin1String("")); 0377 0378 // Insert the string "Hello" into the form 0379 m_document->editFormText(0, form, QStringLiteral("Hello"), 5, 0, 0); 0380 QCOMPARE(form->text(), QStringLiteral("Hello")); 0381 QVERIFY(m_document->canUndo()); 0382 QVERIFY(!m_document->canRedo()); 0383 0384 // Undo the insertion and verify that form is empty again 0385 m_document->undo(); 0386 QCOMPARE(form->text(), QLatin1String("")); 0387 QVERIFY(!m_document->canUndo()); 0388 QVERIFY(m_document->canRedo()); 0389 0390 // Redo the insertion of "Hello" 0391 m_document->redo(); 0392 QCOMPARE(form->text(), QStringLiteral("Hello")); 0393 QVERIFY(m_document->canUndo()); 0394 QVERIFY(!m_document->canRedo()); 0395 0396 // Type "_World" after "Hello" 0397 m_document->editFormText(0, form, QStringLiteral("Hello_"), 6, 5, 5); 0398 m_document->editFormText(0, form, QStringLiteral("Hello_W"), 7, 6, 6); 0399 m_document->editFormText(0, form, QStringLiteral("Hello_Wo"), 8, 7, 7); 0400 m_document->editFormText(0, form, QStringLiteral("Hello_Wor"), 9, 8, 8); 0401 m_document->editFormText(0, form, QStringLiteral("Hello_Worl"), 10, 9, 9); 0402 m_document->editFormText(0, form, QStringLiteral("Hello_World"), 11, 10, 10); 0403 0404 // Verify that character insertion operations were merged together into a single undo command 0405 m_document->undo(); 0406 QCOMPARE(form->text(), QStringLiteral("Hello")); 0407 QVERIFY(m_document->canUndo()); 0408 QVERIFY(m_document->canRedo()); 0409 0410 // Verify that one more undo gets us back to the original state (empty form) 0411 m_document->undo(); 0412 QCOMPARE(form->text(), QLatin1String("")); 0413 QVERIFY(!m_document->canUndo()); 0414 QVERIFY(m_document->canRedo()); 0415 } 0416 0417 QTEST_MAIN(EditFormsTest) 0418 #include "editformstest.moc"