[poppler] poppler/Form.cc qt5/tests

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Mar 31 00:01:03 UTC 2019


 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 <nbenitezl at gmail.com>
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"


More information about the poppler mailing list