sw/qa/extras/ooxmlexport/ooxmlexport.cxx                        |   23 +++
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx                      |   59 
+++++-----
 sw/qa/extras/ooxmlexport/ooxmlexport8.cxx                       |   43 ++++---
 writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx              |   51 ++++++++
 writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx                    |   23 +++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx               |   20 +++
 writerfilter/source/dmapper/SdtHelper.cxx                       |    1 
 writerfilter/source/dmapper/SdtHelper.hxx                       |    5 
 9 files changed, 179 insertions(+), 46 deletions(-)

New commits:
commit 3e29a18bd30223109031306f9630e86b2bbb6543
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed May 11 08:17:32 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri May 13 13:19:56 2022 +0200

    sw content controls, drop-down: add DOCX import
    
    - inline drop-down content controls were imported as an SwDropDownField
      previously, but that has the drawback of not being able to store both
      display texts and values of each list items
    
    - adapt tests under sw/qa/ which asserted that the import result is a
      field, and check content control properties instead
    
    - change dmapper so that SdtControlType::dropDown is one more inline
      SDT that gets mapped to SwContentControl
    
    - remove the no longer needed grab-bagging in writerfilter/, otherwise
      we would write the SDT markup twice on export
    
    - improve DomainMapper_Impl::PopSdt() to actually map the collected
      dropdown properties to properties on the to-be-inserted content
      control
    
    (cherry picked from commit 24417d8c3c9e1c619936e85fa7a20481a24e3530)
    
    Conflicts:
            writerfilter/source/dmapper/DomainMapper.cxx
    
    Change-Id: I7e88ec8cd1d73bc1c6c75154d6ab07352cbcec8b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134258
    Tested-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 68efe0b86509..9d656ee676c1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -307,7 +307,7 @@ DECLARE_OOXMLEXPORT_TEST(testDropdownInCell, 
"dropdown-in-cell.docx")
         uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xCell, 
uno::UNO_QUERY);
         CPPUNIT_ASSERT_EQUAL(sal_Int16(0), 
xTextRangeCompare->compareRegionStarts(xAnchor, xCell));
     }
-    else
+    else if (!mbExported)
     {
         // ComboBox was imported as DropDown text field
         uno::Reference<text::XTextFieldsSupplier> 
xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
@@ -318,6 +318,27 @@ DECLARE_OOXMLEXPORT_TEST(testDropdownInCell, 
"dropdown-in-cell.docx")
         uno::Reference<lang::XServiceInfo> xServiceInfo(aField, 
uno::UNO_QUERY);
         
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown"));
     }
+    else
+    {
+        // DropDown text field is exported as inline SDT, we import that back 
here.
+        uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+        uno::Reference<table::XCell> xCell = xTable->getCellByName("B1");
+        uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xCell, 
uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphsAccess->createEnumeration();
+        uno::Reference<container::XEnumerationAccess> 
xParagraph(xParagraphs->nextElement(),
+                                                             uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xPortions = 
xParagraph->createEnumeration();
+        uno::Reference<beans::XPropertySet> 
xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+        OUString aPortionType;
+        xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+        CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+        uno::Reference<text::XTextContent> xContentControl;
+        xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+        uno::Reference<beans::XPropertySet> 
xContentControlProps(xContentControl, uno::UNO_QUERY);
+        uno::Sequence<beans::PropertyValues> aListItems;
+        xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+        CPPUNIT_ASSERT(aListItems.hasElements());
+    }
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTableAlignment, "table-alignment.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 609d3f7f30b6..868c09c7e191 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -606,8 +606,7 @@ DECLARE_OOXMLEXPORT_TEST(testParaAdjustDistribute, 
"para-adjust-distribute.docx"
 
 DECLARE_OOXMLEXPORT_TEST(testInputListExport, "tdf122186_input_list.odt")
 {
-    CPPUNIT_ASSERT_EQUAL(1, getPages());
-    if (!mbExported || getShapes() == 0) // importing the ODT, an input field
+    if (!mbExported) // importing the ODT, an input field
     {
         uno::Reference<text::XTextFieldsSupplier> 
xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
         uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
@@ -617,19 +616,28 @@ DECLARE_OOXMLEXPORT_TEST(testInputListExport, 
"tdf122186_input_list.odt")
         uno::Reference<lang::XServiceInfo> xServiceInfo(aField, 
uno::UNO_QUERY);
         
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown"));
     }
-    else // importing the DOCX, a form control
+    else // importing the DOCX, a content control
     {
-        uno::Reference<drawing::XControlShape> xControlShape(getShape(1), 
uno::UNO_QUERY);
-        uno::Reference<beans::XPropertySet> 
xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
-        uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, 
uno::UNO_QUERY);
-        
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.form.component.ComboBox"));
-        CPPUNIT_ASSERT(getProperty<bool>(xPropertySet, "Dropdown"));
-        auto const items(getProperty<uno::Sequence<OUString>>(xPropertySet, 
"StringItemList"));
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(3), items.getLength());
-        CPPUNIT_ASSERT_EQUAL(OUString("1"), items[0]);
-        CPPUNIT_ASSERT_EQUAL(OUString("2"), items[1]);
-        CPPUNIT_ASSERT_EQUAL(OUString("3"), items[2]);
-        CPPUNIT_ASSERT_EQUAL(OUString("1"), 
getProperty<OUString>(xPropertySet, "DefaultText"));
+        uno::Reference<beans::XPropertySet> 
xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY);
+        OUString aPortionType;
+        xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+        CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+        uno::Reference<text::XTextContent> xContentControl;
+        xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+        uno::Reference<beans::XPropertySet> 
xContentControlProps(xContentControl, uno::UNO_QUERY);
+        uno::Sequence<beans::PropertyValues> aListItems;
+        xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), 
aListItems.getLength());
+        comphelper::SequenceAsHashMap aMap0(aListItems[0]);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), aMap0["Value"].get<OUString>());
+        comphelper::SequenceAsHashMap aMap1(aListItems[1]);
+        CPPUNIT_ASSERT_EQUAL(OUString("2"), aMap1["Value"].get<OUString>());
+        comphelper::SequenceAsHashMap aMap2(aListItems[2]);
+        CPPUNIT_ASSERT_EQUAL(OUString("3"), aMap2["Value"].get<OUString>());
+        uno::Reference<container::XEnumerationAccess> 
xContentEnumAccess(xContentControl, uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xContentEnum = 
xContentEnumAccess->createEnumeration();
+        uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("1"), xContent->getString());
     }
 }
 
@@ -1129,17 +1137,18 @@ DECLARE_OOXMLEXPORT_TEST(tdf119809, "tdf119809.docx")
     }
     else
     {
-        // ComboBox was imported as DropDown text field
-        uno::Reference<text::XTextFieldsSupplier> 
xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
-        uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
-        uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
-        CPPUNIT_ASSERT(xFields->hasMoreElements());
-        uno::Any aField = xFields->nextElement();
-        uno::Reference<lang::XServiceInfo> xServiceInfo(aField, 
uno::UNO_QUERY);
-        
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown"));
-
-        uno::Sequence<OUString> aItems = getProperty< uno::Sequence<OUString> 
>(aField, "Items");
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aItems.getLength());
+        // DropDown was imported as content control
+        // First run: bookmark
+        uno::Reference<beans::XPropertySet> 
xTextPortion(getRun(getParagraph(1), 2), uno::UNO_QUERY);
+        OUString aPortionType;
+        xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+        CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+        uno::Reference<text::XTextContent> xContentControl;
+        xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+        uno::Reference<beans::XPropertySet> 
xContentControlProps(xContentControl, uno::UNO_QUERY);
+        uno::Sequence<beans::PropertyValues> aListItems;
+        xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), 
aListItems.getLength());
     }
 }
 
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index c65d279739ba..8c11e03b4dcc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -957,20 +957,35 @@ DECLARE_OOXMLEXPORT_TEST(testN779630, "n779630.docx")
     }
     else
     {
-        // ComboBox was imported as DropDown text field
-        uno::Reference<text::XTextFieldsSupplier> 
xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
-        uno::Reference<container::XEnumerationAccess> 
xFieldsAccess(xTextFieldsSupplier->getTextFields());
-        uno::Reference<container::XEnumeration> 
xFields(xFieldsAccess->createEnumeration());
-        CPPUNIT_ASSERT(xFields->hasMoreElements());
-        uno::Any aField = xFields->nextElement();
-        uno::Reference<lang::XServiceInfo> xServiceInfo(aField, 
uno::UNO_QUERY);
-        
CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown"));
-
-        uno::Sequence<OUString> aItems = getProperty< uno::Sequence<OUString> 
>(aField, "Items");
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aItems.getLength());
-        CPPUNIT_ASSERT_EQUAL(OUString("Yes"), aItems[0]);
-        CPPUNIT_ASSERT_EQUAL(OUString("No"), aItems[1]);
-        CPPUNIT_ASSERT_EQUAL(OUString("dropdown default text"), aItems[2]);
+        // Inline SDT: dropdown is imported as content control.
+        uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+        uno::Reference<container::XIndexAccess> 
xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+        uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+        uno::Reference<table::XCell> xCell = xTable->getCellByName("B1");
+        uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xCell, 
uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphsAccess->createEnumeration();
+        uno::Reference<container::XEnumerationAccess> 
xParagraph(xParagraphs->nextElement(),
+                                                             uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xPortions = 
xParagraph->createEnumeration();
+        // Label:
+        xPortions->nextElement();
+        // Space:
+        xPortions->nextElement();
+        // Default text:
+        uno::Reference<beans::XPropertySet> 
xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
+        OUString aPortionType;
+        xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+        CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+        uno::Reference<text::XTextContent> xContentControl;
+        xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+        uno::Reference<beans::XPropertySet> 
xContentControlProps(xContentControl, uno::UNO_QUERY);
+        uno::Sequence<beans::PropertyValues> aListItems;
+        xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), 
aListItems.getLength());
+        uno::Reference<container::XEnumerationAccess> 
xContentEnumAccess(xContentControl, uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xContentEnum = 
xContentEnumAccess->createEnumeration();
+        uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(OUString("dropdown default text"), 
xContent->getString());
     }
 }
 
diff --git a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx 
b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
index c96cb604f91f..633355c79a5f 100644
--- a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
@@ -10,7 +10,10 @@
 #include <test/bootstrapfixture.hxx>
 #include <unotest/macros_test.hxx>
 
+#include <comphelper/sequenceashashmap.hxx>
+
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 
@@ -130,6 +133,54 @@ CPPUNIT_TEST_FIXTURE(Test, testSdtRunCheckbox)
     uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString(u"☒"), xContent->getString());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunDropdown)
+{
+    // Given a document with a dropdown inline/run SDT:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"sdt-run-dropdown.docx";
+
+    // When loading the document:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure that the doc model has a clickable dropdown content 
control:
+    uno::Reference<text::XTextDocument> xTextDocument(getComponent(), 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xParagraphsAccess(xTextDocument->getText(),
+                                                                    
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphsAccess->createEnumeration();
+    uno::Reference<container::XEnumerationAccess> 
xParagraph(xParagraphs->nextElement(),
+                                                             uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xPortions = 
xParagraph->createEnumeration();
+    uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), 
uno::UNO_QUERY);
+    OUString aPortionType;
+    xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
+    // Without the accompanying fix in place, this failed with:
+    // - Expected: ContentControl
+    // - Actual  : TextField
+    // i.e. the SDT was imported as a dropdown field, which does not support 
display-text + value
+    // pairs.
+    CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType);
+    uno::Reference<text::XTextContent> xContentControl;
+    xTextPortion->getPropertyValue("ContentControl") >>= xContentControl;
+    uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, 
uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValues> aListItems;
+    xContentControlProps->getPropertyValue("ListItems") >>= aListItems;
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), aListItems.getLength());
+    comphelper::SequenceAsHashMap aMap0(aListItems[0]);
+    CPPUNIT_ASSERT_EQUAL(OUString("red"), 
aMap0["DisplayText"].get<OUString>());
+    CPPUNIT_ASSERT_EQUAL(OUString("R"), aMap0["Value"].get<OUString>());
+    comphelper::SequenceAsHashMap aMap1(aListItems[1]);
+    CPPUNIT_ASSERT_EQUAL(OUString("green"), 
aMap1["DisplayText"].get<OUString>());
+    CPPUNIT_ASSERT_EQUAL(OUString("G"), aMap1["Value"].get<OUString>());
+    comphelper::SequenceAsHashMap aMap2(aListItems[2]);
+    CPPUNIT_ASSERT_EQUAL(OUString("blue"), 
aMap2["DisplayText"].get<OUString>());
+    CPPUNIT_ASSERT_EQUAL(OUString("B"), aMap2["Value"].get<OUString>());
+    uno::Reference<text::XTextRange> xContentControlRange(xContentControl, 
uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xContentControlRange->getText();
+    uno::Reference<container::XEnumerationAccess> xContentEnumAccess(xText, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xContentEnum = 
xContentEnumAccess->createEnumeration();
+    uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("choose a color"), xContent->getString());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx 
b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx
new file mode 100644
index 000000000000..7718c0b04daa
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-dropdown.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 2bd6ece56ad4..817bd1125ce1 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1092,10 +1092,12 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         case NS_ooxml::LN_CT_SdtRun_sdtEndContent:
             if (nName == NS_ooxml::LN_CT_SdtRun_sdtEndContent)
             {
+                // Inline SDT.
                 switch (m_pImpl->m_pSdtHelper->getControlType())
                 {
                     case SdtControlType::richText:
                     case SdtControlType::checkBox:
+                    case SdtControlType::dropDown:
                         m_pImpl->PopSdt();
                         break;
                     default:
@@ -1128,7 +1130,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             }
         break;
         case NS_ooxml::LN_CT_SdtListItem_displayText:
-            // TODO handle when this is != value
+            
m_pImpl->m_pSdtHelper->getDropDownDisplayTexts().push_back(sStringValue);
         break;
         case NS_ooxml::LN_CT_SdtListItem_value:
             m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
@@ -3684,8 +3686,9 @@ 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->getControlType() == SdtControlType::dropDown)
+    if (m_pImpl->GetSdtStarts().empty() && 
m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::dropDown)
     {
+        // Block, cell or row SDT.
         if (bNewLine)
             // Dropdown control has single-line texts, so in case of newline, 
create the control.
             m_pImpl->m_pSdtHelper->createDropDownControl();
@@ -3737,11 +3740,21 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
                 // 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);
+            uno::Sequence<beans::PropertyValue> aGrabBag = 
m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
+            if (m_pImpl->GetSdtStarts().empty() || 
m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown)
+            {
+                pContext->Insert(PROP_SDTPR, uno::makeAny(aGrabBag), true, 
CHAR_GRAB_BAG);
+            }
         }
         else
-            m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
-                    
uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, 
PARA_GRAB_BAG);
+        {
+            uno::Sequence<beans::PropertyValue> aGrabBag = 
m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear();
+            if (m_pImpl->GetSdtStarts().empty() || 
m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown)
+            {
+                
m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR,
+                        uno::makeAny(aGrabBag), true, PARA_GRAB_BAG);
+            }
+        }
     }
     else if (len == 1 && sText[0] == 0x03)
     {
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 760a923c1c00..813f9943a005 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -900,6 +900,26 @@ void DomainMapper_Impl::PopSdt()
                                                
uno::makeAny(m_pSdtHelper->GetUncheckedState()));
     }
 
+    if (m_pSdtHelper->getControlType() == SdtControlType::dropDown)
+    {
+        std::vector<OUString>& rDisplayTexts = 
m_pSdtHelper->getDropDownDisplayTexts();
+        std::vector<OUString>& rValues = m_pSdtHelper->getDropDownItems();
+        if (rDisplayTexts.size() == rValues.size())
+        {
+            uno::Sequence<beans::PropertyValues> aItems(rValues.size());
+            beans::PropertyValues* pItems = aItems.getArray();
+            for (size_t i = 0; i < rValues.size(); ++i)
+            {
+                uno::Sequence<beans::PropertyValue> aItem = {
+                    comphelper::makePropertyValue("DisplayText", 
rDisplayTexts[i]),
+                    comphelper::makePropertyValue("Value", rValues[i]),
+                };
+                pItems[i] = aItem;
+            }
+            xContentControlProps->setPropertyValue("ListItems", 
uno::Any(aItems));
+        }
+    }
+
     xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
 
     m_pSdtHelper->clear();
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx 
b/writerfilter/source/dmapper/SdtHelper.cxx
index 23c8ba0e4dc4..e13e61a7755e 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -443,6 +443,7 @@ OUString SdtHelper::GetUncheckedState() const { return 
m_aUncheckedState; }
 void SdtHelper::clear()
 {
     m_aDropDownItems.clear();
+    m_aDropDownDisplayTexts.clear();
     setControlType(SdtControlType::unknown);
     m_sDataBindingPrefixMapping.clear();
     m_sDataBindingXPath.clear();
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx 
b/writerfilter/source/dmapper/SdtHelper.hxx
index dfc43c80fce8..a1aecd2aa704 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -59,8 +59,10 @@ class SdtHelper final : public virtual SvRefBase
     DomainMapper_Impl& m_rDM_Impl;
     css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
 
-    /// Items of the drop-down control.
+    /// Items of the drop-down control: <w:listItem w:value="...">.
     std::vector<OUString> m_aDropDownItems;
+    /// Display texts of a drop-down control: <w:listItem w:displayText="...">.
+    std::vector<OUString> m_aDropDownDisplayTexts;
     /// Type of sdt control
     SdtControlType m_aControlType;
     /// Pieces of the default text -- currently used only by the dropdown 
control.
@@ -122,6 +124,7 @@ public:
     ~SdtHelper() override;
 
     std::vector<OUString>& getDropDownItems() { return m_aDropDownItems; }
+    std::vector<OUString>& getDropDownDisplayTexts() { return 
m_aDropDownDisplayTexts; }
     OUStringBuffer& getSdtTexts() { return m_aSdtTexts; }
 
     OUStringBuffer& getDate() { return m_sDate; }

Reply via email to