include/vcl/pdfwriter.hxx                   |    1 
 toolkit/source/helper/formpdfexport.cxx     |    9 ++++
 vcl/qa/cppunit/pdfexport/data/tdf148442.odt |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx      |   58 ++++++++++++++++++++++++++++
 vcl/source/gdi/pdfwriter_impl.cxx           |   20 +++++++++
 5 files changed, 88 insertions(+)

New commits:
commit 2f1e299983379c89e17bd32dbd49a49b3709e606
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Wed May 11 14:35:20 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon May 16 10:50:57 2022 +0200

    tdf#148442: map RefValue property to onValue in pdf
    
    Similar to what it's already done for radiobuttons
    Change-Id: I708d23dc5f9d4470a9850d7ecc60bd71fada594e
    
    Change-Id: I34107c757b0e0933f392a6d0845fa0d2e07aed62
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134170
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    (cherry picked from commit 6ee5fb6d32147e180552f66e615d1de932fdcf9c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134176

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 6e8d68cfcff9..3dfcc31e0994 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -332,6 +332,7 @@ public:
     struct CheckBoxWidget final : public AnyWidget
     {
         bool                Checked;
+        OUString            OnValue; // the value of the checkbox if it is 
selected
 
         CheckBoxWidget()
                 : AnyWidget( vcl::PDFWriter::CheckBox ),
diff --git a/toolkit/source/helper/formpdfexport.cxx 
b/toolkit/source/helper/formpdfexport.cxx
index 9061d3ec7bce..8011ebf9e616 100644
--- a/toolkit/source/helper/formpdfexport.cxx
+++ b/toolkit/source/helper/formpdfexport.cxx
@@ -564,6 +564,15 @@ namespace toolkitform
                 if( ! (xModelProps->getPropertyValue( FM_PROP_STATE ) >>= 
nState) )
                     SAL_WARN("toolkit.helper", "describePDFControl: unable to 
get property " << FM_PROP_STATE);
                 pCheckBoxWidget->Checked = ( nState != 0 );
+
+                try
+                {
+                    xModelProps->getPropertyValue( "RefValue" ) >>= 
pCheckBoxWidget->OnValue;
+                }
+                catch(...)
+                {
+                    pCheckBoxWidget->OnValue = "On";
+                }
             }
 
 
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf148442.odt 
b/vcl/qa/cppunit/pdfexport/data/tdf148442.odt
new file mode 100644
index 000000000000..31fea48e62b2
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf148442.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 6c69f4a2d693..1dc8f40c3b3d 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -818,6 +818,64 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf108963)
     CPPUNIT_ASSERT_EQUAL(1, nYellowPathCount);
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf148442)
+{
+    vcl::filter::PDFDocument aDocument;
+    load(u"tdf148442.odt", aDocument);
+
+    // The document has one page.
+    std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    auto pAnnots = 
dynamic_cast<vcl::filter::PDFArrayElement*>(aPages[0]->Lookup("Annots"));
+    CPPUNIT_ASSERT(pAnnots);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), 
pAnnots->GetElements().size());
+
+    sal_uInt32 nBtnCount = 0;
+    for (const auto& aElement : aDocument.GetElements())
+    {
+        auto pObject = 
dynamic_cast<vcl::filter::PDFObjectElement*>(aElement.get());
+        if (!pObject)
+            continue;
+        auto pType = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("FT"));
+        if (pType && pType->GetValue() == "Btn")
+        {
+            ++nBtnCount;
+            auto pT = 
dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pObject->Lookup("T"));
+            CPPUNIT_ASSERT(pT);
+            auto pAS = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("AS"));
+            CPPUNIT_ASSERT(pAS);
+
+            auto pAP = 
dynamic_cast<vcl::filter::PDFDictionaryElement*>(pObject->Lookup("AP"));
+            CPPUNIT_ASSERT(pAP);
+            auto pN = 
dynamic_cast<vcl::filter::PDFDictionaryElement*>(pAP->LookupElement("N"));
+            CPPUNIT_ASSERT(pN);
+            CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 
pN->GetItems().size());
+
+            if (nBtnCount == 1)
+            {
+                CPPUNIT_ASSERT_EQUAL(OString("Checkbox1"), pT->GetValue());
+                CPPUNIT_ASSERT_EQUAL(OString("Yes"), pAS->GetValue());
+                CPPUNIT_ASSERT(!pN->GetItems().count("ref"));
+            }
+            else if (nBtnCount == 2)
+            {
+                CPPUNIT_ASSERT_EQUAL(OString("Checkbox2"), pT->GetValue());
+                CPPUNIT_ASSERT_EQUAL(OString("Yes"), pAS->GetValue());
+
+                // Without the fix in place, this test would have failed here
+                CPPUNIT_ASSERT(pN->GetItems().count("ref"));
+            }
+            else
+            {
+                CPPUNIT_ASSERT_EQUAL(OString("Checkbox3"), pT->GetValue());
+                CPPUNIT_ASSERT_EQUAL(OString("Off"), pAS->GetValue());
+                CPPUNIT_ASSERT(pN->GetItems().count("ref"));
+            }
+        }
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf118244_radioButtonGroup)
 {
     vcl::filter::PDFDocument aDocument;
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index e69accc8f6cb..6a450314a6a0 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -4166,6 +4166,25 @@ bool PDFWriterImpl::emitWidgetAnnotations()
     {
         PDFWidget& rWidget = m_aWidgets[a];
 
+        if( rWidget.m_eType == PDFWriter::CheckBox )
+        {
+            auto app_it = rWidget.m_aAppearances.find( "N" );
+            if( app_it != rWidget.m_aAppearances.end() )
+            {
+                auto stream_it = app_it->second.find( "Yes" );
+                if( stream_it != app_it->second.end() )
+                {
+                    SvMemoryStream* pStream = stream_it->second;
+                    app_it->second.erase( stream_it );
+                    OStringBuffer aBuf( rWidget.m_aOnValue.getLength()*2 );
+                    appendName( rWidget.m_aOnValue, aBuf );
+                    (app_it->second)[ aBuf.makeStringAndClear() ] = pStream;
+                }
+                else
+                    SAL_INFO("vcl.pdfwriter", "error: CheckBox without \"Yes\" 
stream" );
+            }
+        }
+
         OStringBuffer aLine( 1024 );
         OStringBuffer aValue( 256 );
         aLine.append( rWidget.m_nObject );
@@ -10854,6 +10873,7 @@ sal_Int32 PDFWriterImpl::createControl( const 
PDFWriter::AnyWidget& rControl, sa
 
         rNewWidget.m_aValue
             = rBox.Checked ? std::u16string_view(u"Yes") : 
std::u16string_view(u"Off" );
+        rNewWidget.m_aOnValue   = rBox.OnValue;
         // create default appearance before m_aRect gets transformed
         createDefaultCheckBoxAppearance( rNewWidget, rBox );
     }

Reply via email to