poppler/Form.cc | 5 +++- qt5/tests/check_forms.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-)
New commits: commit 8aa78dbcf5370d78ea025e7249e9119202767e44 Author: Nelson Benítez León <[email protected]> Date: Sun Nov 11 19:25:30 2018 +0500 Form.cc: fix radiobutton reporting wrong state When a radiobutton (belonging to a normal radiobutton group) has a /V key matching his 'OnStr' state, then when you ask that radiobutton for his state (eg. radiobutton->state()) it will wrongly return 'true', when really the active radiobutton is another one in the group. This happens because the faulty radiobutton was not passing the getState() call to his Parent (which every radiobutton in a group should do, as the Parent stores the value of the current active item). The code was not doing it because it had a valid AppearanceState (/V key). That behaviour may be right for checkboxes but not for radiobuttons. A testcase is included. An example definition of an affected radiobutton follows: /F 4 /FT /Btn /Ff 49152 /AP /N /Beer 59 0 R /Off 61 0 R /AS /Beer /MK /BC [1,0,0] /BG [1,1,1] /CA (4) /P 20 0 R /Parent 8 0 R /Rect [235.277,654.247,249.224,668.194] /Subtype /Widget /Type /Annot /V /Beer Fixes issue #159 diff --git a/poppler/Form.cc b/poppler/Form.cc index 92775cdc..c3091deb 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -992,7 +992,10 @@ FormFieldButton::FormFieldButton(PDFDoc *docA, Object &&aobj, const Ref ref, For } } - if (btype != formButtonPush) { + bool isChildRadiobutton = btype == formButtonRadio && terminal && parent && parent->getType() == formButton; + // Ignore "V" for child radiobuttons, so FormFieldButton::getState() does not use it and instead uses the + // "V" of the parent, which is the real value indicating the active field in the radio group. Issue #159 + if (btype != formButtonPush && !isChildRadiobutton) { // Even though V is inheritable we are interested in the value of this // field, if not present it's probably because it's a button in a set. appearanceState = dict->lookup("V"); diff --git a/qt5/tests/check_forms.cpp b/qt5/tests/check_forms.cpp index c514d3f1..6c6482df 100644 --- a/qt5/tests/check_forms.cpp +++ b/qt5/tests/check_forms.cpp @@ -11,6 +11,7 @@ public: TestForms(QObject *parent = nullptr) : QObject(parent) { } private slots: void testCheckbox();// Test for issue #655 + void testCheckboxIssue159();// Test for issue #159 }; void TestForms::testCheckbox() @@ -41,5 +42,51 @@ void TestForms::testCheckbox() QCOMPARE( chkFormFieldButton->state() , true ); } +void TestForms::testCheckboxIssue159() +{ + // Test for checkbox issue #159 + QScopedPointer< Poppler::Document > document(Poppler::Document::load(TESTDATADIR "/unittestcases/checkbox_issue_159.pdf")); + QVERIFY( document ); + + QScopedPointer< Poppler::Page > page(document->page(0)); + QVERIFY( page ); + + Poppler::FormFieldButton *beerFieldButton = nullptr; + Poppler::FormFieldButton *wineFieldButton = nullptr; + + QList<Poppler::FormField*> forms = page->formFields(); + + // Let's find and assign the "Wine" and "Beer" radio buttons + Q_FOREACH (Poppler::FormField *field, forms) { + if (field->type() != Poppler::FormField::FormButton) + continue; + + Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field); + if (fieldButton->buttonType() != Poppler::FormFieldButton::Radio) + continue; + + //printf("%s \n", fieldButton->caption().toLatin1().data()); + if (fieldButton->caption() == QStringLiteral("Wine")) { + wineFieldButton = fieldButton; + } else if (fieldButton->caption() == QStringLiteral("Beer")) { + beerFieldButton = fieldButton; + } + } + + // "Beer" and "Wine" radiobuttons belong to the same RadioButton group. + // So selecting one should unselect the other. + QVERIFY( beerFieldButton ); + QVERIFY( wineFieldButton ); + + // Test that the RadioButton group comes with "Beer" initially selected + QCOMPARE( beerFieldButton->state() , true ); + + // Now select "Wine". As a result "Beer" should no longer be selected. + wineFieldButton->setState(true); + + // Test that "Beer" is indeed not reporting as being selected + QCOMPARE( beerFieldButton->state() , false ); +} + QTEST_GUILESS_MAIN(TestForms) #include "check_forms.moc" _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
