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

Jacobo Aragunde Pérez jaragunde at igalia.com
Thu Mar 20 02:29:00 PDT 2014


 oox/source/token/tokens.txt                         |    3 
 sw/qa/extras/ooxmlexport/data/author-property.docx  |binary
 sw/qa/extras/ooxmlexport/data/checkbox-control.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx            |   34 ++++-
 sw/source/filter/ww8/docxattributeoutput.cxx        |  125 ++++++++++++++++----
 sw/source/filter/ww8/docxattributeoutput.hxx        |   11 +
 writerfilter/source/dmapper/DomainMapper.cxx        |   21 +++
 writerfilter/source/dmapper/PropertyIds.cxx         |    2 
 writerfilter/source/dmapper/PropertyIds.hxx         |    2 
 writerfilter/source/dmapper/SdtHelper.cxx           |    5 
 writerfilter/source/dmapper/SdtHelper.hxx           |    1 
 writerfilter/source/ooxml/model.xml                 |   64 +++++++---
 12 files changed, 220 insertions(+), 48 deletions(-)

New commits:
commit 306859babd5a997a1e5d50e7791e8e5852a7ea2e
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Mar 19 19:44:27 2014 +0100

    ooxml: preserve dataBinding tag in SDT properties
    
    SDT blocks can contain document properties, like the author. This is
    done with the dataBinding tag inside sdtPr.
    
    Added a resource definition to the ooxml model file, so the parser can
    process this tag. The attributes are stored in the existing grab bag
    used for other sdt properties and written back on export.
    
    The code to write the SDT block in the exporter has been modified to
    be able to extract the new tag from the grab bag and write it to the
    document.
    
    Added a unit test.
    
    Change-Id: I18f35a61784eb0a03ab9ca2cc398ca0df289956c

diff --git a/sw/qa/extras/ooxmlexport/data/author-property.docx b/sw/qa/extras/ooxmlexport/data/author-property.docx
new file mode 100644
index 0000000..474bb79
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/author-property.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 9b0e110..a7657fb 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2927,6 +2927,21 @@ DECLARE_OOXMLEXPORT_TEST(test76317_2K10, "test76317_2K10.docx")
     assertXPath(pXmlDoc, "/w:document[1]/w:body[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:prstGeom[1]/a:avLst[1]/a:gd[1]", "name", "adj");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testAuthorPropertySdt, "author-property.docx")
+{
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+
+    if (!pXmlDoc)
+       return;
+
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "xpath", "/ns1:coreProperties[1]/ns0:creator[1]");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "storeItemID","{6C3C8BC8-F283-45AE-878A-BAB7291924A1}");
+    // FIXME: the next property doesn't match, though it's correct in theory. A bug in assertXPath?
+    // assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:dataBinding", "prefixMappings",
+    //            "xmlns:ns0='http://purl.org/dc/elements/1.1/' xmlns:ns1='http://schemas.openxmlformats.org/package/2006/metadata/core-properties'");
+}
+
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 8d2627f..4792dc1 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -371,7 +371,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
 
     m_pSerializer->endElementNS( XML_w, XML_p );
 
-    WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren );
+    WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs );
     m_pSerializer->mergeTopMarks();
 
     // Check for end of cell, rows, tables here
@@ -381,9 +381,9 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
 
 }
 
-void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren )
+void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs )
 {
-    if( nSdtPrToken > 0 )
+    if( nSdtPrToken > 0 || pSdtPrDataBindingAttrs )
     {
         // sdt start mark
         m_pSerializer->mark();
@@ -393,7 +393,7 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
         // output sdt properties
         m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
 
-        if( pSdtPrTokenChildren )
+        if( nSdtPrToken > 0 && pSdtPrTokenChildren )
         {
             m_pSerializer->startElement( nSdtPrToken, FSEND );
 
@@ -406,9 +406,15 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
 
             m_pSerializer->endElement( nSdtPrToken );
         }
-        else
+        else if( nSdtPrToken > 0 )
             m_pSerializer->singleElement( nSdtPrToken, FSEND );
 
+        if( pSdtPrDataBindingAttrs )
+        {
+            XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs );
+            m_pSerializer->singleElementNS( XML_w, XML_dataBinding, xAttrList );
+        }
+
         m_pSerializer->endElementNS( XML_w, XML_sdtPr );
 
         // sdt contents start tag
@@ -424,6 +430,11 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
         // clear sdt status
         nSdtPrToken = 0;
         delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
+        if( pSdtPrDataBindingAttrs )
+        {
+            // do not delete yet; it's in xAttrList inside the parser
+            pSdtPrDataBindingAttrs = NULL;
+        }
     }
 }
 
@@ -812,7 +823,7 @@ void DocxAttributeOutput::EndRun()
     m_pSerializer->endElementNS( XML_w, XML_r );
 
     // enclose in a sdt block, if necessary
-    WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren );
+    WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs );
     m_pSerializer->mergeTopMarks();
 
     WritePostponedMath();
@@ -7072,6 +7083,27 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
                                        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)
+                {
+                    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);
@@ -7135,8 +7167,10 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_setFootnote(false)
     , m_nParagraphSdtPrToken(0)
     , m_pParagraphSdtPrTokenChildren(NULL)
+    , m_pParagraphSdtPrDataBindingAttrs(NULL)
     , m_nRunSdtPrToken(0)
     , m_pRunSdtPrTokenChildren(NULL)
+    , m_pRunSdtPrDataBindingAttrs(NULL)
 {
 }
 
@@ -7156,7 +7190,9 @@ DocxAttributeOutput::~DocxAttributeOutput()
 
     delete m_pTableWrt, m_pTableWrt = NULL;
     delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
+    delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
     delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
+    delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
 }
 
 DocxExport& DocxAttributeOutput::GetExport()
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index bccd33a..da94c87 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -682,7 +682,7 @@ private:
     void WritePostponedVMLDrawing();
     void WritePostponedDMLDrawing();
 
-    void WriteSdtBlock(sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren);
+    void WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs );
 
     void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = false );
     void DoWriteCmd( const OUString& rCmd );
@@ -861,9 +861,11 @@ private:
     /// members to control the existence of grabbagged SDT properties in the paragraph
     sal_Int32 m_nParagraphSdtPrToken;
     ::sax_fastparser::FastAttributeList *m_pParagraphSdtPrTokenChildren;
+    ::sax_fastparser::FastAttributeList *m_pParagraphSdtPrDataBindingAttrs;
     /// members to control the existence of grabbagged SDT properties in the text run
     sal_Int32 m_nRunSdtPrToken;
     ::sax_fastparser::FastAttributeList *m_pRunSdtPrTokenChildren;
+    ::sax_fastparser::FastAttributeList *m_pRunSdtPrDataBindingAttrs;
 
 public:
     DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 85cbcec..f57c142 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -898,6 +898,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
                 m_pImpl->m_bIgnoreNextPara = true;
         break;
+        case NS_ooxml::LN_CT_DataBinding_prefixMappings:
+        case NS_ooxml::LN_CT_DataBinding_xpath:
+        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));
+        }
+        break;
         default:
             {
 #if OSL_DEBUG_LEVEL > 0
@@ -2234,6 +2242,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
         m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
     }
     break;
+    case NS_ooxml::LN_CT_SdtPr_dataBinding:
     case NS_ooxml::LN_CT_SdtPr_equation:
     case NS_ooxml::LN_CT_SdtPr_checkbox:
     case NS_ooxml::LN_CT_SdtPr_docPartObj:
@@ -2656,7 +2665,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
         // 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")
+        if(sName == "ooxml:CT_SdtPr_checkbox" || sName == "ooxml:CT_SdtPr_dataBinding")
             m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, aPropValue, true, CHAR_GRAB_BAG);
         else
             m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, aPropValue, true, PARA_GRAB_BAG);
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 2ab502a..e60d60e 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -24536,6 +24536,11 @@
       <attribute name="val" tokenid="ooxml:CT_CalendarType_val" action="setValue"/>
       <action name="start" action="setDefaultStringValue"/>
     </resource>
+    <resource name="CT_DataBinding" resource="Properties">
+      <attribute name="prefixMappings" tokenid="ooxml:CT_DataBinding_prefixMappings"/>
+      <attribute name="xpath" tokenid="ooxml:CT_DataBinding_xpath"/>
+      <attribute name="storeItemID" tokenid="ooxml:CT_DataBinding_storeItemID"/>
+    </resource>
     <resource xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" name="CT_SdtPr" resource="Properties" tag="field">
       <element name="rPr" tokenid="ooxml:CT_SdtPr_rPr"/>
       <element name="alias" tokenid="ooxml:CT_SdtPr_alias"/>
commit 876f1cf9bfcbd9f0e578aea6e2a96443ecf823fd
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Mar 19 19:29:18 2014 +0100

    ooxml: Fix testSimpleSdts
    
    Change-Id: Iefd8de05107c6e9ad1dec04711ee3fd8e4c05b17

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 8c4c21b..9b0e110 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2898,9 +2898,9 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx")
     if (!pXmlDoc)
        return;
 
-    assertXPath(pXmlDoc, "/w:body/w:sdt/w:sdtPr/w:picture", 0);
-    assertXPath(pXmlDoc, "/w:body/w:sdt/w:sdtPr/w:group", 0);
-    assertXPath(pXmlDoc, "/w:body/w:sdt/w:sdtPr/w:citation", 0);
+    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);
 
 }
 
commit 692fd140706c9366ee46c651813887c67d5b4a97
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Mar 19 17:10:24 2014 +0100

    fdo#76327: only enclose the checkbox in the sdt block.
    
    The exporter writes the sdt blocks enclosing an entire paragraph, but
    that's not the proper behaviour in all cases. The documents that mix
    checkboxes and text in the same paragraph export the text inside the
    sdt box and that's incorrect.
    
    We have added code to be able to write sdt blocks that enclose
    paragraphs or text runs, depending on the type of block. We have
    applied it to checkboxes now.
    
    There are two sets of properties in DocxAttributeOutput that store
    sdt properties for the text run and for the paragraph. We have
    modified the method WriteParagraphSdt to be generic enough to support
    both cases. To write the sdt block enclosing the text run we used
    parser marks.
    
    We have renamed the property id PROP_PARA_SDTPR to the more generic
    name PROP_SDTPR.
    
    Checkbox unit test was modified to match the new structure of the
    generated document.
    
    Change-Id: I81ffe0062e1a5f80fc4638f7ee454a9bc18e63ee

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 105bd36..8c4c21b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2757,9 +2757,9 @@ DECLARE_OOXMLEXPORT_TEST(testCheckBoxControl, "checkbox-control.docx")
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
     if (!pXmlDoc)
         return;
-    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checked", "val", "1");
-    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checkedState", "val", "2612");
-    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:uncheckedState", "val", "2610");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:checked", "val", "1");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:checkedState", "val", "2612");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:uncheckedState", "val", "2610");
 
     // TODO: import control and add a check here
 }
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 6e2edb2..8d2627f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -371,7 +371,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
 
     m_pSerializer->endElementNS( XML_w, XML_p );
 
-    WriteParagraphSdt();
+    WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren );
     m_pSerializer->mergeTopMarks();
 
     // Check for end of cell, rows, tables here
@@ -381,9 +381,9 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
 
 }
 
-void DocxAttributeOutput::WriteParagraphSdt()
+void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren )
 {
-    if( m_nSdtPrToken > 0 )
+    if( nSdtPrToken > 0 )
     {
         // sdt start mark
         m_pSerializer->mark();
@@ -393,21 +393,21 @@ void DocxAttributeOutput::WriteParagraphSdt()
         // output sdt properties
         m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
 
-        if( m_pSdtPrTokenChildren )
+        if( pSdtPrTokenChildren )
         {
-            m_pSerializer->startElement( m_nSdtPrToken, FSEND );
+            m_pSerializer->startElement( nSdtPrToken, FSEND );
 
-            uno::Sequence<xml::FastAttribute> aChildren = m_pSdtPrTokenChildren->getFastAttributes();
+            uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
             for( sal_Int32 i=0; i < aChildren.getLength(); ++i )
                 m_pSerializer->singleElement( aChildren[i].Token,
                                               FSNS(XML_w, XML_val),
                                               rtl::OUStringToOString( aChildren[i].Value, RTL_TEXTENCODING_UTF8 ).getStr(),
                                               FSEND );
 
-            m_pSerializer->endElement( m_nSdtPrToken );
+            m_pSerializer->endElement( nSdtPrToken );
         }
         else
-            m_pSerializer->singleElement( m_nSdtPrToken, FSEND );
+            m_pSerializer->singleElement( nSdtPrToken, FSEND );
 
         m_pSerializer->endElementNS( XML_w, XML_sdtPr );
 
@@ -422,8 +422,8 @@ void DocxAttributeOutput::WriteParagraphSdt()
         m_pSerializer->endElementNS( XML_w, XML_sdt );
 
         // clear sdt status
-        m_nSdtPrToken = 0;
-        delete m_pSdtPrTokenChildren; m_pSdtPrTokenChildren = NULL;
+        nSdtPrToken = 0;
+        delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
     }
 }
 
@@ -676,6 +676,9 @@ void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bS
     // that has to be started first.
     m_pRedlineData = pRedlineData;
 
+    // this mark is used to be able to enclose the run inside a sdr tag.
+    m_pSerializer->mark();
+
     // postpone the output of the start of a run (there are elements that need
     // to be written before the start of the run, but we learn which they are
     // _inside_ of the run)
@@ -808,6 +811,10 @@ void DocxAttributeOutput::EndRun()
     // append the actual run end
     m_pSerializer->endElementNS( XML_w, XML_r );
 
+    // enclose in a sdt block, if necessary
+    WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren );
+    m_pSerializer->mergeTopMarks();
+
     WritePostponedMath();
 
     for (std::vector<const SdrObject*>::iterator it = m_aPostponedFormControls.begin(); it != m_aPostponedFormControls.end(); ++it)
@@ -6886,16 +6893,16 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
                     FSNS(XML_w, XML_themeFill), OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8).getStr(),
                     FSNS(XML_w, XML_fill), OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8).getStr());
         }
-        else if (i->first == "ParaSdtPr")
+        else if (i->first == "SdtPr")
         {
             beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>();
             if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
                     aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
             {
                 if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
-                    m_nSdtPrToken = FSNS( XML_w, XML_docPartObj );
+                    m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj );
                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
-                    m_nSdtPrToken = FSNS( XML_w, XML_docPartList );
+                    m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList );
 
                 uno::Sequence<beans::PropertyValue> aGrabBag;
                 aPropertyValue.Value >>= aGrabBag;
@@ -6903,47 +6910,25 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
                 {
                     OUString sValue = aGrabBag[j].Value.get<OUString>();
                     if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery")
-                        AddToAttrList( m_pSdtPrTokenChildren,
+                        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_pSdtPrTokenChildren,
+                        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_pSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
-                }
-            }
-            else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
-            {
-                m_nSdtPrToken = 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_pSdtPrTokenChildren,
-                                       FSNS( XML_w14, XML_checked ),
-                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
-                    else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
-                        AddToAttrList( m_pSdtPrTokenChildren,
-                                       FSNS( XML_w14, XML_checkedState ),
-                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
-                    else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
-                        AddToAttrList( m_pSdtPrTokenChildren,
-                                       FSNS( XML_w14, XML_uncheckedState ),
-                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+                        AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
                 }
             }
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
-                m_nSdtPrToken = FSNS( XML_w, XML_equation );
+                m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation );
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
-                m_nSdtPrToken = FSNS( XML_w, XML_picture );
+                m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture );
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
-                m_nSdtPrToken = FSNS( XML_w, XML_citation );
+                m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
-                m_nSdtPrToken = FSNS( XML_w, XML_group );
+                m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
         }
         else
             SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
@@ -7062,6 +7047,32 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
             m_aTextEffectsGrabBag.realloc(m_aTextEffectsGrabBag.getLength() + 1);
             m_aTextEffectsGrabBag[aLength] = aPropertyValue;
         }
+        else if (i->first == "SdtPr")
+        {
+            beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>();
+            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)
+                {
+                    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
             SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first);
     }
@@ -7122,8 +7133,10 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_nParaBeforeSpacing(0),
       m_nParaAfterSpacing(0),
       m_setFootnote(false)
-    , m_nSdtPrToken(0)
-    , m_pSdtPrTokenChildren(NULL)
+    , m_nParagraphSdtPrToken(0)
+    , m_pParagraphSdtPrTokenChildren(NULL)
+    , m_nRunSdtPrToken(0)
+    , m_pRunSdtPrTokenChildren(NULL)
 {
 }
 
@@ -7142,7 +7155,8 @@ DocxAttributeOutput::~DocxAttributeOutput()
     delete m_pEndnotesList, m_pEndnotesList = NULL;
 
     delete m_pTableWrt, m_pTableWrt = NULL;
-    delete m_pSdtPrTokenChildren; m_pSdtPrTokenChildren = NULL;
+    delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
+    delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
 }
 
 DocxExport& DocxAttributeOutput::GetExport()
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 5b55dc8..bccd33a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -682,7 +682,7 @@ private:
     void WritePostponedVMLDrawing();
     void WritePostponedDMLDrawing();
 
-    void WriteParagraphSdt();
+    void WriteSdtBlock(sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren);
 
     void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = false );
     void DoWriteCmd( const OUString& rCmd );
@@ -859,8 +859,11 @@ private:
     std::map<const Graphic*, OString> m_aRelIdCache;
 
     /// members to control the existence of grabbagged SDT properties in the paragraph
-    sal_Int32 m_nSdtPrToken;
-    ::sax_fastparser::FastAttributeList *m_pSdtPrTokenChildren;
+    sal_Int32 m_nParagraphSdtPrToken;
+    ::sax_fastparser::FastAttributeList *m_pParagraphSdtPrTokenChildren;
+    /// members to control the existence of grabbagged SDT properties in the text run
+    sal_Int32 m_nRunSdtPrToken;
+    ::sax_fastparser::FastAttributeList *m_pRunSdtPrTokenChildren;
 
 public:
     DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 0b62830..85cbcec 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2654,8 +2654,12 @@ 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
+        OUString sName = m_pImpl->m_pSdtHelper->getInteropGrabBagName();
         uno::Any aPropValue = uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear());
-        m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_PARA_SDTPR, aPropValue, true, PARA_GRAB_BAG);
+        if(sName == "ooxml:CT_SdtPr_checkbox")
+            m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, aPropValue, true, CHAR_GRAB_BAG);
+        else
+            m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, aPropValue, true, PARA_GRAB_BAG);
     }
     else if (len == 1 && sText[0] == 0x03)
     {
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index a26cdf9..8bdba4e 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -387,7 +387,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const
             case PROP_CHAR_NUMSPACING_TEXT_EFFECT    :   sName = "CharNumSpacingTextEffect"; break;
             case PROP_CHAR_STYLISTICSETS_TEXT_EFFECT :   sName = "CharStylisticSetsTextEffect"; break;
             case PROP_CHAR_CNTXTALTS_TEXT_EFFECT     :   sName = "CharCntxtAltsTextEffect"; break;
-            case PROP_PARA_SDTPR                     :   sName = "ParaSdtPr"; break;
+            case PROP_SDTPR                          :   sName = "SdtPr"; break;
         }
         ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt =
                 m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName ));
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index 6370a1d..1d29c0b 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -359,7 +359,7 @@ enum PropertyIds
         ,PROP_CHAR_NUMSPACING_TEXT_EFFECT
         ,PROP_CHAR_STYLISTICSETS_TEXT_EFFECT
         ,PROP_CHAR_CNTXTALTS_TEXT_EFFECT
-        ,PROP_PARA_SDTPR
+        ,PROP_SDTPR
     };
 struct PropertyNameSupplier_Impl;
 class PropertyNameSupplier
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx
index 32691d9..2ff928b 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -223,6 +223,11 @@ bool SdtHelper::isInteropGrabBagEnabled()
     return !m_sGrabBagName.isEmpty();
 }
 
+OUString SdtHelper::getInteropGrabBagName()
+{
+    return m_sGrabBagName;
+}
+
 } // namespace dmapper
 } // namespace writerfilter
 
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx
index 95f6559..8f70de9 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -88,6 +88,7 @@ public:
     com::sun::star::beans::PropertyValue getInteropGrabBagAndClear();
     void enableInteropGrabBag(const OUString& rName);
     bool isInteropGrabBagEnabled();
+    OUString getInteropGrabBagName();
 };
 
 } // namespace dmapper
commit f79f3e072c2ff2f4624c2ec4c577d400733584a5
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Mar 19 12:29:26 2014 +0100

    ooxml: import combobox sdt control
    
    This patch modifies the importer to reuse the code that imports the
    dropdown control and creates a combo box with it.
    
    The only drawback is that the combobox tag is transformed into a
    dropdownlist when exported back, but it doesn't seem to be an issue
    from the point of view of the user.
    
    Change-Id: I340d0cf02d8c5ea575ad4784a1242d2a3e9bd214

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index e1215f0..0b62830 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2203,6 +2203,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
     }
     break;
     case NS_ooxml::LN_CT_SdtPr_dropDownList:
+    case NS_ooxml::LN_CT_SdtPr_comboBox:
     {
         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
         if (pProperties.get() != NULL)
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index ca9685d..2ab502a 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -18774,19 +18774,6 @@
           </attribute>
         </optional>
       </define>
-      <define name="CT_SdtComboBox">
-        <zeroOrMore>
-          <element name="listItem">
-            <ref name="CT_SdtListItem"/>
-          </element>
-        </zeroOrMore>
-        <optional>
-          <attribute name="lastValue">
-            <text/>
-            <xs:documentation>Combo Box Last Saved Value</xs:documentation>
-          </attribute>
-        </optional>
-      </define>
       <define name="CT_SdtDocPart">
         <optional>
           <element name="docPartGallery">
@@ -18896,7 +18883,7 @@
                   <ref name="CT_OnOff"/>
                 </element>
                 <element name="comboBox">
-                  <ref name="CT_SdtComboBox"/>
+                  <ref name="CT_SdtDropDownList"/>
                 </element>
                 <element name="w14:checkbox">
                   <ref name="CT_SdtCheckbox"/>
commit 64ad575674e6170ebb8ebeeacd41b14af07a0377
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Mar 19 11:19:54 2014 +0100

    ooxml: preserve checkbox sdt control
    
    Checkbox controls in docx are implemented with a sdt block containing
    the property w:14:checkbox, which has several child elements.
    
    To implement the preservation of the field, we had to add several
    tags to the ooxml model file. Notice they belong to namespace w14,
    that's why we had to add a redundant definitions of CT_STRING,
    ST_STRING and their actions. Then, we just used the existing
    mechanisms on the importer and the exporter.
    
    Finally, added a unit test.
    
    TODO: the checkbox is preserved on export but it cannot be modified.
    We should import it like we do for combo and date boxes.
    
    Change-Id: I40f29b48ec24719c48482b9c8cff10176d1b188d

diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index 8d40a4b..e274001 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -1141,8 +1141,10 @@ chartStar
 chartX
 chartreuse
 chartsheet
+checkbox
 checkBox
 checkCompatibility
+checkedState
 checkErrors
 checkStyle
 checked
@@ -5395,6 +5397,7 @@ unbalanced
 unbalancedGroup
 unboundColumnsLeft
 unboundColumnsRight
+uncheckedState
 undOvr
 underDot
 underlineTabInNumList
diff --git a/sw/qa/extras/ooxmlexport/data/checkbox-control.docx b/sw/qa/extras/ooxmlexport/data/checkbox-control.docx
new file mode 100644
index 0000000..905d29a
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/checkbox-control.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 90712a3..105bd36 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2751,6 +2751,19 @@ DECLARE_OOXMLEXPORT_TEST(testComboBoxControl, "combobox-control.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("pepito"), aItems[1]);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testCheckBoxControl, "checkbox-control.docx")
+{
+    // check XML
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+        return;
+    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checked", "val", "1");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checkedState", "val", "2612");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:uncheckedState", "val", "2610");
+
+    // TODO: import control and add a check here
+}
+
 DECLARE_OOXMLEXPORT_TEST(testParagraphWithComments, "paragraphWithComments.docx")
 {
     /* Comment id's were getting overwritten for annotation mark(s),
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index a97fa11..6e2edb2 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6914,6 +6914,28 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
                         AddToAttrList( m_pSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
                 }
             }
+            else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
+            {
+                m_nSdtPrToken = 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_pSdtPrTokenChildren,
+                                       FSNS( XML_w14, XML_checked ),
+                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+                    else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
+                        AddToAttrList( m_pSdtPrTokenChildren,
+                                       FSNS( XML_w14, XML_checkedState ),
+                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+                    else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
+                        AddToAttrList( m_pSdtPrTokenChildren,
+                                       FSNS( XML_w14, XML_uncheckedState ),
+                                       rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+                }
+            }
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
                 m_nSdtPrToken = FSNS( XML_w, XML_equation );
             else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 0407fd1..e1215f0 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2234,6 +2234,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
     }
     break;
     case NS_ooxml::LN_CT_SdtPr_equation:
+    case NS_ooxml::LN_CT_SdtPr_checkbox:
     case NS_ooxml::LN_CT_SdtPr_docPartObj:
     case NS_ooxml::LN_CT_SdtPr_docPartList:
     case NS_ooxml::LN_CT_SdtPr_picture:
@@ -2250,6 +2251,9 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
             pProperties->resolve(*this);
     }
     break;
+    case NS_ooxml::LN_CT_SdtCheckbox_checked:
+    case NS_ooxml::LN_CT_SdtCheckbox_checkedState:
+    case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState:
     case NS_ooxml::LN_CT_SdtDocPart_docPartGallery:
     case NS_ooxml::LN_CT_SdtDocPart_docPartCategory:
     case NS_ooxml::LN_CT_SdtDocPart_docPartUnique:
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index d80f2e2..ca9685d 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -6280,9 +6280,47 @@
           <ref name="CT_OnOff"/>
         </element>
       </define>
+
+      <define name="ST_String">
+        <data type="string">
+          <xs:documentation>String</xs:documentation>
+        </data>
+      </define>
+      <define name="CT_String">
+        <attribute name="val">
+          <ref name="ST_String"/>
+          <xs:documentation>value</xs:documentation>
+        </attribute>
+      </define>
+      <define name="CT_SdtCheckbox">
+        <optional>
+          <element name="checked">
+            <ref name="CT_String"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="checkedState">
+            <ref name="CT_String"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="uncheckedState">
+            <ref name="CT_String"/>
+          </element>
+        </optional>
+      </define>
     </grammar>
 
     <!-- Simple Types Resource Definitions -->
+    <resource name="CT_String" resource="Value" tag="attribute">
+      <attribute name="val" tokenid="ooxml:CT_String_val" action="setValue"/>
+      <action name="start" action="setDefaultStringValue"/>
+    </resource>
+    <resource name="CT_SdtCheckbox" resource="Properties" tag="field">
+      <element name="checked" tokenid="ooxml:CT_SdtCheckbox_checked">checked</element>
+      <element name="checkedState" tokenid="ooxml:CT_SdtCheckbox_checkedState">checkedState</element>
+      <element name="uncheckedState" tokenid="ooxml:CT_SdtCheckbox_uncheckedState">uncheckedState</element>
+    </resource>
     <resource name="ST_SchemeColorVal" resource="List" generated="yes">
       <value name="bg1" tokenid="ooxml:ST_SchemeColorVal_bg1">bg1</value>
       <value name="tx1" tokenid="ooxml:ST_SchemeColorVal_tx1">tx1</value>
@@ -18860,6 +18898,9 @@
                 <element name="comboBox">
                   <ref name="CT_SdtComboBox"/>
                 </element>
+                <element name="w14:checkbox">
+                  <ref name="CT_SdtCheckbox"/>
+                </element>
                 <element name="date">
                   <ref name="CT_SdtDate"/>
                 </element>
@@ -24508,7 +24549,7 @@
       <attribute name="val" tokenid="ooxml:CT_CalendarType_val" action="setValue"/>
       <action name="start" action="setDefaultStringValue"/>
     </resource>
-    <resource name="CT_SdtPr" resource="Properties" tag="field">
+    <resource xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" name="CT_SdtPr" resource="Properties" tag="field">
       <element name="rPr" tokenid="ooxml:CT_SdtPr_rPr"/>
       <element name="alias" tokenid="ooxml:CT_SdtPr_alias"/>
       <element name="lock" tokenid="ooxml:CT_SdtPr_lock"/>
@@ -24520,6 +24561,7 @@
       <element name="tag" tokenid="ooxml:CT_SdtPr_tag"/>
       <element name="equation" tokenid="ooxml:CT_SdtPr_equation"/>
       <element name="comboBox" tokenid="ooxml:CT_SdtPr_comboBox"/>
+      <element name="w14:checkbox" tokenid="ooxml:CT_SdtPr_checkbox"/>
       <element name="date" tokenid="ooxml:CT_SdtPr_date"/>
       <element name="docPartObj" tokenid="ooxml:CT_SdtPr_docPartObj"/>
       <element name="docPartList" tokenid="ooxml:CT_SdtPr_docPartList"/>
commit de1f5cb2ad67d94dfac46b3577a7c0b8ed06ba6d
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Tue Mar 18 10:59:12 2014 +0100

    ooxml: preserve docPartList property in sdt blocks
    
    This patch strictly reuses the code introduced at commit
    55211e612d2cbed03dd81c039d07ea4e936c2804.
    
    Change-Id: Ie9151c81c2cb63d0f4a320293b6e5d27f20d4043

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1ff6305..a97fa11 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6889,9 +6889,14 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
         else if (i->first == "ParaSdtPr")
         {
             beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>();
-            if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
+            if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
+                    aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
             {
-                m_nSdtPrToken = FSNS( XML_w, XML_docPartObj );
+                if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
+                    m_nSdtPrToken = FSNS( XML_w, XML_docPartObj );
+                else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
+                    m_nSdtPrToken = FSNS( XML_w, XML_docPartList );
+
                 uno::Sequence<beans::PropertyValue> aGrabBag;
                 aPropertyValue.Value >>= aGrabBag;
                 for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 4c18238..0407fd1 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2235,6 +2235,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
     break;
     case NS_ooxml::LN_CT_SdtPr_equation:
     case NS_ooxml::LN_CT_SdtPr_docPartObj:
+    case NS_ooxml::LN_CT_SdtPr_docPartList:
     case NS_ooxml::LN_CT_SdtPr_picture:
     case NS_ooxml::LN_CT_SdtPr_citation:
     case NS_ooxml::LN_CT_SdtPr_group:


More information about the Libreoffice-commits mailing list