offapi/com/sun/star/text/ContentControl.idl                                    
  |   10 +++-
 sw/inc/unoprnms.hxx                                                            
  |    1 
 sw/source/core/txtnode/attrcontentcontrol.cxx                                  
  |   11 +++-
 sw/source/core/unocore/unocontentcontrol.cxx                                   
  |    7 +++
 sw/source/core/unocore/unomap1.cxx                                             
  |    1 
 writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx                     
  |   23 ++++++++++
 
writerfilter/qa/cppunittests/dmapper/data/content-control-date-data-binding.docx
 |binary
 writerfilter/source/dmapper/DomainMapper_Impl.cxx                              
  |   18 ++++++-
 8 files changed, 64 insertions(+), 7 deletions(-)

New commits:
commit 58002ab85d992c7ac44d8bb4d135246b67aa5cc7
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 26 10:03:04 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 26 10:47:59 2022 +0200

    sw content controls: enable data binding for date
    
    The document had a 2022 date in document.xml, but had a 2012 date in
    data binding. Writer used to show 2022, while Word picks 2012.
    
    Data binding for dates were disabled in commit
    de90c192cb8f1f03a4028493d8bfe9a127a76b2a (sw content controls, plain
    text: enable DOCX filter with data binding, 2022-09-19), because the
    formatting of those date timestamps were missing, so it was better to
    just not update them from data binding, temporarily.
    
    Fix the problem by adding a new read-only DateString property on
    SwXContentControl, this way the import filter can set not only the
    timestamp but the formatted date as well.
    
    This shares the SwContentControl::GetDateString() code with the UI,
    which already had the need in the past to turn a timestamp into a
    date string, based on a provided language and date format.
    
    Change-Id: I842a9483a675f895129a9854caec347be6b6b84e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141859
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/offapi/com/sun/star/text/ContentControl.idl 
b/offapi/com/sun/star/text/ContentControl.idl
index 8f390665c2b3..ae8a0e1a9396 100644
--- a/offapi/com/sun/star/text/ContentControl.idl
+++ b/offapi/com/sun/star/text/ContentControl.idl
@@ -100,17 +100,23 @@ service ContentControl
     */
     [optional, property] boolean ComboBox;
 
-    /** The alias: just remembered.
+    /** The alias: kind of a human-readable title / description, show up on 
the UI.
 
         @since LibreOffice 7.5
     */
     [optional, property] string Alias;
 
-    /** The tag: just remembered.
+    /** The tag: similar to Alias, but is meant to be machine-readable.
 
         @since LibreOffice 7.5
     */
     [optional, property] string Tag;
+
+    /** The formatted date string, based on DateFormat, DateLanguage and 
CurrentDate.
+
+        @since LibreOffice 7.5
+    */
+    [optional, property, readonly] string DateString;
 };
 
 
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 0a21fd182690..61cdcbb05938 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -892,6 +892,7 @@
 #define UNO_NAME_COLOR "Color"
 #define UNO_NAME_ALIAS "Alias"
 #define UNO_NAME_TAG "Tag"
+#define UNO_NAME_DATE_STRING "DateString"
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 587d2f53ed74..fe530f8b9128 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -240,9 +240,14 @@ OUString SwContentControl::GetDateString() const
 
     const Color* pColor = nullptr;
     OUString aFormatted;
-    if (!m_oSelectedDate)
+    double fSelectedDate = 0;
+    if (m_oSelectedDate)
     {
-        return OUString();
+        fSelectedDate = *m_oSelectedDate;
+    }
+    else
+    {
+        fSelectedDate = GetCurrentDateValue();
     }
 
     if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
@@ -250,7 +255,7 @@ OUString SwContentControl::GetDateString() const
         return OUString();
     }
 
-    pNumberFormatter->GetOutputString(*m_oSelectedDate, nFormat, aFormatted, 
&pColor, false);
+    pNumberFormatter->GetOutputString(fSelectedDate, nFormat, aFormatted, 
&pColor, false);
     return aFormatted;
 }
 
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx 
b/sw/source/core/unocore/unocontentcontrol.cxx
index a0d7d96099cc..189cdb9ba316 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -1168,6 +1168,13 @@ uno::Any SAL_CALL 
SwXContentControl::getPropertyValue(const OUString& rPropertyN
             aRet <<= m_pImpl->m_pContentControl->GetTag();
         }
     }
+    else if (rPropertyName == UNO_NAME_DATE_STRING)
+    {
+        if (!m_pImpl->m_bIsDescriptor)
+        {
+            aRet <<= m_pImpl->m_pContentControl->GetDateString();
+        }
+    }
     else
     {
         throw beans::UnknownPropertyException();
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index 55c1d2731de9..a860f2900754 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1011,6 +1011,7 @@ o3tl::span<const SfxItemPropertyMapEntry> 
SwUnoPropertyMapProvider::GetContentCo
         { u"" UNO_NAME_COLOR, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
         { u"" UNO_NAME_ALIAS, 0, cppu::UnoType<OUString>::get(), 
PROPERTY_NONE, 0 },
         { u"" UNO_NAME_TAG, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 
0 },
+        { u"" UNO_NAME_DATE_STRING, 0, cppu::UnoType<OUString>::get(), 
PropertyAttribute::READONLY, 0 },
     };
 
     return aContentControlMap_Impl;
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index 16039f98370a..8da9b65f6e9c 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -318,6 +318,29 @@ CPPUNIT_TEST_FIXTURE(Test, testClearingBreak)
     // SwLineBreakClear::ALL
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), eClear);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testContentControlDateDataBinding)
+{
+    // Given a document with date content control and data binding, data 
binding date is 2012,
+    // in-document date is 2022:
+    OUString aURL
+        = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"content-control-date-data-binding.docx";
+
+    // When loading that file:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure that the date is from the data binding, not from 
document.xml:
+    uno::Reference<text::XTextDocument> xTextDocument(getComponent(), 
uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xText, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParagraphs = 
xParaEnumAccess->createEnumeration();
+    uno::Reference<text::XTextRange> xParagraph(xParagraphs->nextElement(), 
uno::UNO_QUERY);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 4/26/2012
+    // - Actual  : 4/26/2022
+    // i.e. the date was from document.xml, which is considered outdated.
+    CPPUNIT_ASSERT_EQUAL(OUString("4/26/2012"), xParagraph->getString());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/content-control-date-data-binding.docx
 
b/writerfilter/qa/cppunittests/dmapper/data/content-control-date-data-binding.docx
new file mode 100644
index 000000000000..9ad644ef642c
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/content-control-date-data-binding.docx
 differ
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index dc42f0198cdf..b5afddc7a494 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -894,7 +894,7 @@ void DomainMapper_Impl::PopSdt()
     xCursor->gotoRange(xEnd, /*bExpand=*/true);
 
     std::optional<OUString> oData = m_pSdtHelper->getValueFromDataBinding();
-    if (oData.has_value() && m_pSdtHelper->getControlType() != 
SdtControlType::datePicker)
+    if (oData.has_value())
     {
         // Data binding has a value for us, prefer that over the in-document 
value.
         xCursor->setString(*oData);
@@ -992,6 +992,7 @@ void DomainMapper_Impl::PopSdt()
         xContentControlProps->setPropertyValue("Picture", uno::Any(true));
     }
 
+    bool bDateFromDataBinding = false;
     if (m_pSdtHelper->getControlType() == SdtControlType::datePicker)
     {
         xContentControlProps->setPropertyValue("Date", uno::Any(true));
@@ -1000,8 +1001,14 @@ void DomainMapper_Impl::PopSdt()
                                                
uno::Any(aDateFormat.replaceAll("'", "\"")));
         xContentControlProps->setPropertyValue("DateLanguage",
                                                
uno::Any(m_pSdtHelper->getLocale().makeStringAndClear()));
+        OUString aCurrentDate = m_pSdtHelper->getDate().makeStringAndClear();
+        if (oData.has_value())
+        {
+            aCurrentDate = *oData;
+            bDateFromDataBinding = true;
+        }
         xContentControlProps->setPropertyValue("CurrentDate",
-                                               
uno::Any(m_pSdtHelper->getDate().makeStringAndClear()));
+                                               uno::Any(aCurrentDate));
     }
 
     if (m_pSdtHelper->getControlType() == SdtControlType::plainText)
@@ -1011,6 +1018,13 @@ void DomainMapper_Impl::PopSdt()
 
     xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
 
+    if (bDateFromDataBinding)
+    {
+        OUString aDateString;
+        xContentControlProps->getPropertyValue("DateString") >>= aDateString;
+        xCursor->setString(aDateString);
+    }
+
     m_pSdtHelper->clear();
 }
 

Reply via email to