[Libreoffice-commits] core.git: 7 commits - sw/qa sw/source writerfilter/source

Jacobo Aragunde Pérez jaragunde at igalia.com
Sat Mar 22 15:58:42 PDT 2014


 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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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 <jaragunde at igalia.com>
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.


More information about the Libreoffice-commits mailing list