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 };
