sw/qa/extras/inc/swmodeltestbase.hxx | 14 ++ sw/qa/extras/ooxmlexport/data/simple-sdts.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 2 sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 48 +++++++ sw/source/filter/ww8/docxattributeoutput.cxx | 156 ++++++++++++++----------- sw/source/filter/ww8/docxsdrexport.cxx | 113 +++++++++++------- writerfilter/source/dmapper/DomainMapper.cxx | 27 ++-- writerfilter/source/dmapper/SdtHelper.cxx | 47 +++---- writerfilter/source/dmapper/SdtHelper.hxx | 10 - writerfilter/source/ooxml/model.xml | 2 10 files changed, 272 insertions(+), 147 deletions(-)
New commits: commit 8931ab3fc27acb0665fa636eb6390034cbb3eec6 Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 21:11:33 2014 +0100 ooxml: preserve rich text sdt controls These controls don't have a special property, like for example unformatted text controls have. So we use the id property as a marker; we will grab-bag it together with other sdt properties and use the existing mechanism to write the sdt block on export. A grab bag that only contains an id property is for sure a rich text control so we add it to the character props and not to the paragraph props, like in the case of the unformatted text control. Word doesn't allow us to write an empty <w:id/> tag, so we fill it with a random number. Finally, modified an existing unit test to add a rich text control and check it is exported correctly. Change-Id: If403a4a2393d4ee069a628645e364d21f104a859 diff --git a/sw/qa/extras/ooxmlexport/data/simple-sdts.docx b/sw/qa/extras/ooxmlexport/data/simple-sdts.docx index 294ae79..95c5d00 100644 Binary files a/sw/qa/extras/ooxmlexport/data/simple-sdts.docx and b/sw/qa/extras/ooxmlexport/data/simple-sdts.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index bac36e4..557a3f5 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2920,6 +2920,7 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx") return; assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:text", 1); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:id", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:picture", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:group", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:citation", 1); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 48366e4..546b0a4 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -406,6 +406,11 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse m_pSerializer->endElement( nSdtPrToken ); } + else if( nSdtPrToken == FSNS( XML_w, XML_id ) ) + //Word won't open a document with an empty id tag, we fill it with a random number + m_pSerializer->singleElement( nSdtPrToken, + FSNS(XML_w, XML_val), OString::number( rand() ), + FSEND ); else if( nSdtPrToken > 0 ) m_pSerializer->singleElement( nSdtPrToken, FSEND ); @@ -7141,6 +7146,9 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) } else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text") m_nRunSdtPrToken = FSNS( XML_w, XML_text ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id" && m_nRunSdtPrToken == 0) + // only write id token as a marker if no other exist + m_nRunSdtPrToken = FSNS( XML_w, XML_id ); } } else diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index ed3dc13..f36db65 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2251,6 +2251,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) case NS_ooxml::LN_CT_SdtPr_citation: case NS_ooxml::LN_CT_SdtPr_group: case NS_ooxml::LN_CT_SdtPr_text: + case NS_ooxml::LN_CT_SdtPr_id: { // this is an unsupported SDT property, create a grab bag for it OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nSprmId).c_str()); @@ -2669,7 +2670,9 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) // save them in the paragraph interop grab bag if(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding")) + m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") || + (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") && + m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG); else diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index daf9b81..22f1198 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -215,6 +215,11 @@ bool SdtHelper::isInteropGrabBagEmpty() return m_aGrabBag.getLength() == 0; } +sal_Int32 SdtHelper::getInteropGrabBagSize() +{ + return m_aGrabBag.getLength(); +} + bool SdtHelper::containedInInteropGrabBag(OUString rValueName) { for (sal_Int32 i=0; i < m_aGrabBag.getLength(); ++i) diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index a696287..cfdd875 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -88,6 +88,7 @@ public: com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> getInteropGrabBagAndClear(); bool isInteropGrabBagEmpty(); bool containedInInteropGrabBag(OUString rValueName); + sal_Int32 getInteropGrabBagSize(); }; } // namespace dmapper commit 452469f1b825ac4dfa2b9b096175f7cfc9a1aa36 Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 20:45:53 2014 +0100 ooxml: preserve text sdt property Change-Id: I46b857298ae5d86fe6055efb86d046da48882e8a diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index e9be6b6..bac36e4 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2919,6 +2919,7 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx") if (!pXmlDoc) return; + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:text", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:picture", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:group", 1); assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:citation", 1); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index df6a0df..48366e4 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -7139,6 +7139,8 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); } } + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text") + m_nRunSdtPrToken = FSNS( XML_w, XML_text ); } } else diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index d8d14e6..ed3dc13 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2250,6 +2250,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) case NS_ooxml::LN_CT_SdtPr_picture: case NS_ooxml::LN_CT_SdtPr_citation: case NS_ooxml::LN_CT_SdtPr_group: + case NS_ooxml::LN_CT_SdtPr_text: { // this is an unsupported SDT property, create a grab bag for it OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nSprmId).c_str()); @@ -2667,6 +2668,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) // there are unsupported SDT properties in the document // save them in the paragraph interop grab bag if(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") || + m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding")) m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG); diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index e60d60e..16039bc 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -18907,7 +18907,7 @@ <ref name="CT_Empty"/> </element> <element name="text"> - <ref name="CT_SdtText"/> + <ref name="CT_OnOff"/> </element> <element name="citation"> <ref name="CT_OnOff"/> commit b825b336caec720acfdc97766ebfd96bb077a5af Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 19:53:34 2014 +0100 Fix indentation Change-Id: I380138438171c009a953cfc8afb2cc13e1c1e6a6 diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index d78efaa..df6a0df 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -6937,39 +6937,39 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k) { beans::PropertyValue aPropertyValue = aGrabBagSdt[k]; - if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" || - aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") - { - if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj ); - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList ); - - uno::Sequence<beans::PropertyValue> aGrabBag; - aPropertyValue.Value >>= aGrabBag; - for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" || + aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") { - OUString sValue = aGrabBag[j].Value.get<OUString>(); - if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery") - AddToAttrList( m_pParagraphSdtPrTokenChildren, - FSNS( XML_w, XML_docPartGallery ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory") - AddToAttrList( m_pParagraphSdtPrTokenChildren, - FSNS( XML_w, XML_docPartCategory ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique") - AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" ); + if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList ); + + uno::Sequence<beans::PropertyValue> aGrabBag; + aPropertyValue.Value >>= aGrabBag; + for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + { + OUString sValue = aGrabBag[j].Value.get<OUString>(); + if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery") + AddToAttrList( m_pParagraphSdtPrTokenChildren, + FSNS( XML_w, XML_docPartGallery ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory") + AddToAttrList( m_pParagraphSdtPrTokenChildren, + FSNS( XML_w, XML_docPartCategory ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique") + AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" ); + } } - } - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation ); - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture ); - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation ); - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group") - m_nParagraphSdtPrToken = FSNS( XML_w, XML_group ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation ); + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group") + m_nParagraphSdtPrToken = FSNS( XML_w, XML_group ); } } else @@ -7096,50 +7096,50 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k) { beans::PropertyValue aPropertyValue = aGrabBagSdt[k]; - if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") - { - m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox ); - uno::Sequence<beans::PropertyValue> aGrabBag; - aPropertyValue.Value >>= aGrabBag; - for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") { - OUString sValue = aGrabBag[j].Value.get<OUString>(); - if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checked") - AddToAttrList( m_pRunSdtPrTokenChildren, - FSNS( XML_w14, XML_checked ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState") - AddToAttrList( m_pRunSdtPrTokenChildren, - FSNS( XML_w14, XML_checkedState ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState") - AddToAttrList( m_pRunSdtPrTokenChildren, - FSNS( XML_w14, XML_uncheckedState ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox ); + uno::Sequence<beans::PropertyValue> aGrabBag; + aPropertyValue.Value >>= aGrabBag; + for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + { + OUString sValue = aGrabBag[j].Value.get<OUString>(); + if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checked") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_checked ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_checkedState ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_uncheckedState ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + } } - } - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding") - { - uno::Sequence<beans::PropertyValue> aGrabBag; - aPropertyValue.Value >>= aGrabBag; - for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding") { - OUString sValue = aGrabBag[j].Value.get<OUString>(); - if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings") - AddToAttrList( m_pRunSdtPrDataBindingAttrs, - FSNS( XML_w, XML_prefixMappings ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath") - AddToAttrList( m_pRunSdtPrDataBindingAttrs, - FSNS( XML_w, XML_xpath ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID") - AddToAttrList( m_pRunSdtPrDataBindingAttrs, - FSNS( XML_w, XML_storeItemID ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + uno::Sequence<beans::PropertyValue> aGrabBag; + aPropertyValue.Value >>= aGrabBag; + for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) + { + OUString sValue = aGrabBag[j].Value.get<OUString>(); + if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings") + AddToAttrList( m_pRunSdtPrDataBindingAttrs, + FSNS( XML_w, XML_prefixMappings ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath") + AddToAttrList( m_pRunSdtPrDataBindingAttrs, + FSNS( XML_w, XML_xpath ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID") + AddToAttrList( m_pRunSdtPrDataBindingAttrs, + FSNS( XML_w, XML_storeItemID ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + } } } - } } else SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first); commit e55a4222e694d4354d3c46e6d6aa8d4e7e1ff898 Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 19:52:12 2014 +0100 ooxml: Make SdtHelper grab bag more generic Flexibilize the way the grab bag in SdtHelper works, enabling it to store several children of SdtPr. For every tag inside SdtPr, we enable the DomainMapper grab bag, store the children properties there, and insert the full grab bag inside the SdtHelper grab bag. In this way, the SdtHelper grab bag becomes a Sequence of pairs "SdtPr token name" -> "Bag with children tokens and values". The first advantage of this implementation is that we can preserve dataBinding sdt property plus another one of those supported; until now the second property overwrote the first one in SdtHelper bag. In further patches we will add support for other tags. Some lines are incorrectly indented to make the purpose of this patch more evident, and will be corrected in the next patch. Change-Id: I0ec7be7b96dca455bbbeb03fc2fed230df04c52a diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 4b433c9..d78efaa 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -6932,7 +6932,11 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) } else if (i->first == "SdtPr") { - beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>(); + uno::Sequence<beans::PropertyValue> aGrabBagSdt = + i->second.get< uno::Sequence<beans::PropertyValue> >(); + for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k) + { + beans::PropertyValue aPropertyValue = aGrabBagSdt[k]; if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" || aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") { @@ -6966,6 +6970,7 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation ); else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group") m_nParagraphSdtPrToken = FSNS( XML_w, XML_group ); + } } else SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first ); @@ -7086,7 +7091,11 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) } else if (i->first == "SdtPr") { - beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>(); + uno::Sequence<beans::PropertyValue> aGrabBagSdt = + i->second.get< uno::Sequence<beans::PropertyValue> >(); + for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k) + { + beans::PropertyValue aPropertyValue = aGrabBagSdt[k]; if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") { m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox ); @@ -7130,6 +7139,7 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); } } + } } else SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index f57c142..d8d14e6 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -903,7 +903,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) case NS_ooxml::LN_CT_DataBinding_storeItemID: { OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nName).c_str()); - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(sName, uno::Any(sStringValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, sName, sStringValue); } break; default: @@ -2253,12 +2253,15 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) { // this is an unsupported SDT property, create a grab bag for it OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nSprmId).c_str()); - m_pImpl->m_pSdtHelper->enableInteropGrabBag(sName); + enableInteropGrabBag(sName); // process subitems writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); if (pProperties.get() != NULL) pProperties->resolve(*this); + + m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag()); + m_pImpl->disableInteropGrabBag(); } break; case NS_ooxml::LN_CT_SdtCheckbox_checked: @@ -2270,7 +2273,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) { // this is a child of an unsupported SDT property, store in the grab bag OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nSprmId).c_str()); - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(sName, uno::Any(sStringValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, sName, sStringValue); } break; case NS_ooxml::LN_EG_SectPrContents_pgNumType: @@ -2659,16 +2662,17 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) m_pImpl->m_pSdtHelper->createDateControl(sText); return; } - else if (m_pImpl->m_pSdtHelper->isInteropGrabBagEnabled()) + else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty()) { // there are unsupported SDT properties in the document // save them in the paragraph interop grab bag - OUString sName = m_pImpl->m_pSdtHelper->getInteropGrabBagName(); - uno::Any aPropValue = uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()); - if(sName == "ooxml:CT_SdtPr_checkbox" || sName == "ooxml:CT_SdtPr_dataBinding") - m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, aPropValue, true, CHAR_GRAB_BAG); + if(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") || + m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding")) + m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, + uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG); else - m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, aPropValue, true, PARA_GRAB_BAG); + m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, + uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, PARA_GRAB_BAG); } else if (len == 1 && sText[0] == 0x03) { diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index 2ff928b..daf9b81 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -190,42 +190,38 @@ bool SdtHelper::hasElements() void SdtHelper::appendToInteropGrabBag(const OUString& rName, const css::uno::Any& rValue) { - if (isInteropGrabBagEnabled()) - { - sal_Int32 nLength = m_aGrabBag.getLength(); - m_aGrabBag.realloc(nLength + 1); - m_aGrabBag[nLength].Name = rName; - m_aGrabBag[nLength].Value = rValue; - } + sal_Int32 nLength = m_aGrabBag.getLength(); + m_aGrabBag.realloc(nLength + 1); + m_aGrabBag[nLength].Name = rName; + m_aGrabBag[nLength].Value = rValue; } -beans::PropertyValue SdtHelper::getInteropGrabBagAndClear() +void SdtHelper::appendToInteropGrabBag(com::sun::star::beans::PropertyValue rValue) { - beans::PropertyValue aProp; - if (isInteropGrabBagEnabled()) - { - aProp.Name = m_sGrabBagName; - aProp.Value = uno::Any(m_aGrabBag); - - m_aGrabBag.realloc(0); - m_sGrabBagName = ""; - } - return aProp; + sal_Int32 nLength = m_aGrabBag.getLength(); + m_aGrabBag.realloc(nLength + 1); + m_aGrabBag[nLength] = rValue; } -void SdtHelper::enableInteropGrabBag(const OUString& rName) +com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> SdtHelper::getInteropGrabBagAndClear() { - m_sGrabBagName = rName; + com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> aRet = m_aGrabBag; + m_aGrabBag.realloc(0); + return aRet; } -bool SdtHelper::isInteropGrabBagEnabled() +bool SdtHelper::isInteropGrabBagEmpty() { - return !m_sGrabBagName.isEmpty(); + return m_aGrabBag.getLength() == 0; } -OUString SdtHelper::getInteropGrabBagName() +bool SdtHelper::containedInInteropGrabBag(OUString rValueName) { - return m_sGrabBagName; + for (sal_Int32 i=0; i < m_aGrabBag.getLength(); ++i) + if (m_aGrabBag[i].Name == rValueName) + return true; + + return false; } } // namespace dmapper diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 8f70de9..a696287 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -59,7 +59,6 @@ class SdtHelper OUStringBuffer m_sLocale; /// Grab bag to store unsupported SDTs, aiming to save them back on export. com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> m_aGrabBag; - OUString m_sGrabBagName; bool m_bHasElements; @@ -85,10 +84,10 @@ public: void createDateControl(OUString& rContentText); void appendToInteropGrabBag(const OUString& rName, const css::uno::Any& rValue); - com::sun::star::beans::PropertyValue getInteropGrabBagAndClear(); - void enableInteropGrabBag(const OUString& rName); - bool isInteropGrabBagEnabled(); - OUString getInteropGrabBagName(); + void appendToInteropGrabBag(com::sun::star::beans::PropertyValue rValue); + com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> getInteropGrabBagAndClear(); + bool isInteropGrabBagEmpty(); + bool containedInInteropGrabBag(OUString rValueName); }; } // namespace dmapper commit c6ff03f37a6898f50a5ca07152168fb4fe911e05 Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 13:16:52 2014 +0100 fdo#70838: apply rotation transformations to DML anchor position Used the same algorithm that we had for VML to update the position of the DML anchor taking into account the rotation of the shape. Complemented the unit test to check the values in the generated DML. Change-Id: Ie0293c3cf4d1309fad58c0387f1589e69071fd9a diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 918af37..c8f45e3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -490,6 +490,54 @@ DECLARE_OOXMLEXPORT_TEST(testFdo70838, "fdo70838.docx") if (!pXmlDocument) return; + // Check DML document + + sal_Int32 aXPos[4], aYPos[4]; + aXPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + + aYPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + + // TODO: compare values with a reference value extracted from the original document + // depends on fdo#75722 + // certain degree of error is tolerated due to rounding in unit conversions + CPPUNIT_ASSERT(abs(aXPos[0] - aXPos[1]) < 1000); + CPPUNIT_ASSERT(abs(aXPos[1] - aXPos[2]) < 1000); + CPPUNIT_ASSERT(abs(aXPos[2] - aXPos[3]) < 1000); + + CPPUNIT_ASSERT(abs(aYPos[0] - aYPos[1]) < 1000); + CPPUNIT_ASSERT(abs(aYPos[1] - aYPos[2]) < 1000); + CPPUNIT_ASSERT(abs(aYPos[2] - aYPos[3]) < 1000); + + sal_Int32 aHSize[4], aVSize[4]; + aHSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + + aVSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + + // certain degree of error is tolerated due to rounding in unit conversions + CPPUNIT_ASSERT(abs(3599280 - aHSize[0]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[1]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[2]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[3]) < 1000); + + CPPUNIT_ASSERT(abs(1799640 - aVSize[0]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[1]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[2]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[3]) < 1000); + + // Check VML document + // get styles of the four shapes OUString aStyles[4]; aStyles[0] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:rect", "style"); diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 4d755fc..8add83f 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -86,6 +86,35 @@ OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj) return aResult; } +void lclMovePositionWithRotation(awt::Point& aPos, sal_Int64 nRotation) +{ + // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx) + // TODO: refactor + + if ( nRotation == 0 ) + return; + + if ( nRotation < 0 ) + nRotation = ( 36000 + nRotation ) % 36000; + if ( nRotation % 18000 == 0 ) + nRotation = 0; + while ( nRotation > 9000 ) + nRotation = ( 18000 - ( nRotation % 18000 ) ); + + double fVal = (double) nRotation * F_PI18000; + double fCos = cos( fVal ); + double fSin = sin( fVal ); + + double nWidthHalf = (double) aPos.X / 2; + double nHeightHalf = (double) aPos.Y / 2; + + double nXDiff = fSin * nHeightHalf + fCos * nWidthHalf - nWidthHalf; + double nYDiff = fSin * nWidthHalf + fCos * nHeightHalf - nHeightHalf; + + aPos.X += nXDiff; + aPos.Y += nYDiff; +} + } ExportDataSaveRestore::ExportDataSaveRestore(DocxExport& rExport, sal_uLong nStt, sal_uLong nEnd, sw::Frame* pParentFrame) @@ -268,11 +297,14 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS { sax_fastparser::FastAttributeList* attrList = m_pImpl->m_pSerializer->createAttrList(); bool bOpaque = pFrmFmt->GetOpaque().GetValue(); + awt::Point aPos(pFrmFmt->GetHoriOrient().GetPos(), pFrmFmt->GetVertOrient().GetPos()); const SdrObject* pObj = pFrmFmt->FindRealSdrObject(); if (pObj != NULL) { // SdrObjects know their layer, consider that instead of the frame format. bOpaque = pObj->GetLayer() != pFrmFmt->GetDoc()->GetHellId() && pObj->GetLayer() != pFrmFmt->GetDoc()->GetInvisibleHellId(); + + lclMovePositionWithRotation(aPos, pObj->GetRotateAngle()); } attrList->add(XML_behindDoc, bOpaque ? "0" : "1"); attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr()); @@ -394,7 +426,7 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS else { m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND); - m_pImpl->m_pSerializer->write(TwipsToEMU(pFrmFmt->GetHoriOrient().GetPos())); + m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.X)); m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset); } m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionH); @@ -408,7 +440,7 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS else { m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND); - m_pImpl->m_pSerializer->write(TwipsToEMU(pFrmFmt->GetVertOrient().GetPos())); + m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.Y)); m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset); } m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionV); commit 1b922da415339726fb0186246dba6a03429b33bf Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 10:43:05 2014 +0100 sw/qa: Code refactor. Change-Id: I552b5111901a2e1011a2bd0acaf0231dadd56614 diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index c7e9970..4d755fc 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -50,29 +50,37 @@ using namespace oox; namespace { -OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj) +template<class T> +T lclGetProperty(uno::Reference<drawing::XShape> rShape, OUString rPropName) { - OUString aResult; - uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObj)->getUnoShape(), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); + T aResult; + uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY); uno::Reference<beans::XPropertySetInfo> xPropSetInfo; if (!xPropertySet.is()) return aResult; xPropSetInfo = xPropertySet->getPropertySetInfo(); - if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag")) + if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(rPropName)) { - uno::Sequence< beans::PropertyValue > propList; - xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList; - for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp) + xPropertySet->getPropertyValue(rPropName) >>= aResult; + } + return aResult; +} + +OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj) +{ + OUString aResult; + uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObj)->getUnoShape(), uno::UNO_QUERY); + uno::Sequence< beans::PropertyValue > propList = + lclGetProperty< uno::Sequence<beans::PropertyValue> >(xShape, "FrameInteropGrabBag"); + for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp) + { + OUString aPropName = propList[nProp].Name; + if (aPropName == "AnchorId") { - OUString aPropName = propList[nProp].Name; - if (aPropName == "AnchorId") - { - propList[nProp].Value >>= aResult; - break; - } + propList[nProp].Value >>= aResult; + break; } } return aResult; @@ -555,31 +563,6 @@ void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrmFmt* pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef); uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW); - uno::Reference< beans::XPropertySet > xPropertySet(xShape, uno::UNO_QUERY); - uno::Reference< beans::XPropertySetInfo > xPropSetInfo; - if (xPropertySet.is()) - xPropSetInfo = xPropertySet->getPropertySetInfo(); - - bool bLockedCanvas = false; - if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("InteropGrabBag")) - { - uno::Sequence< beans::PropertyValue > propList; - xPropertySet->getPropertyValue("InteropGrabBag") >>= propList; - for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp) - { - OUString propName = propList[nProp].Name; - if (propName == "LockedCanvas") - { - /* - * Export as Locked Canvas only if the drawing - * was originally a Locked Canvas and is now inside a Text Frame. - */ - - bLockedCanvas = m_pImpl->m_bIsInDMLTextFrame; - break; - } - } - } const char* pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape"; if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape")) pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"; @@ -592,6 +575,22 @@ void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrmFmt* XML_uri, pNamespace, FSEND); + bool bLockedCanvas = false; + uno::Sequence< beans::PropertyValue > propList = + lclGetProperty< uno::Sequence<beans::PropertyValue> >(xShape, "InteropGrabBag"); + for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp) + { + OUString propName = propList[nProp].Name; + if (propName == "LockedCanvas") + { + /* + * Export as Locked Canvas only if the drawing + * was originally a Locked Canvas and is now inside a Text Frame. + */ + bLockedCanvas = m_pImpl->m_bIsInDMLTextFrame; + break; + } + } if (bLockedCanvas) pFS->startElementNS(XML_lc, XML_lockedCanvas, FSNS(XML_xmlns, XML_lc), "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas", commit d3e15e0cb1f21e1fa0bdc83ad5c1a0b8c5f9756d Author: Jacobo Aragunde Pérez <[email protected]> Date: Sat Mar 22 12:51:17 2014 +0100 qa: Added SwModelTestBase::getXPathContent Equivalent to assertXPathContent but returning the string. Change-Id: I06ae4ba7c17db188af64d152b9c2807cc84535ce diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 20d76cc..a204ca0 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -574,6 +574,20 @@ protected: } /** + * Same as the assertXPathContent(), but don't assert: return the string instead. + */ + OUString getXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath) + { + xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath); + + CPPUNIT_ASSERT_MESSAGE(OString("XPath '" + rXPath + "' not found").getStr(), + xmlXPathNodeSetGetLength(pXmlNodes) > 0); + + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0]; + return OUString::createFromAscii((const char*)((pXmlNode->children[0]).content)); + } + + /** * Assert that rXPath exists, and returns exactly one node. * In case rAttribute is provided, the rXPath's attribute's value must * equal to the rExpected value.
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
