sw/qa/extras/ooxmlexport/ooxmlexport17.cxx                     |   37 
+++++++++-
 sw/source/filter/ww8/docxattributeoutput.cxx                   |    5 +
 writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx             |   33 ++++++++
 writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx                   |   11 ++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx              |    5 +
 writerfilter/source/dmapper/SdtHelper.hxx                      |    1 
 7 files changed, 91 insertions(+), 1 deletion(-)

New commits:
commit 22d7cbc0f0c50c59abca7ab5f7db46e4d0e5f86a
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri May 20 08:54:28 2022 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri May 20 10:09:19 2022 +0200

    sw content controls, picture: add DOCX filter
    
    Map Picture UNO property on content controls to:
    
        <w:sdt>
          <w:sdtPr>
            <w:picture/>
        ...
    
    And do the opposite on import.
    
    Change-Id: I5b164f796f194f5fc4bb30d7a30e053e577ed92d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134657
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 8146e942ce5d..281884057770 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -285,7 +285,7 @@ CPPUNIT_TEST_FIXTURE(Test, testCheckboxContentControlExport)
 
 CPPUNIT_TEST_FIXTURE(Test, testDropdownContentControlExport)
 {
-    // Given a document with a checkbox content control around a text portion:
+    // Given a document with a dropdown content control around a text portion:
     mxComponent = loadFromDesktop("private:factory/swriter");
     uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, 
uno::UNO_QUERY);
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
@@ -335,6 +335,41 @@ CPPUNIT_TEST_FIXTURE(Test, 
testDropdownContentControlExport)
     assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:dropDownList/w:listItem[3]", 
"value", "B");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testPictureContentControlExport)
+{
+    // Given a document with a picture content control around a text portion:
+    mxComponent = loadFromDesktop("private:factory/swriter");
+    uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<beans::XPropertySet> xTextGraphic(
+        xMSF->createInstance("com.sun.star.text.TextGraphicObject"), 
uno::UNO_QUERY);
+    xTextGraphic->setPropertyValue("AnchorType",
+                                   
uno::Any(text::TextContentAnchorType_AS_CHARACTER));
+    uno::Reference<text::XTextContent> xTextContent(xTextGraphic, 
uno::UNO_QUERY);
+    xText->insertTextContent(xCursor, xTextContent, false);
+    xCursor->gotoStart(/*bExpand=*/false);
+    xCursor->gotoEnd(/*bExpand=*/true);
+    uno::Reference<text::XTextContent> xContentControl(
+        xMSF->createInstance("com.sun.star.text.ContentControl"), 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, 
uno::UNO_QUERY);
+    xContentControlProps->setPropertyValue("Picture", uno::Any(true));
+    xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
+
+    // When exporting to DOCX:
+    save("Office Open XML Text", maTempFile);
+    mbExported = true;
+
+    // Then make sure the expected markup is used:
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    // Without the fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. <w:picture> was lost on export.
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:picture", 1);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf148494)
 {
     loadAndSave("tdf148494.docx");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 4e46b456c602..65fc656ee13a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2335,6 +2335,11 @@ void DocxAttributeOutput::WriteContentControlStart()
         m_pSerializer->singleElementNS(XML_w, XML_showingPlcHdr);
     }
 
+    if (m_pContentControl->GetPicture())
+    {
+        m_pSerializer->singleElementNS(XML_w, XML_picture);
+    }
+
     if (m_pContentControl->GetCheckbox())
     {
         m_pSerializer->startElementNS(XML_w14, XML_checkbox);
diff --git a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx 
b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
index 633355c79a5f..b2e7f1058f88 100644
--- a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
@@ -181,6 +181,39 @@ CPPUNIT_TEST_FIXTURE(Test, testSdtRunDropdown)
     uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString("choose a color"), xContent->getString());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunPicture)
+{
+    // Given a document with a dropdown inline/run SDT:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"sdt-run-picture.docx";
+
+    // When loading the document:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure that the doc model has a clickable picture content 
control:
+    uno::Reference<text::XTextDocument> xTextDocument(getComponent(), 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xParagraphsAccess(xTextDocument->getText(),
+                                                                    
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphsAccess->createEnumeration();
+    uno::Reference<container::XEnumerationAccess> 
xParagraph(xParagraphs->nextElement(),
+                                                             uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xPortions = 
xParagraph->createEnumeration();
+    uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), 
uno::UNO_QUERY);
+    OUString aPortionType;
+    xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+    // Without the accompanying fix in place, this failed with:
+    // - Expected: ContentControl
+    // - Actual  : Frame
+    // i.e. the SDT was imported as a plain image, not as a clickable 
placeholder in a content
+    // control.
+    CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+    uno::Reference<text::XTextContent> xContentControl;
+    xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+    uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, 
uno::UNO_QUERY);
+    bool bPicture{};
+    xContentControlProps->getPropertyValue("Picture") >>= bPicture;
+    CPPUNIT_ASSERT(bPicture);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx 
b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx
new file mode 100644
index 000000000000..25fcc7f6f8f9
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-picture.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 8f3815fa9abd..0b070b23ea85 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1091,6 +1091,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                     case SdtControlType::richText:
                     case SdtControlType::checkBox:
                     case SdtControlType::dropDown:
+                    case SdtControlType::picture:
                         m_pImpl->PopSdt();
                         break;
                     default:
@@ -2773,6 +2774,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 }
                 break;
             }
+            else if (nSprmId == NS_ooxml::LN_CT_SdtPr_picture)
+            {
+                m_pImpl->m_pSdtHelper->setControlType(SdtControlType::picture);
+                writerfilter::Reference<Properties>::Pointer_t pProperties = 
rSprm.getProps();
+                if (pProperties)
+                {
+                    pProperties->resolve(*this);
+                }
+                break;
+            }
         }
 
         // this is an unsupported SDT property, create a grab bag for it
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index cca5d67adf5a..fd2e3c41631d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -925,6 +925,11 @@ void DomainMapper_Impl::PopSdt()
         }
     }
 
+    if (m_pSdtHelper->getControlType() == SdtControlType::picture)
+    {
+        xContentControlProps->setPropertyValue("Picture", uno::Any(true));
+    }
+
     xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
 
     m_pSdtHelper->clear();
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx 
b/writerfilter/source/dmapper/SdtHelper.hxx
index 6d7310d2a1cc..3fab668c1f19 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -44,6 +44,7 @@ enum class SdtControlType
     plainText,
     richText,
     checkBox,
+    picture,
     unsupported, // Sdt block is defined, but we still do not support such 
type of field
     unknown
 };

Reply via email to