From 58002ab85d992c7ac44d8bb4d135246b67aa5cc7 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 26 Oct 2022 10:03:04 +0200 Subject: 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 Tested-by: Jenkins --- .../qa/cppunittests/dmapper/DomainMapper_Impl.cxx | 23 +++++++++++++++++++++ .../data/content-control-date-data-binding.docx | Bin 0 -> 33834 bytes writerfilter/source/dmapper/DomainMapper_Impl.cxx | 18 ++++++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 writerfilter/qa/cppunittests/dmapper/data/content-control-date-data-binding.docx (limited to 'writerfilter') 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(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 xTextDocument(getComponent(), uno::UNO_QUERY); + uno::Reference xText = xTextDocument->getText(); + uno::Reference xParaEnumAccess(xText, uno::UNO_QUERY); + uno::Reference xParagraphs = xParaEnumAccess->createEnumeration(); + uno::Reference 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 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(); } -- cgit