From 2f1e299983379c89e17bd32dbd49a49b3709e606 Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Wed, 11 May 2022 14:35:20 +0200 Subject: 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 (cherry picked from commit 6ee5fb6d32147e180552f66e615d1de932fdcf9c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134176 --- include/vcl/pdfwriter.hxx | 1 + toolkit/source/helper/formpdfexport.cxx | 9 +++++ vcl/qa/cppunit/pdfexport/data/tdf148442.odt | Bin 0 -> 10573 bytes vcl/qa/cppunit/pdfexport/pdfexport.cxx | 58 ++++++++++++++++++++++++++++ vcl/source/gdi/pdfwriter_impl.cxx | 20 ++++++++++ 5 files changed, 88 insertions(+) create mode 100644 vcl/qa/cppunit/pdfexport/data/tdf148442.odt 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 aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aPages.size()); + + auto pAnnots = dynamic_cast(aPages[0]->Lookup("Annots")); + CPPUNIT_ASSERT(pAnnots); + CPPUNIT_ASSERT_EQUAL(static_cast(3), pAnnots->GetElements().size()); + + sal_uInt32 nBtnCount = 0; + for (const auto& aElement : aDocument.GetElements()) + { + auto pObject = dynamic_cast(aElement.get()); + if (!pObject) + continue; + auto pType = dynamic_cast(pObject->Lookup("FT")); + if (pType && pType->GetValue() == "Btn") + { + ++nBtnCount; + auto pT = dynamic_cast(pObject->Lookup("T")); + CPPUNIT_ASSERT(pT); + auto pAS = dynamic_cast(pObject->Lookup("AS")); + CPPUNIT_ASSERT(pAS); + + auto pAP = dynamic_cast(pObject->Lookup("AP")); + CPPUNIT_ASSERT(pAP); + auto pN = dynamic_cast(pAP->LookupElement("N")); + CPPUNIT_ASSERT(pN); + CPPUNIT_ASSERT_EQUAL(static_cast(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 ); } -- cgit