sw/qa/extras/ooxmlexport/data/tdf137466.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx   |   15 ++++
 sw/qa/extras/ooxmlexport/ooxmlexport4.cxx    |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx    |    4 -
 sw/qa/extras/ooxmlexport/ooxmlw14export.cxx  |    2 
 sw/source/filter/ww8/docxattributeoutput.cxx |   89 ++++++++++++++++++++++++---
 sw/source/filter/ww8/docxattributeoutput.hxx |    6 +
 sw/source/filter/ww8/docxexport.cxx          |    3 
 writerfilter/source/dmapper/DomainMapper.cxx |   20 +++++-
 writerfilter/source/ooxml/model.xml          |   29 +++++++-
 10 files changed, 152 insertions(+), 18 deletions(-)

New commits:
commit 7db38a496a5e458ec12888ddbf63c603706ae3fc
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Tue Nov 16 11:50:03 2021 +0300
Commit:     Vasily Melenchuk <vasily.melenc...@cib.de>
CommitDate: Mon Nov 29 11:41:53 2021 +0100

    tdf#137466: docx: support w:placeholder & w15:color in w:sdtPr
    
    Content controls in Word can contain some other elements which
    are not supported by Writer. Put them into grabbag and write
    back to DOCX on save to avoid losing quite sensitive data.
    
    Test testSimpleSdts is modified: testcase is actully containing
    4 sdt elements with ids in input and output.
    
    Change-Id: I1f9addd03ed828bf375ccac5188a004f011e8a0d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125271
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf137466.docx 
b/sw/qa/extras/ooxmlexport/data/tdf137466.docx
new file mode 100644
index 000000000000..3c5977251bda
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf137466.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index c991bdf87f13..ea6b62e5e8e0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -65,6 +65,21 @@ CPPUNIT_TEST_FIXTURE(Test, testParaStyleNumLevel)
     assertXPath(pXmlDoc, 
"/w:styles/w:style[@w:styleId='Mystyle']/w:pPr/w:numPr/w:ilvl", "val", "1");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf137466, "tdf137466.docx")
+{
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+       return; // initial import, no futher checks
+
+    // Ensure that we have <w:placeholder><w:docPart 
v:val="xxxx"/></w:placeholder>
+    OUString sDocPart = getXPath(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtPr/w:placeholder/w:docPart", "val");
+    CPPUNIT_ASSERT_EQUAL(OUString("DefaultPlaceholder_-1854013440"), sDocPart);
+
+    // Ensure that we have <w15:color v:val="xxxx"/>
+    OUString sColor = getXPath(pXmlDoc, 
"/w:document/w:body/w:sdt/w:sdtPr/w15:color", "val");
+    CPPUNIT_ASSERT_EQUAL(OUString("FF0000"), sColor);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testDontAddNewStyles)
 {
     // Given a document that lacks builtin styles, and addition of them is 
disabled:
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
index 0bead93d1d8a..1957ee7a545d 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
@@ -1026,7 +1026,7 @@ CPPUNIT_TEST_FIXTURE(Test, testSimpleSdts)
     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
 
     assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:text", 1);
-    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:id", 3);
+    assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:id", 4);
     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:p/w:sdt/w:sdtPr/w:citation", 1);
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index cbd6e13f340d..29d5630562c0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -582,10 +582,10 @@ CPPUNIT_TEST_FIXTURE(Test, testFDO79062)
 {
     loadAndSave("fdo79062.docx");
     xmlDocUniquePtr pXmlFootNotes = parseExport("word/footnotes.xml");
-    assertXPath(pXmlFootNotes, "/w:footnotes", "Ignorable", "w14 wp14");
+    assertXPath(pXmlFootNotes, "/w:footnotes", "Ignorable", "w14 wp14 w15");
 
     xmlDocUniquePtr pXmlEndNotes = parseExport("word/endnotes.xml");
-    assertXPath(pXmlEndNotes, "/w:endnotes", "Ignorable", "w14 wp14");
+    assertXPath(pXmlEndNotes, "/w:endnotes", "Ignorable", "w14 wp14 w15");
 
     //tdf#93121 don't add fake tabs in front of extra footnote paragraphs
     uno::Reference<text::XFootnotesSupplier> xFootnoteSupp(mxComponent, 
uno::UNO_QUERY);
diff --git a/sw/qa/extras/ooxmlexport/ooxmlw14export.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlw14export.cxx
index e508e2d08145..602ef048f5ca 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlw14export.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlw14export.cxx
@@ -254,7 +254,7 @@ CPPUNIT_TEST_FIXTURE(Test, Test_McIgnorable)
     loadAndReload("TextEffects_StylisticSets_CntxtAlts.docx");
     xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml");
 
-    assertXPath(pXmlDocument, "/w:document", "Ignorable", "w14 wp14");
+    assertXPath(pXmlDocument, "/w:document", "Ignorable", "w14 wp14 w15");
 
     xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 9b6a144ed481..4ddb54a517f5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -587,7 +587,7 @@ static void lcl_deleteAndResetTheLists(
     rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenChildren,
     rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrDataBindingAttrs,
     rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTextAttrs,
-    OUString& rSdtPrAlias)
+    OUString& rSdtPrAlias, OUString& rSdtPrPlaceholderDocPart, OUString& 
rColor)
 {
     if( pSdtPrTokenChildren.is() )
         pSdtPrTokenChildren.clear();
@@ -597,6 +597,10 @@ static void lcl_deleteAndResetTheLists(
         pSdtPrTextAttrs.clear();
     if (!rSdtPrAlias.isEmpty())
         rSdtPrAlias.clear();
+    if (!rSdtPrPlaceholderDocPart.isEmpty())
+        rSdtPrPlaceholderDocPart.clear();
+    if (!rColor.isEmpty())
+        rColor.clear();
 }
 
 void DocxAttributeOutput::PopulateFrameProperties(const SwFrameFormat* 
pFrameFormat, const Size& rSize)
@@ -803,14 +807,20 @@ void DocxAttributeOutput::EndParagraph( 
ww8::WW8TableNodeInfoInner::Pointer_t pT
     m_pSerializer->endElementNS( XML_w, XML_p );
     // on export sdt blocks are never nested ATM
     if( !m_bAnchorLinkedToNode && !m_bStartedParaSdt )
-        WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, 
m_pParagraphSdtPrTokenAttributes, m_pParagraphSdtPrDataBindingAttrs, 
m_pParagraphSdtPrTextAttrs, m_aParagraphSdtPrAlias, /*bPara=*/true );
+        WriteSdtBlock(m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren,
+                      m_pParagraphSdtPrTokenAttributes, 
m_pParagraphSdtPrDataBindingAttrs,
+                      m_pParagraphSdtPrTextAttrs, m_aParagraphSdtPrAlias,
+                      m_aParagraphSdtPrPlaceHolderDocPart, 
m_aParagraphSdtPrColor, /*bPara=*/true);
     else
     {
         //These should be written out to the actual Node and not to the anchor.
         //Clear them as they will be repopulated when the node is processed.
         m_nParagraphSdtPrToken = 0;
         m_bParagraphSdtHasId = false;
-        lcl_deleteAndResetTheLists( m_pParagraphSdtPrTokenChildren, 
m_pParagraphSdtPrDataBindingAttrs, m_pParagraphSdtPrTextAttrs, 
m_aParagraphSdtPrAlias );
+        lcl_deleteAndResetTheLists(m_pParagraphSdtPrTokenChildren,
+                                   m_pParagraphSdtPrDataBindingAttrs, 
m_pParagraphSdtPrTextAttrs,
+                                   m_aParagraphSdtPrAlias, 
m_aParagraphSdtPrPlaceHolderDocPart,
+                                   m_aParagraphSdtPrColor);
     }
 
     m_pSerializer->mark(Tag_StartParagraph_2);
@@ -849,9 +859,11 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& 
nSdtPrToken,
                                          
rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrDataBindingAttrs,
                                          
rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTextAttrs,
                                          OUString& rSdtPrAlias,
+                                         OUString& rSdtPrPlaceholderDocPart,
+                                         OUString& rColor,
                                          bool bPara )
 {
-    if( nSdtPrToken <= 0 && !pSdtPrDataBindingAttrs.is() )
+    if( nSdtPrToken <= 0 && !pSdtPrDataBindingAttrs.is() && 
!m_bParagraphSdtHasId)
         return;
 
     // sdt start mark
@@ -908,6 +920,17 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& 
nSdtPrToken,
         m_pSerializer->singleElementNS(XML_w, XML_text, xAttrList);
     }
 
+    if (!rSdtPrPlaceholderDocPart.isEmpty())
+    {
+        m_pSerializer->startElementNS(XML_w, XML_placeholder);
+        m_pSerializer->singleElementNS(XML_w, XML_docPart, FSNS(XML_w, 
XML_val), rSdtPrPlaceholderDocPart);
+        m_pSerializer->endElementNS(XML_w, XML_placeholder);
+    }
+    if (!rColor.isEmpty())
+    {
+        m_pSerializer->singleElementNS(XML_w15, XML_color, FSNS(XML_w, 
XML_val), rColor);
+    }
+
     if (!rSdtPrAlias.isEmpty())
         m_pSerializer->singleElementNS(XML_w, XML_alias, FSNS(XML_w, XML_val), 
rSdtPrAlias);
 
@@ -938,7 +961,7 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& 
nSdtPrToken,
     pSdtPrDataBindingAttrs.clear();
     pSdtPrTextAttrs.clear();
     rSdtPrAlias.clear();
-
+    m_bParagraphSdtHasId = false;
 }
 
 void DocxAttributeOutput::EndSdtBlock()
@@ -1616,14 +1639,18 @@ void DocxAttributeOutput::EndRun(const SwTextNode* 
pNode, sal_Int32 nPos, bool /
     if ( !m_bAnchorLinkedToNode && !m_bStartedCharSdt )
     {
         rtl::Reference<sax_fastparser::FastAttributeList> 
pRunSdtPrTokenAttributes;
-        WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, 
pRunSdtPrTokenAttributes, m_pRunSdtPrDataBindingAttrs, m_pRunSdtPrTextAttrs, 
m_aRunSdtPrAlias, /*bPara=*/false );
+        WriteSdtBlock(m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, 
pRunSdtPrTokenAttributes,
+                      m_pRunSdtPrDataBindingAttrs, m_pRunSdtPrTextAttrs, 
m_aRunSdtPrAlias,
+                      m_aRunSdtPrPlaceHolderDocPart, m_aRunSdtPrColor, 
/*bPara=*/false);
     }
     else
     {
         //These should be written out to the actual Node and not to the anchor.
         //Clear them as they will be repopulated when the node is processed.
         m_nRunSdtPrToken = 0;
-        lcl_deleteAndResetTheLists( m_pRunSdtPrTokenChildren, 
m_pRunSdtPrDataBindingAttrs, m_pRunSdtPrTextAttrs, m_aRunSdtPrAlias );
+        lcl_deleteAndResetTheLists(m_pRunSdtPrTokenChildren, 
m_pRunSdtPrDataBindingAttrs,
+                                   m_pRunSdtPrTextAttrs, m_aRunSdtPrAlias,
+                                   m_aRunSdtPrPlaceHolderDocPart, 
m_aRunSdtPrColor);
     }
 
     if (bCloseEarlierSDT)
@@ -9836,7 +9863,7 @@ void DocxAttributeOutput::ParaGrabBag(const 
SfxGrabBagItem& rItem)
                         for (const auto& rProp : std::as_const(aGrabBag))
                         {
                             OUString sValue = rProp.Value.get<OUString>();
-                            if (rProp.Name == "ooxml:LN_CT_SdtText_multiLine")
+                            if (rProp.Name == "ooxml:CT_SdtText_multiLine")
                                 AddToAttrList(m_pParagraphSdtPrTextAttrs,
                                     FSNS(XML_w, XML_multiLine),
                                     OUStringToOString(sValue, 
RTL_TEXTENCODING_UTF8).getStr());
@@ -9869,6 +9896,28 @@ void DocxAttributeOutput::ParaGrabBag(const 
SfxGrabBagItem& rItem)
                                            OUStringToOString( sValue, 
RTL_TEXTENCODING_UTF8 ).getStr() );
                     }
                 }
+                else if (aPropertyValue.Name == 
"ooxml:CT_SdtPlaceholder_docPart")
+                {
+                    uno::Sequence<beans::PropertyValue> aGrabBag;
+                    aPropertyValue.Value >>= aGrabBag;
+                    for (const auto& rProp : std::as_const(aGrabBag))
+                    {
+                        OUString sValue = rProp.Value.get<OUString>();
+                        if (rProp.Name == 
"ooxml:CT_SdtPlaceholder_docPart_val")
+                            m_aParagraphSdtPrPlaceHolderDocPart = sValue;
+                    }
+                }
+                else if (aPropertyValue.Name == "ooxml:CT_SdtPr_color")
+                {
+                    uno::Sequence<beans::PropertyValue> aGrabBag;
+                    aPropertyValue.Value >>= aGrabBag;
+                    for (const auto& rProp : std::as_const(aGrabBag))
+                    {
+                        OUString sValue = rProp.Value.get<OUString>();
+                        if (rProp.Name == "ooxml:CT_SdtColor_val")
+                            m_aParagraphSdtPrColor = sValue;
+                    }
+                }
                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && 
m_aParagraphSdtPrAlias.isEmpty())
                 {
                     if (!(aPropertyValue.Value >>= m_aParagraphSdtPrAlias))
@@ -10070,7 +10119,7 @@ void DocxAttributeOutput::CharGrabBag( const 
SfxGrabBagItem& rItem )
                     for (const auto& rProp : std::as_const(aGrabBag))
                     {
                         OUString sValue = rProp.Value.get<OUString>();
-                        if (rProp.Name == "ooxml:LN_CT_SdtText_multiLine")
+                        if (rProp.Name == "ooxml:CT_SdtText_multiLine")
                             AddToAttrList(m_pRunSdtPrTextAttrs,
                                 FSNS(XML_w, XML_multiLine),
                                 OUStringToOString(sValue, 
RTL_TEXTENCODING_UTF8).getStr());
@@ -10097,6 +10146,28 @@ void DocxAttributeOutput::CharGrabBag( const 
SfxGrabBagItem& rItem )
                                            OUStringToOString( sValue, 
RTL_TEXTENCODING_UTF8 ).getStr() );
                     }
                 }
+                else if (aPropertyValue.Name == 
"ooxml:CT_SdtPlaceholder_docPart")
+                {
+                    uno::Sequence<beans::PropertyValue> aGrabBag;
+                    aPropertyValue.Value >>= aGrabBag;
+                    for (const auto& rProp : std::as_const(aGrabBag))
+                    {
+                        OUString sValue = rProp.Value.get<OUString>();
+                        if (rProp.Name == 
"ooxml:CT_SdtPlaceholder_docPart_val")
+                            m_aRunSdtPrPlaceHolderDocPart = sValue;
+                    }
+                }
+                else if (aPropertyValue.Name == "ooxml:CT_SdtPr_color")
+                {
+                    uno::Sequence<beans::PropertyValue> aGrabBag;
+                    aPropertyValue.Value >>= aGrabBag;
+                    for (const auto& rProp : std::as_const(aGrabBag))
+                    {
+                        OUString sValue = rProp.Value.get<OUString>();
+                        if (rProp.Name == "ooxml:CT_SdtColor_val")
+                            m_aRunSdtPrColor = sValue;
+                    }
+                }
                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && 
m_aRunSdtPrAlias.isEmpty())
                 {
                     if (!(aPropertyValue.Value >>= m_aRunSdtPrAlias))
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 8843eb01ca4e..967e42e54e77 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -726,6 +726,8 @@ private:
                        rtl::Reference<sax_fastparser::FastAttributeList>& 
pSdtPrDataBindingAttrs,
                        rtl::Reference<sax_fastparser::FastAttributeList>& 
pSdtPrTextAttrs,
                        OUString& rSdtPrAlias,
+                       OUString& rSdtPrPlaceholderDocPart,
+                       OUString& rColor,
                        bool bPara);
     /// Closes a currently open SDT block.
     void EndSdtBlock();
@@ -1006,9 +1008,13 @@ private:
     rtl::Reference<sax_fastparser::FastAttributeList> m_pRunSdtPrTextAttrs;
     /// Value of the <w:alias> paragraph SDT element.
     OUString m_aParagraphSdtPrAlias;
+    OUString m_aParagraphSdtPrPlaceHolderDocPart;
+    OUString m_aParagraphSdtPrColor;
     /// Same as m_aParagraphSdtPrAlias, but its content is available till the 
SDT is closed.
     OUString m_aStartedParagraphSdtPrAlias;
     OUString m_aRunSdtPrAlias;
+    OUString m_aRunSdtPrPlaceHolderDocPart;
+    OUString m_aRunSdtPrColor;
     /// Currently paragraph SDT has a <w:id> child element.
     bool m_bParagraphSdtHasId;
 
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index a1ead25a3b7e..3d5fc3fe679a 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1769,7 +1769,8 @@ rtl::Reference<FastAttributeList> 
DocxExport::MainXmlNamespaces()
     pAttr->add( FSNS( XML_xmlns, XML_mc ), 
OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(mce)), 
RTL_TEXTENCODING_UTF8) );
     pAttr->add( FSNS( XML_xmlns, XML_wp14 ), 
OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(wp14)), 
RTL_TEXTENCODING_UTF8) );
     pAttr->add( FSNS( XML_xmlns, XML_w14 ), 
OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(w14)), 
RTL_TEXTENCODING_UTF8) );
-    pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14" );
+    pAttr->add( FSNS( XML_xmlns, XML_w15 ), 
OUStringToOString(m_rFilter.getNamespaceURL(OOX_NS(w15)), 
RTL_TEXTENCODING_UTF8));
+    pAttr->add( FSNS( XML_mc, XML_Ignorable ), "w14 wp14 w15" );
     return pAttr;
 }
 
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 6001d49d2117..0383abb708aa 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1133,8 +1133,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         case NS_ooxml::LN_CT_DataBinding_storeItemID:
             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_DataBinding_storeItemID", sStringValue);
             break;
+        case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val:
+            m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_SdtPlaceholder_docPart_val", sStringValue);
+            break;
+        case NS_ooxml::LN_CT_SdtColor_val:
+            m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_SdtColor_val", sStringValue);
+            break;
         case NS_ooxml::LN_CT_SdtText_multiLine:
-            m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:LN_CT_SdtText_multiLine", sStringValue);
+            m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_SdtText_multiLine", sStringValue);
             break;
         case NS_ooxml::LN_CT_PTab_leader:
         case NS_ooxml::LN_CT_PTab_relativeTo:
@@ -2645,6 +2651,14 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
             pProperties->resolve(*this);
     }
     break;
+    case NS_ooxml::LN_CT_SdtPr_placeholder:
+    {
+        writerfilter::Reference<Properties>::Pointer_t pProperties = 
rSprm.getProps();
+        if (pProperties)
+            pProperties->resolve(*this);
+    }
+    break;
+    break;
     case NS_ooxml::LN_CT_SdtPr_date:
     {
         resolveSprmProps(*this, rSprm);
@@ -2680,6 +2694,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
     case NS_ooxml::LN_CT_SdtPr_text:
     case NS_ooxml::LN_CT_SdtPr_id:
     case NS_ooxml::LN_CT_SdtPr_alias:
+    case NS_ooxml::LN_CT_SdtPlaceholder_docPart:
+    case NS_ooxml::LN_CT_SdtPr_color:
     {
         // this is an unsupported SDT property, create a grab bag for it
         OUString sName;
@@ -2696,6 +2712,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
             case NS_ooxml::LN_CT_SdtPr_text:        sName = 
"ooxml:CT_SdtPr_text"; break;
             case NS_ooxml::LN_CT_SdtPr_id:          sName = 
"ooxml:CT_SdtPr_id"; break;
             case NS_ooxml::LN_CT_SdtPr_alias:       sName = 
"ooxml:CT_SdtPr_alias"; break;
+            case NS_ooxml::LN_CT_SdtPlaceholder_docPart: sName = 
"ooxml:CT_SdtPlaceholder_docPart"; break;
+            case NS_ooxml::LN_CT_SdtPr_color:       sName = 
"ooxml:CT_SdtPr_color"; break;
             default: assert(false);
         };
         enableInteropGrabBag(sName);
diff --git a/writerfilter/source/ooxml/model.xml 
b/writerfilter/source/ooxml/model.xml
index a84d1e0caec5..56767f526356 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -13914,9 +13914,14 @@
           <data type="string"/>
         </attribute>
       </define>
-      <define name="CT_Placeholder">
+      <define name="CT_SdtPlaceholderDocPart">
+        <attribute name="val">
+          <data type="string"/>
+        </attribute>
+      </define>
+      <define name="CT_SdtPlaceholder">
         <element name="docPart">
-          <ref name="CT_String"/>
+          <ref name="CT_SdtPlaceholderDocPart"/>
         </element>
       </define>
       <define name="CT_SdtText">
@@ -13935,6 +13940,11 @@
           <data type="string"/>
         </attribute>
       </define>
+      <define name="CT_SdtColor">
+        <attribute name="val">
+          <data type="string"/>
+        </attribute>
+      </define>
       <define name="CT_SdtPr">
         <choice>
           <element name="rPr">
@@ -13947,7 +13957,7 @@
             <ref name="CT_Lock"/>
           </element>
           <element name="placeholder">
-            <ref name="CT_Placeholder"/>
+            <ref name="CT_SdtPlaceholder"/>
           </element>
           <element name="showingPlcHdr">
             <ref name="CT_OnOff"/>
@@ -14003,6 +14013,9 @@
           <element name="bibliography">
             <ref name="CT_Empty"/>
           </element>
+          <element name="w15:color">
+            <ref name="CT_SdtColor"/>
+          </element>
         </choice>
       </define>
       <define name="CT_SdtEndPr">
@@ -18235,11 +18248,17 @@
     <resource name="CT_SdtText" resource="Properties">
       <attribute name="multiLine" tokenid="ooxml:CT_SdtText_multiLine"/>
     </resource>
+    <resource name="CT_SdtPlaceholder" resource="Properties">
+      <attribute name="docPart" tokenid="ooxml:CT_SdtPlaceholder_docPart"/>
+    </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 name="CT_SdtColor" resource="Properties">
+      <attribute name="val" tokenid="ooxml:CT_SdtColor_val"/>
+    </resource>
     <resource name="CT_SdtPr" resource="Properties">
       <element name="rPr" tokenid="ooxml:CT_SdtPr_rPr"/>
       <element name="alias" tokenid="ooxml:CT_SdtPr_alias"/>
@@ -18263,6 +18282,7 @@
       <element name="citation" tokenid="ooxml:CT_SdtPr_citation"/>
       <element name="group" tokenid="ooxml:CT_SdtPr_group"/>
       <element name="bibliography" tokenid="ooxml:CT_SdtPr_bibliography"/>
+      <element name="w15:color" tokenid="ooxml:CT_SdtPr_color"/>
     </resource>
     <resource name="CT_SdtEndPr" resource="Properties">
       <element name="rPr" tokenid="ooxml:CT_SdtEndPr_rPr"/>
@@ -18327,6 +18347,9 @@
       <attribute name="displayText" 
tokenid="ooxml:CT_SdtListItem_displayText"/>
       <attribute name="value" tokenid="ooxml:CT_SdtListItem_value"/>
     </resource>
+    <resource name="CT_SdtPlaceholderDocPart" resource="Properties">
+      <attribute name="val" tokenid="ooxml:CT_SdtPlaceholder_docPart_val"/>
+    </resource>
     <resource name="CT_Attr" resource="Properties">
       <attribute name="uri" tokenid="ooxml:CT_Attr_uri"/>
       <attribute name="name" tokenid="ooxml:CT_Attr_name"/>

Reply via email to