sw/qa/core/text/data/content-control-header.docx |binary
 sw/qa/core/text/itrform2.cxx                     |   27 +++++++++++++++++++++++
 sw/source/core/text/itrform2.cxx                 |   10 +++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

New commits:
commit e1c06c2f9a7498278b8be55dc4bb79aad7b6874e
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Oct 10 20:06:39 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Oct 16 11:41:00 2023 +0200

    tdf#157593 sw content control, PDF export: fix headers/footers
    
    Regression from commit de90c192cb8f1f03a4028493d8bfe9a127a76b2a (sw
    content controls, plain text: enable DOCX filter with data binding,
    2022-09-19), the PDF export of the bugdoc was broken, content was
    missing on page 2.
    
    Looking at the problem at a higher level, PDF form control in a header
    or footer makes no sense, since then you would get multiple answers for
    the same question.
    
    Fix the problem by disabling the mapping of Writer content controls to
    PDF widgets in headers and footers.
    
    Note that the original motivation is probably around providing a way to
    set the document header via scripting, without touching document.xml or
    headerN.xml. This valid use-case still works after this fix, we still
    update the value of the content control from data binding.
    
    (cherry picked from commit 5dff1f3a995a8e78a156214fd9c32b1005337183)
    
    Change-Id: I969682bf90026236276992dd6b6099e50dffe949
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157783
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Tested-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/core/text/data/content-control-header.docx 
b/sw/qa/core/text/data/content-control-header.docx
new file mode 100644
index 000000000000..c65ac1d41cac
Binary files /dev/null and b/sw/qa/core/text/data/content-control-header.docx 
differ
diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx
index 637396a01c2e..187eb9ab678e 100644
--- a/sw/qa/core/text/itrform2.cxx
+++ b/sw/qa/core/text/itrform2.cxx
@@ -112,6 +112,33 @@ CPPUNIT_TEST_FIXTURE(Test, testFlyMinimalWrap)
     // text frames in the body frame, not 2.
     CPPUNIT_ASSERT(!pPage2Para2->GetNext());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testContentControlHeaderPDFExport)
+{
+    // Given a document with a content control in the header:
+    createSwDoc("content-control-header.docx");
+
+    // When exporting to PDF:
+    save("writer_pdf_Export");
+
+    // Then make sure all the expected text is there on page 2:
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
+    std::unique_ptr<vcl::pdf::PDFiumPage> pPage2 = pPdfDocument->openPage(1);
+    int nTextCount = 0;
+    for (int i = 0; i < pPage2->getObjectCount(); ++i)
+    {
+        std::unique_ptr<vcl::pdf::PDFiumPageObject> pObject = 
pPage2->getObject(i);
+        if (pObject->getType() == vcl::pdf::PDFPageObjectType::Text)
+        {
+            ++nTextCount;
+        }
+    }
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 3
+    // - Actual  : 2
+    // i.e. not all of header, heading and body text was there on page 2, 
content was lost.
+    CPPUNIT_ASSERT_EQUAL(3, nTextCount);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 3aaab7a9f258..c44b831d2a63 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -974,8 +974,16 @@ bool SwContentControlPortion::DescribePDFControl(const 
SwTextPaintInfo& rInf) co
         return false;
     }
 
-    // Check if this is the first content control portion of this content 
control.
     SwTextNode* pTextNode = pContentControl->GetTextNode();
+    SwDoc& rDoc = pTextNode->GetDoc();
+    if (rDoc.IsInHeaderFooter(*pTextNode))
+    {
+        // Form control in header/footer makes no sense, would allow multiple 
values for the same
+        // control.
+        return false;
+    }
+
+    // Check if this is the first content control portion of this content 
control.
     sal_Int32 nStart = m_pTextContentControl->GetStart();
     sal_Int32 nEnd = *m_pTextContentControl->GetEnd();
     TextFrameIndex nViewStart = rInf.GetTextFrame()->MapModelToView(pTextNode, 
nStart);

Reply via email to