sw/qa/core/text/itrform2.cxx     |   40 +++++++++++++++++++++++++++++++++++++++
 sw/source/core/text/itrform2.cxx |    9 ++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)

New commits:
commit 03f8e1c7549a3909fa64f9cd9dfc4cc4c8cc6124
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 30 16:51:49 2024 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 31 09:32:46 2024 +0100

    tdf#159452 sw content control, PDF export: fix checked checkboxes
    
    Regression from commit 9bad5be0ffdcdee92d40162b598ed2ab2815e5d5 (sw
    content controls, checkbox: add PDF export, 2022-09-13), we used to
    export checkbox content controls as plain text, but once checkbox
    content controls are exported as forms, the state of the checkboxes are
    lost.
    
    Writer content control checkboxes support custom values for the checked
    and unchecked states, but the PDF export does not. On one hand,
    PDFWriterImpl::createDefaultCheckBoxAppearance() assumes that the
    checked state should be a checkmark, not the Writer default 'BALLOT BOX
    WITH X' (U+2612). On the other hand, the PDF spec section 12.7.4.2.3
    "Check Boxes" says that the checked state should be "Yes", which
    explains why our checked state is not recognized by PDF readers.
    
    Fix the problem by making the export of checked/unchecked states
    conditional in SwContentControlPortion::DescribePDFControl(): the
    checked state then shows up as expected.
    
    Leave the unchecked case unchanged, the current markup there doesn't
    cause problems.
    
    (cherry picked from commit 256e2c679bcbb3ea446884d0ff4e3f8687b82ede)
    
    Change-Id: I9063d8607c8cccfa080921af38b3cbfe40905115

diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx
index fc8e981dcf5f..6d59140f97f0 100644
--- a/sw/qa/core/text/itrform2.cxx
+++ b/sw/qa/core/text/itrform2.cxx
@@ -16,6 +16,10 @@
 #include <sortedobjs.hxx>
 #include <pagefrm.hxx>
 #include <cntfrm.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <formatcontentcontrol.hxx>
+#include <textcontentcontrol.hxx>
 
 namespace
 {
@@ -166,6 +170,42 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyAnchorLeftMargin)
     // i.e. the left margin was lost.
     CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(6480), 
pLastPara->getFramePrintArea().Left());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testCheckedCheckboxContentControlPDF)
+{
+    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+    if (!pPDFium)
+        return;
+
+    // Given a file with a checked checkbox content control:
+    createSwDoc();
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->InsertContentControl(SwContentControlType::CHECKBOX);
+    // Toggle it, so we get a checked one:
+    SwTextContentControl* pTextContentControl = 
pWrtShell->CursorInsideContentControl();
+    const SwFormatContentControl& rFormatContentControl = 
pTextContentControl->GetContentControl();
+    pWrtShell->GotoContentControl(rFormatContentControl);
+
+    // When exporting to PDF:
+    save("writer_pdf_Export");
+
+    // Then make sure that a checked checkbox form widget is emitted:
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
+    std::unique_ptr<vcl::pdf::PDFiumPage> pPage = pPdfDocument->openPage(0);
+    CPPUNIT_ASSERT_EQUAL(1, pPage->getAnnotationCount());
+    std::unique_ptr<vcl::pdf::PDFiumAnnotation> pAnnotation = 
pPage->getAnnotation(0);
+    CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Widget, 
pAnnotation->getSubType());
+    CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFFormFieldType::CheckBox,
+                         pAnnotation->getFormFieldType(pPdfDocument.get()));
+    OUString aActual = pAnnotation->getFormFieldValue(pPdfDocument.get());
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: Yes
+    // - Actual  : Off
+    // i.e. the /AP -> /N key of the checkbox widget annotation object didn't 
have a sub-key that
+    // would match /V, leading to not showing the checked state.
+    CPPUNIT_ASSERT_EQUAL(OUString("Yes"), aActual);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index f38bba2ef751..6623000c335f 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1018,8 +1018,13 @@ bool SwContentControlPortion::DescribePDFControl(const 
SwTextPaintInfo& rInf) co
             pDescriptor = std::make_unique<vcl::PDFWriter::CheckBoxWidget>();
             auto pCheckBoxWidget = 
static_cast<vcl::PDFWriter::CheckBoxWidget*>(pDescriptor.get());
             pCheckBoxWidget->Checked = pContentControl->GetChecked();
-            pCheckBoxWidget->OnValue = pContentControl->GetCheckedState();
-            pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState();
+            // If it's checked already, then leave the default "Yes" OnValue 
unchanged, so the
+            // appropriate appearance is found by PDF readers.
+            if (!pCheckBoxWidget->Checked)
+            {
+                pCheckBoxWidget->OnValue = pContentControl->GetCheckedState();
+                pCheckBoxWidget->OffValue = 
pContentControl->GetUncheckedState();
+            }
             break;
         }
         case SwContentControlType::DROP_DOWN_LIST:

Reply via email to