summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-01-30 16:51:49 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2024-01-31 15:52:23 +0100
commit98120818ebec99287f2eaee4146ab125c5ec470b (patch)
tree8a78aa42c1fefcfb39a6153c1501df86c61e386f
parenttdf#159131 Calc is laggy when moving a line (row) (diff)
downloadcore-98120818ebec99287f2eaee4146ab125c5ec470b.tar.gz
core-98120818ebec99287f2eaee4146ab125c5ec470b.zip
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. Change-Id: I9063d8607c8cccfa080921af38b3cbfe40905115 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162765 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins (cherry picked from commit 256e2c679bcbb3ea446884d0ff4e3f8687b82ede) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162729 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> (cherry picked from commit e2ea03109ee85d8859b56871350fd6179905cd9b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162817
-rw-r--r--sw/qa/core/text/itrform2.cxx40
-rw-r--r--sw/source/core/text/itrform2.cxx9
2 files changed, 47 insertions, 2 deletions
diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx
index 2d9166b12390..c4fd1ac99dd8 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
{
@@ -162,6 +166,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 b46505e226c2..2ded20a97e8f 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: