sw/inc/formatcontentcontrol.hxx               |   47 ++++++++
 sw/inc/unoprnms.hxx                           |    5 
 sw/qa/core/unocore/unocore.cxx                |   20 +++
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx    |   12 ++
 sw/source/core/txtnode/attrcontentcontrol.cxx |   10 +
 sw/source/core/unocore/unocontentcontrol.cxx  |  140 ++++++++++++++++++++++++++
 sw/source/core/unocore/unomap1.cxx            |    6 +
 sw/source/filter/ww8/docxattributeoutput.cxx  |   22 ++++
 8 files changed, 262 insertions(+)

New commits:
commit 0f70f4d76b5f68e5b1d81f0e300435ccef893c9a
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri May 27 12:35:20 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri May 27 13:42:59 2022 +0200

    sw content controls, date: preserve more properties
    
    While working on the DOCX import for dates, it turns out there is a need
    to store more properties for DOCX export purposes. Given that these are
    potentially useful for full support, add dedicated UNO API and DOCX
    export for these (i.e. not just grab-bag), but omit UI or ODT filter for
    now. This includes:
    
    - <w:docPart w:val="...">
    
    - <w:dataBinding w:prefixMappings="..." w:xpath="..." w:storeItemID="...">
    
    - <w15:color w:val="...">
    
    And tests for all these.
    
    Change-Id: I18ddec50d40c1c4abd87f7ea947a24dd8a92a755
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135039
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx
index 36f0b01a527e..91b5ba011100 100644
--- a/sw/inc/formatcontentcontrol.hxx
+++ b/sw/inc/formatcontentcontrol.hxx
@@ -139,6 +139,21 @@ class SW_DLLPUBLIC SwContentControl : public 
sw::BroadcastingModify
     /// Date in YYYY-MM-DDT00:00:00Z format.
     OUString m_aCurrentDate;
 
+    /// The placeholder's doc part: just remembered.
+    OUString m_aPlaceholderDocPart;
+
+    /// The data bindings's prefix mappings: just remembered.
+    OUString m_aDataBindingPrefixMappings;
+
+    /// The data bindings's XPath: just remembered.
+    OUString m_aDataBindingXpath;
+
+    /// The data bindings's store item ID: just remembered.
+    OUString m_aDataBindingStoreItemID;
+
+    /// The color: just remembered.
+    OUString m_aColor;
+
     /// Stores a list item index, in case the doc model is not yet updated.
     std::optional<size_t> m_oSelectedListItem;
 
@@ -233,6 +248,13 @@ public:
     /// Formats m_oSelectedDate, taking m_aDateFormat and m_aDateLanguage into 
account.
     OUString GetDateString() const;
 
+    void SetPlaceholderDocPart(const OUString& rPlaceholderDocPart)
+    {
+        m_aPlaceholderDocPart = rPlaceholderDocPart;
+    }
+
+    OUString GetPlaceholderDocPart() const { return m_aPlaceholderDocPart; }
+
     void SetSelectedListItem(std::optional<size_t> oSelectedListItem)
     {
         m_oSelectedListItem = oSelectedListItem;
@@ -245,6 +267,31 @@ public:
     std::optional<double> GetSelectedDate() const { return m_oSelectedDate; }
 
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
+
+    void SetDataBindingPrefixMappings(const OUString& 
rDataBindingPrefixMappings)
+    {
+        m_aDataBindingPrefixMappings = rDataBindingPrefixMappings;
+    }
+
+    OUString GetDataBindingPrefixMappings() const { return 
m_aDataBindingPrefixMappings; }
+
+    void SetDataBindingXpath(const OUString& rDataBindingXpath)
+    {
+        m_aDataBindingXpath = rDataBindingXpath;
+    }
+
+    OUString GetDataBindingXpath() const { return m_aDataBindingXpath; }
+
+    void SetDataBindingStoreItemID(const OUString& rDataBindingStoreItemID)
+    {
+        m_aDataBindingStoreItemID = rDataBindingStoreItemID;
+    }
+
+    OUString GetDataBindingStoreItemID() const { return 
m_aDataBindingStoreItemID; }
+
+    void SetColor(const OUString& rColor) { m_aColor = rColor; }
+
+    OUString GetColor() const { return m_aColor; }
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 90921cbc655d..14da263acd96 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -883,6 +883,11 @@
 #define UNO_NAME_DATE_FORMAT "DateFormat"
 #define UNO_NAME_DATE_LANGUAGE "DateLanguage"
 #define UNO_NAME_CURRENT_DATE "CurrentDate"
+#define UNO_NAME_PLACEHOLDER_DOC_PART "PlaceholderDocPart"
+#define UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS "DataBindingPrefixMappings"
+#define UNO_NAME_DATA_BINDING_XPATH "DataBindingXpath"
+#define UNO_NAME_DATA_BINDING_STORE_ITEM_ID "DataBindingStoreItemID"
+#define UNO_NAME_COLOR "Color"
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index 1ccd8b250ec3..56b9ed4c74de 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -603,6 +603,17 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, 
testContentControlDate)
     xContentControlProps->setPropertyValue("DateLanguage", 
uno::Any(OUString("en-US")));
     xContentControlProps->setPropertyValue("CurrentDate",
                                            
uno::Any(OUString("2022-05-25T00:00:00Z")));
+    xContentControlProps->setPropertyValue("PlaceholderDocPart",
+                                           
uno::Any(OUString("DefaultPlaceholder_-1854013437")));
+    xContentControlProps->setPropertyValue(
+        "DataBindingPrefixMappings",
+        
uno::Any(OUString("xmlns:ns0='http://schemas.microsoft.com/vsto/samples' ")));
+    xContentControlProps->setPropertyValue(
+        "DataBindingXpath",
+        
uno::Any(OUString("/ns0:employees[1]/ns0:employee[1]/ns0:hireDate[1]")));
+    xContentControlProps->setPropertyValue(
+        "DataBindingStoreItemID", 
uno::Any(OUString("{241A8A02-7FFD-488D-8827-63FBE74E8BC9}")));
+    xContentControlProps->setPropertyValue("Color", 
uno::Any(OUString("008000")));
     xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
 
     // Then make sure that the specified properties are set:
@@ -617,6 +628,15 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, 
testContentControlDate)
     CPPUNIT_ASSERT_EQUAL(OUString("M/d/yyyy"), 
pContentControl->GetDateFormat());
     CPPUNIT_ASSERT_EQUAL(OUString("en-US"), 
pContentControl->GetDateLanguage());
     CPPUNIT_ASSERT_EQUAL(OUString("2022-05-25T00:00:00Z"), 
pContentControl->GetCurrentDate());
+    CPPUNIT_ASSERT_EQUAL(OUString("DefaultPlaceholder_-1854013437"),
+                         pContentControl->GetPlaceholderDocPart());
+    
CPPUNIT_ASSERT_EQUAL(OUString("xmlns:ns0='http://schemas.microsoft.com/vsto/samples'
 "),
+                         pContentControl->GetDataBindingPrefixMappings());
+    
CPPUNIT_ASSERT_EQUAL(OUString("/ns0:employees[1]/ns0:employee[1]/ns0:hireDate[1]"),
+                         pContentControl->GetDataBindingXpath());
+    CPPUNIT_ASSERT_EQUAL(OUString("{241A8A02-7FFD-488D-8827-63FBE74E8BC9}"),
+                         pContentControl->GetDataBindingStoreItemID());
+    CPPUNIT_ASSERT_EQUAL(OUString("008000"), pContentControl->GetColor());
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 2ba7a7cfdd97..da72f770151b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -388,6 +388,12 @@ CPPUNIT_TEST_FIXTURE(Test, testDateContentControlExport)
     xContentControlProps->setPropertyValue("Date", uno::Any(true));
     xContentControlProps->setPropertyValue("DateFormat", 
uno::Any(OUString("M/d/yyyy")));
     xContentControlProps->setPropertyValue("DateLanguage", 
uno::Any(OUString("en-US")));
+    xContentControlProps->setPropertyValue("CurrentDate", 
uno::Any(OUString("2022-05-26T00:00:00Z")));
+    xContentControlProps->setPropertyValue("PlaceholderDocPart", 
uno::Any(OUString("DefaultPlaceholder_-1854013437")));
+    xContentControlProps->setPropertyValue("DataBindingPrefixMappings", 
uno::Any(OUString("xmlns:ns0='http://schemas.microsoft.com/vsto/samples' ")));
+    xContentControlProps->setPropertyValue("DataBindingXpath", 
uno::Any(OUString("/ns0:employees[1]/ns0:employee[1]/ns0:hireDate[1]")));
+    xContentControlProps->setPropertyValue("DataBindingStoreItemID", 
uno::Any(OUString("{241A8A02-7FFD-488D-8827-63FBE74E8BC9}")));
+    xContentControlProps->setPropertyValue("Color", 
uno::Any(OUString("008000")));
     xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
 
     // When exporting to DOCX:
@@ -403,6 +409,12 @@ CPPUNIT_TEST_FIXTURE(Test, testDateContentControlExport)
     // i.e. the <w:date> was lost on export.
     assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date/w:dateFormat", "val", 
"M/d/yyyy");
     assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date/w:lid", "val", "en-US");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", "fullDate", 
"2022-05-26T00:00:00Z");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:placeholder/w:docPart", "val", 
"DefaultPlaceholder_-1854013437");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:dataBinding", "prefixMappings", 
"xmlns:ns0='http://schemas.microsoft.com/vsto/samples' ");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:dataBinding", "xpath", 
"/ns0:employees[1]/ns0:employee[1]/ns0:hireDate[1]");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:dataBinding", "storeItemID", 
"{241A8A02-7FFD-488D-8827-63FBE74E8BC9}");
+    assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w15:color", "val", "008000");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf148494)
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 529a3ea9e331..f70a36b49de2 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -326,6 +326,16 @@ void SwContentControl::dumpAsXml(xmlTextWriterPtr pWriter) 
const
                                       
BAD_CAST(m_aDateLanguage.toUtf8().getStr()));
     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("current-date"),
                                       
BAD_CAST(m_aCurrentDate.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, 
BAD_CAST("placeholder-doc-part"),
+                                      
BAD_CAST(m_aPlaceholderDocPart.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, 
BAD_CAST("data-binding-prefix-mappings"),
+                                      
BAD_CAST(m_aDataBindingPrefixMappings.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-xpath"),
+                                      
BAD_CAST(m_aDataBindingXpath.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, 
BAD_CAST("data-binding-store-item-id"),
+                                      
BAD_CAST(m_aDataBindingStoreItemID.toUtf8().getStr()));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"),
+                                      BAD_CAST(m_aColor.toUtf8().getStr()));
 
     if (!m_aListItems.empty())
     {
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx 
b/sw/source/core/unocore/unocontentcontrol.cxx
index 493e287296e3..0024339ca297 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -166,6 +166,11 @@ public:
     OUString m_aDateFormat;
     OUString m_aDateLanguage;
     OUString m_aCurrentDate;
+    OUString m_aPlaceholderDocPart;
+    OUString m_aDataBindingPrefixMappings;
+    OUString m_aDataBindingXpath;
+    OUString m_aDataBindingStoreItemID;
+    OUString m_aColor;
 
     Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* 
pContentControl,
          const uno::Reference<text::XText>& xParentText,
@@ -531,6 +536,11 @@ void SwXContentControl::AttachImpl(const 
uno::Reference<text::XTextRange>& xText
     pContentControl->SetDateFormat(m_pImpl->m_aDateFormat);
     pContentControl->SetDateLanguage(m_pImpl->m_aDateLanguage);
     pContentControl->SetCurrentDate(m_pImpl->m_aCurrentDate);
+    pContentControl->SetPlaceholderDocPart(m_pImpl->m_aPlaceholderDocPart);
+    
pContentControl->SetDataBindingPrefixMappings(m_pImpl->m_aDataBindingPrefixMappings);
+    pContentControl->SetDataBindingXpath(m_pImpl->m_aDataBindingXpath);
+    
pContentControl->SetDataBindingStoreItemID(m_pImpl->m_aDataBindingStoreItemID);
+    pContentControl->SetColor(m_pImpl->m_aColor);
 
     SwFormatContentControl aContentControl(pContentControl, nWhich);
     bool bSuccess
@@ -845,6 +855,81 @@ void SAL_CALL SwXContentControl::setPropertyValue(const 
OUString& rPropertyName,
             }
         }
     }
+    else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
+    {
+        OUString aValue;
+        if (rValue >>= aValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_aPlaceholderDocPart = aValue;
+            }
+            else
+            {
+                m_pImpl->m_pContentControl->SetPlaceholderDocPart(aValue);
+            }
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS)
+    {
+        OUString aValue;
+        if (rValue >>= aValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_aDataBindingPrefixMappings = aValue;
+            }
+            else
+            {
+                
m_pImpl->m_pContentControl->SetDataBindingPrefixMappings(aValue);
+            }
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH)
+    {
+        OUString aValue;
+        if (rValue >>= aValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_aDataBindingXpath = aValue;
+            }
+            else
+            {
+                m_pImpl->m_pContentControl->SetDataBindingXpath(aValue);
+            }
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID)
+    {
+        OUString aValue;
+        if (rValue >>= aValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_aDataBindingStoreItemID = aValue;
+            }
+            else
+            {
+                m_pImpl->m_pContentControl->SetDataBindingStoreItemID(aValue);
+            }
+        }
+    }
+    else if (rPropertyName == UNO_NAME_COLOR)
+    {
+        OUString aValue;
+        if (rValue >>= aValue)
+        {
+            if (m_pImpl->m_bIsDescriptor)
+            {
+                m_pImpl->m_aColor = aValue;
+            }
+            else
+            {
+                m_pImpl->m_pContentControl->SetColor(aValue);
+            }
+        }
+    }
     else
     {
         throw beans::UnknownPropertyException();
@@ -979,6 +1064,61 @@ uno::Any SAL_CALL 
SwXContentControl::getPropertyValue(const OUString& rPropertyN
             aRet <<= m_pImpl->m_pContentControl->GetCurrentDate();
         }
     }
+    else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_aPlaceholderDocPart;
+        }
+        else
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetCurrentDate();
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_aDataBindingPrefixMappings;
+        }
+        else
+        {
+            aRet <<= 
m_pImpl->m_pContentControl->GetDataBindingPrefixMappings();
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_aDataBindingXpath;
+        }
+        else
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetDataBindingXpath();
+        }
+    }
+    else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_aDataBindingStoreItemID;
+        }
+        else
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetDataBindingStoreItemID();
+        }
+    }
+    else if (rPropertyName == UNO_NAME_COLOR)
+    {
+        if (m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_aColor;
+        }
+        else
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetColor();
+        }
+    }
     else
     {
         throw beans::UnknownPropertyException();
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index d61e598590a4..145a443be134 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1031,7 +1031,13 @@ const SfxItemPropertyMapEntry* 
SwUnoPropertyMapProvider::GetContentControlProper
         { u"" UNO_NAME_PICTURE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 
0 },
         { u"" UNO_NAME_DATE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
         { u"" UNO_NAME_DATE_FORMAT, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_DATE_LANGUAGE, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
         { u"" UNO_NAME_CURRENT_DATE, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_PLACEHOLDER_DOC_PART, 0, 
cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS, 0, 
cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_DATA_BINDING_XPATH, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_DATA_BINDING_STORE_ITEM_ID, 0, 
cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+        { u"" UNO_NAME_COLOR, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
         { u"", 0, css::uno::Type(), 0, 0 }
     };
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index b46c6ad3354c..446d26b459de 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2330,6 +2330,28 @@ void DocxAttributeOutput::WriteContentControlStart()
 
     m_pSerializer->startElementNS(XML_w, XML_sdt);
     m_pSerializer->startElementNS(XML_w, XML_sdtPr);
+    if (!m_pContentControl->GetPlaceholderDocPart().isEmpty())
+    {
+        m_pSerializer->startElementNS(XML_w, XML_placeholder);
+        m_pSerializer->singleElementNS(XML_w, XML_docPart, FSNS(XML_w, 
XML_val),
+                                       
m_pContentControl->GetPlaceholderDocPart());
+        m_pSerializer->endElementNS(XML_w, XML_placeholder);
+    }
+
+    if (!m_pContentControl->GetDataBindingPrefixMappings().isEmpty() || 
!m_pContentControl->GetDataBindingXpath().isEmpty() || 
!m_pContentControl->GetDataBindingStoreItemID().isEmpty())
+    {
+        m_pSerializer->singleElementNS( XML_w, XML_dataBinding,
+            FSNS(XML_w, XML_prefixMappings), 
m_pContentControl->GetDataBindingPrefixMappings(),
+            FSNS(XML_w, XML_xpath), m_pContentControl->GetDataBindingXpath(),
+            FSNS(XML_w, XML_storeItemID), 
m_pContentControl->GetDataBindingStoreItemID());
+    }
+
+    if (!m_pContentControl->GetColor().isEmpty())
+    {
+        m_pSerializer->singleElementNS(XML_w15, XML_color, FSNS(XML_w, 
XML_val),
+                                       m_pContentControl->GetColor());
+    }
+
     if (m_pContentControl->GetShowingPlaceHolder())
     {
         m_pSerializer->singleElementNS(XML_w, XML_showingPlcHdr);

Reply via email to