sw/qa/extras/ooxmlexport/data/test_sdt_datepicker.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx          |   25 ++++
 sw/source/filter/ww8/docxattributeoutput.cxx           |   62 +++++++----
 sw/source/filter/ww8/docxattributeoutput.hxx           |    3 
 writerfilter/source/dmapper/DomainMapper.cxx           |   90 ++++++++---------
 writerfilter/source/dmapper/SdtHelper.cxx              |   16 +--
 writerfilter/source/dmapper/SdtHelper.hxx              |   33 ++++--
 7 files changed, 146 insertions(+), 83 deletions(-)

New commits:
commit 2a57cd4e01b5fba00f210b792d1fcf0acb9c69fb
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Thu Nov 18 20:06:08 2021 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Dec 9 09:48:42 2021 +0100

    sw: support for other sdt attributes roundtrip in datepicker
    
    Word Control Field with datepicker is implemented with LO datepicker,
    but during this conversion we lose some field data, like control
    color, data mapping, etc. This data is already retrieved and stored
    in grab bag, so we need just to keep this grabbag in field and use
    it again on export.
    
    Change-Id: I6af8204fe1a7d2f9081d83372a6786b2f86260d8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125486
    Tested-by: Jenkins
    Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126280

diff --git a/sw/qa/extras/ooxmlexport/data/test_sdt_datepicker.docx 
b/sw/qa/extras/ooxmlexport/data/test_sdt_datepicker.docx
new file mode 100644
index 000000000000..3ff04cb60b89
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/test_sdt_datepicker.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 658830274534..8354b5b669de 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -718,6 +718,31 @@ DECLARE_OOXMLEXPORT_TEST(testTdf142464_ampm, 
"tdf142464_ampm.docx")
     }
 }
 
+DECLARE_OOXMLEXPORT_TEST( testSdtDatePicker, "test_sdt_datepicker.docx" )
+{
+    // Check that roundtrip for date picker field does not lose essential data
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    if (!pXmlDoc)
+       return; // initial import, no futher checks
+
+    // Placeholder is here
+    OUString sDocPart = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:sdt/w:sdtPr/w:placeholder/w:docPart", "val");
+    CPPUNIT_ASSERT_EQUAL(OUString("DefaultPlaceholder_-1854013437"), sDocPart);
+
+    // Ensure that we have data binding stuff
+    OUString sDBprefix = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "prefixMappings");
+    
CPPUNIT_ASSERT_EQUAL(OUString("xmlns:ns0='http://schemas.microsoft.com/vsto/samples'
 "), sDBprefix);
+
+    OUString sDBxpath = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "xpath");
+    
CPPUNIT_ASSERT_EQUAL(OUString("/ns0:employees[1]/ns0:employee[1]/ns0:hireDate[1]"),
 sDBxpath);
+
+    OUString sDBstoreid = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "storeItemID");
+    CPPUNIT_ASSERT_EQUAL(OUString("{241A8A02-7FFD-488D-8827-63FBE74E8BC9}"), 
sDBstoreid);
+
+    OUString sColor = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:sdt/w:sdtPr/w15:color", "val");
+    CPPUNIT_ASSERT_EQUAL(OUString("008000"), sColor);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 71fa753bd44c..51a8ac155cad 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -663,12 +663,36 @@ void 
SdtBlockHelper::WriteSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer, b
         }
     }
 
+    WriteExtraParams(pSerializer);
+
+    pSerializer->endElementNS(XML_w, XML_sdtPr);
+
+    // sdt contents start tag
+    pSerializer->startElementNS(XML_w, XML_sdtContent);
+
+    // prepend the tags since the sdt start mark before the paragraph
+    pSerializer->mergeTopMarks(Tag_WriteSdtBlock, 
sax_fastparser::MergeMarks::PREPEND);
+
+    // write the ending tags after the paragraph
+    m_bStartedSdt = true;
+
+    // clear sdt status
+    m_nSdtPrToken = 0;
+    m_pTokenChildren.clear();
+    m_pDataBindingAttrs.clear();
+    m_pTextAttrs.clear();
+    m_aAlias.clear();
+    m_bHasId = false;
+}
+
+void SdtBlockHelper::WriteExtraParams(::sax_fastparser::FSHelperPtr& 
pSerializer)
+{
     if (m_nSdtPrToken == FSNS(XML_w, XML_id) || m_bHasId)
         //Word won't open a document with an empty id tag, we fill it with a 
random number
         pSerializer->singleElementNS(XML_w, XML_id, FSNS(XML_w, XML_val),
             OString::number(comphelper::rng::uniform_int_distribution(0, 
std::numeric_limits<int>::max())));
 
-    if (m_pDataBindingAttrs.is() && !bParagraphHasDrawing)
+    if (m_pDataBindingAttrs.is())
     {
         rtl::Reference<FastAttributeList> xAttrList = 
std::move(m_pDataBindingAttrs);
         pSerializer->singleElementNS(XML_w, XML_dataBinding, xAttrList);
@@ -693,25 +717,6 @@ void 
SdtBlockHelper::WriteSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer, b
 
     if (!m_aAlias.isEmpty())
         pSerializer->singleElementNS(XML_w, XML_alias, FSNS(XML_w, XML_val), 
m_aAlias);
-
-    pSerializer->endElementNS(XML_w, XML_sdtPr);
-
-    // sdt contents start tag
-    pSerializer->startElementNS(XML_w, XML_sdtContent);
-
-    // prepend the tags since the sdt start mark before the paragraph
-    pSerializer->mergeTopMarks(Tag_WriteSdtBlock, 
sax_fastparser::MergeMarks::PREPEND);
-
-    // write the ending tags after the paragraph
-    m_bStartedSdt = true;
-
-    // clear sdt status
-    m_nSdtPrToken = 0;
-    m_pTokenChildren.clear();
-    m_pDataBindingAttrs.clear();
-    m_pTextAttrs.clear();
-    m_aAlias.clear();
-    m_bHasId = false;
 }
 
 void SdtBlockHelper::EndSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer)
@@ -2152,7 +2157,7 @@ void DocxAttributeOutput::WriteFFData(  const FieldInfos& 
rInfos )
     }
 }
 
-void DocxAttributeOutput::WriteFormDateStart(const OUString& sFullDate, const 
OUString& sDateFormat, const OUString& sLang)
+void DocxAttributeOutput::WriteFormDateStart(const OUString& sFullDate, const 
OUString& sDateFormat, const OUString& sLang, const 
uno::Sequence<beans::PropertyValue>& aGrabBagSdt)
 {
     m_pSerializer->startElementNS(XML_w, XML_sdt);
     m_pSerializer->startElementNS(XML_w, XML_sdtPr);
@@ -2172,8 +2177,16 @@ void DocxAttributeOutput::WriteFormDateStart(const 
OUString& sFullDate, const OU
                                    FSNS(XML_w, XML_val), "dateTime");
     m_pSerializer->singleElementNS(XML_w, XML_calendar,
                                    FSNS(XML_w, XML_val), "gregorian");
-
     m_pSerializer->endElementNS(XML_w, XML_date);
+
+    if (aGrabBagSdt.hasElements())
+    {
+        // There are some extra sdt parameters came from grab bag
+        SdtBlockHelper aSdtBlock;
+        aSdtBlock.GetSdtParamsFromGrabBag(aGrabBagSdt);
+        aSdtBlock.WriteExtraParams(m_pSerializer);
+    }
+
     m_pSerializer->endElementNS(XML_w, XML_sdtPr);
 
     m_pSerializer->startElementNS(XML_w, XML_sdtContent);
@@ -2276,7 +2289,10 @@ void DocxAttributeOutput::StartField_Impl( const 
SwTextNode* pNode, sal_Int32 nP
         OUString sLang;
         params.extractParam( ODF_FORMDATE_DATEFORMAT_LANGUAGE, sLang );
 
-        WriteFormDateStart( sFullDate, sDateFormat, sLang );
+        uno::Sequence<beans::PropertyValue> aSdtParams;
+        params.extractParam("SdtParams", aSdtParams);
+
+        WriteFormDateStart( sFullDate, sDateFormat, sLang, aSdtParams);
     }
     else if (rInfos.eType == ww::eFORMDROPDOWN && rInfos.pField)
     {
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 595b30e7329b..3897073ffe1f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -144,6 +144,7 @@ public:
     void DeleteAndResetTheLists();
 
     void WriteSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer, bool 
bRunTextIsOn, bool bParagraphHasDrawing);
+    void WriteExtraParams(::sax_fastparser::FSHelperPtr& pSerializer);
 
     /// Closes a currently open SDT block.
     void EndSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer);
@@ -750,7 +751,7 @@ private:
     void WritePostponedCustomShape();
     void WriteFlyFrame(const ww8::Frame& rFrame);
 
-    void WriteFormDateStart(const OUString& sFullDate, const OUString& 
sDateFormat, const OUString& sLang);
+    void WriteFormDateStart(const OUString& sFullDate, const OUString& 
sDateFormat, const OUString& sLang, const uno::Sequence<beans::PropertyValue>& 
aGrabBagSdt);
     void WriteSdtDropDownStart(std::u16string_view rName, OUString const& 
rSelected, uno::Sequence<OUString> const& rListItems);
     void WriteSdtDropDownEnd(OUString const& rSelected, 
uno::Sequence<OUString> const& rListItems);
     void WriteSdtEnd();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index ea16e51e0f9f..b247e0156b38 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1132,12 +1132,15 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         }
         break;
         case NS_ooxml::LN_CT_DataBinding_prefixMappings:
+            m_pImpl->m_pSdtHelper->setDataBindingPrefixMapping(sStringValue);
             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_DataBinding_prefixMappings", sStringValue);
             break;
         case NS_ooxml::LN_CT_DataBinding_xpath:
+            m_pImpl->m_pSdtHelper->setDataBindingXPath(sStringValue);
             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_DataBinding_xpath", sStringValue);
             break;
         case NS_ooxml::LN_CT_DataBinding_storeItemID:
+            m_pImpl->m_pSdtHelper->setDataBindingStoreItemID(sStringValue);
             m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, 
"ooxml:CT_DataBinding_storeItemID", sStringValue);
             break;
         case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val:
@@ -3539,11 +3542,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
     }
     else if (m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::datePicker)
     {
-        if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
-        {
-            m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
-        }
-        else if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
+        if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
         {
             m_pImpl->m_pSdtHelper->getDateFormat().truncate();
             m_pImpl->m_pSdtHelper->getLocale().truncate();
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx 
b/writerfilter/source/dmapper/SdtHelper.cxx
index 46f834280404..5466baec8fc1 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -196,6 +196,9 @@ void SdtHelper::createDateContentControl()
     }
 
     setControlType(SdtControlType::unknown);
+
+    // Store all unused sdt parameters from grabbag
+    xNameCont->insertByName("SdtParams", 
uno::makeAny(getInteropGrabBagAndClear()));
 }
 
 void SdtHelper::createControlShape(awt::Size aSize,
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx 
b/writerfilter/source/dmapper/SdtHelper.hxx
index 5a39177c4a56..9d31e1621504 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -54,6 +54,14 @@ class SdtHelper final : public virtual SvRefBase
     OUStringBuffer m_sDate;
     /// Date format string as it comes from the ooxml document.
     OUStringBuffer m_sDateFormat;
+
+    /// <w:dataBinding w:prefixMappings="">
+    OUString m_sDataBindingPrefixMapping;
+    /// <w:dataBinding w:xpath="">
+    OUString m_sDataBindingXPath;
+    /// <w:dataBinding w:storeItemID="">
+    OUString m_sDataBindingStoreItemID;
+
     /// Start range of the date field
     css::uno::Reference<css::text::XTextRange> m_xDateFieldStartRange;
     /// Locale string as it comes from the ooxml document.
@@ -81,6 +89,13 @@ public:
 
     OUStringBuffer& getDateFormat() { return m_sDateFormat; }
 
+    void setDataBindingPrefixMapping(const OUString& sValue)
+    {
+        m_sDataBindingPrefixMapping = sValue;
+    }
+    void setDataBindingXPath(const OUString& sValue) { m_sDataBindingXPath = 
sValue; }
+    void setDataBindingStoreItemID(const OUString& sValue) { 
m_sDataBindingStoreItemID = sValue; }
+
     void setDateFieldStartRange(const 
css::uno::Reference<css::text::XTextRange>& xStartRange)
     {
         m_xDateFieldStartRange = xStartRange;
commit 9ac193fd3cc1f66aeedaa64a09642c4fcc4c62e0
Author:     Vasily Melenchuk <vasily.melenc...@cib.de>
AuthorDate: Thu Nov 18 15:04:00 2021 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Dec 9 09:48:28 2021 +0100

    writerfilter: extend SdtHelper for better support control types
    
    There is much more different controls which must be supprorted
    in future. So approach with isInsideDropDownControl() and
    validateDateFormat() is not sufficient. Use enum to determine
    and store control type.
    
    Change-Id: Ibea7fde117c059053195be213a3ae821644f277c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125471
    Tested-by: Jenkins
    Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126279

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 0383abb708aa..ea16e51e0f9f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1078,10 +1078,17 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             else
                 m_pImpl->setSdtEndDeferred(true);
 
-            if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
-                m_pImpl->m_pSdtHelper->createDropDownControl();
-            else if (m_pImpl->m_pSdtHelper->validateDateFormat())
-                m_pImpl->m_pSdtHelper->createDateContentControl();
+            switch (m_pImpl->m_pSdtHelper->getControlType())
+            {
+                case SdtControlType::dropDown:
+                    m_pImpl->m_pSdtHelper->createDropDownControl();
+                    break;
+                case SdtControlType::datePicker:
+                    m_pImpl->m_pSdtHelper->createDateContentControl();
+                    break;
+                case SdtControlType::unknown:
+                default:;
+            }
         break;
         case NS_ooxml::LN_CT_SdtListItem_displayText:
             // TODO handle when this is != value
@@ -2638,7 +2645,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
     case NS_ooxml::LN_CT_SdtPr_dropDownList:
     case NS_ooxml::LN_CT_SdtPr_comboBox:
     {
-        m_pImpl->m_pSdtHelper->setInsideDropDownControl(true);
+        m_pImpl->m_pSdtHelper->setControlType(SdtControlType::dropDown);
         writerfilter::Reference<Properties>::Pointer_t pProperties = 
rSprm.getProps();
         if (pProperties)
             pProperties->resolve(*this);
@@ -2661,6 +2668,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
     break;
     case NS_ooxml::LN_CT_SdtPr_date:
     {
+        m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker);
         resolveSprmProps(*this, rSprm);
         
m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd());
     }
@@ -3518,7 +3526,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
     }
 
     bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07);
-    if (m_pImpl->m_pSdtHelper->isInsideDropDownControl())
+    if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::dropDown)
     {
         if (bNewLine)
             // Dropdown control has single-line texts, so in case of newline, 
create the control.
@@ -3529,43 +3537,47 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
             return;
         }
     }
+    else if (m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::datePicker)
+    {
+        if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
+        {
+            m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
+        }
+        else if (IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
+        {
+            m_pImpl->m_pSdtHelper->getDateFormat().truncate();
+            m_pImpl->m_pSdtHelper->getLocale().truncate();
+            return;
+        }
+    }
     else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty())
     {
-         // Ignore grabbag when we have a date field, it can conflict during 
export
-        if(m_pImpl->m_pSdtHelper->validateDateFormat())
+        // there are unsupported SDT properties in the document
+        // save them in the paragraph interop grab bag
+        if (m_pImpl->IsDiscardHeaderFooter())
         {
+            // Unless we're supposed to ignore this header/footer.
             m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
+            return;
         }
-        else
+        
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_citation") ||
+                
(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
+                        m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) 
&& !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
         {
+            PropertyMapPtr pContext = 
m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
 
-            // there are unsupported SDT properties in the document
-            // save them in the paragraph interop grab bag
-            if (m_pImpl->IsDiscardHeaderFooter())
-            {
-                // Unless we're supposed to ignore this header/footer.
-                m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
-                return;
-            }
-            
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_citation") ||
-                    
(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
-                            m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 
1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
-            {
-                PropertyMapPtr pContext = 
m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
-
-                if (m_pImpl->IsOpenField())
-                    // We have a field, insert the SDT properties to the 
field's grab-bag, so they won't be lost.
-                    pContext = m_pImpl->GetTopFieldContext()->getProperties();
+            if (m_pImpl->IsOpenField())
+                // We have a field, insert the SDT properties to the field's 
grab-bag, so they won't be lost.
+                pContext = m_pImpl->GetTopFieldContext()->getProperties();
 
-                pContext->Insert(PROP_SDTPR, 
uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, 
CHAR_GRAB_BAG);
-            }
-            else
-                
m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
-                        
uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, 
PARA_GRAB_BAG);
+            pContext->Insert(PROP_SDTPR, 
uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, 
CHAR_GRAB_BAG);
         }
+        else
+            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)
     {
@@ -3591,15 +3603,6 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
             return;
         }
     }
-    else if (m_pImpl->m_pSdtHelper->validateDateFormat())
-    {
-        if(IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter())
-        {
-            m_pImpl->m_pSdtHelper->getDateFormat().truncate();
-            m_pImpl->m_pSdtHelper->getLocale().truncate();
-            return;
-        }
-    }
     if (!m_pImpl->hasTableManager())
         return;
 
@@ -4186,7 +4189,7 @@ void DomainMapper::HandleRedline( Sprm& rSprm )
 
 void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering)
 {
-    if (m_pImpl->m_pSdtHelper->validateDateFormat())
+    if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::datePicker)
         m_pImpl->m_pSdtHelper->createDateContentControl();
     m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), 
bRemove, bNoNumbering);
 }
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx 
b/writerfilter/source/dmapper/SdtHelper.cxx
index 7bf233446ee5..46f834280404 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -67,7 +67,7 @@ static awt::Size lcl_getOptimalWidth(const 
StyleSheetTablePtr& pStyleSheet,
 
 SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl)
     : m_rDM_Impl(rDM_Impl)
-    , m_bInsideDropDownControl(false)
+    , m_aControlType(SdtControlType::unknown)
     , m_bHasElements(false)
     , m_bOutsideAParagraph(false)
 {
@@ -77,7 +77,7 @@ SdtHelper::~SdtHelper() = default;
 
 void SdtHelper::createDropDownControl()
 {
-    assert(m_bInsideDropDownControl);
+    assert(getControlType() == SdtControlType::dropDown);
 
     const bool bDropDown
         = 
officecfg::Office::Writer::Filter::Import::DOCX::ImportComboBoxAsDropDown::get();
@@ -132,12 +132,7 @@ void SdtHelper::createDropDownControl()
 
     // clean up
     m_aDropDownItems.clear();
-    m_bInsideDropDownControl = false;
-}
-
-bool SdtHelper::validateDateFormat()
-{
-    return !m_sDateFormat.toString().isEmpty() && 
!m_sLocale.toString().isEmpty();
+    setControlType(SdtControlType::unknown);
 }
 
 void SdtHelper::createDateContentControl()
@@ -199,6 +194,8 @@ void SdtHelper::createDateContentControl()
             sFullDate = sFullDate.copy(0, nTimeSep);
         xNameCont->insertByName(ODF_FORMDATE_CURRENTDATE, 
uno::makeAny(sFullDate));
     }
+
+    setControlType(SdtControlType::unknown);
 }
 
 void SdtHelper::createControlShape(awt::Size aSize,
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx 
b/writerfilter/source/dmapper/SdtHelper.hxx
index 13859aab0f2c..5a39177c4a56 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -27,6 +27,13 @@ namespace writerfilter::dmapper
 {
 class DomainMapper_Impl;
 
+enum class SdtControlType
+{
+    datePicker,
+    dropDown,
+    unknown
+};
+
 /**
  * Helper to create form controls from w:sdt tokens.
  *
@@ -39,8 +46,8 @@ class SdtHelper final : public virtual SvRefBase
 
     /// Items of the drop-down control.
     std::vector<OUString> m_aDropDownItems;
-    /// Indicator of a drop-down control
-    bool m_bInsideDropDownControl;
+    /// Type of sdt control
+    SdtControlType m_aControlType;
     /// Pieces of the default text -- currently used only by the dropdown 
control.
     OUStringBuffer m_aSdtTexts;
     /// Date ISO string contained in the w:date element, used by the date 
control.
@@ -79,9 +86,6 @@ public:
         m_xDateFieldStartRange = xStartRange;
     }
 
-    /// Decides if we have enough information to create a date control.
-    bool validateDateFormat();
-
     OUStringBuffer& getLocale() { return m_sLocale; }
     /// If createControlShape() was ever called.
     bool hasElements() const { return m_bHasElements; }
@@ -93,8 +97,8 @@ public:
 
     bool isOutsideAParagraph() const { return m_bOutsideAParagraph; }
 
-    bool isInsideDropDownControl() const { return m_bInsideDropDownControl; }
-    void setInsideDropDownControl(bool bInside) { m_bInsideDropDownControl = 
bInside; }
+    SdtControlType getControlType() { return m_aControlType; }
+    void setControlType(SdtControlType aType) { m_aControlType = aType; }
 
     /// Create drop-down control from w:sdt's w:dropDownList.
     void createDropDownControl();

Reply via email to