From b2385830711ec700956869ace7670edd845a50df Mon Sep 17 00:00:00 2001 From: Jacobo Aragunde PĂ©rez Date: Fri, 7 Mar 2014 18:04:09 +0100 Subject: ooxml: export date controls properly Export date controls as ooxml Standard Document Tags (SDT) instead of replacing them with plain text. SDT date controls contain the date in ISO format as an attribute of tag, a custom date format that can be specified by the user in the tag and the date formatted in that custom format in the tag. The unit test testFormControl from ooxmlexport suite was removed, it only checked if the date control was exported as text and it obviously fails now. A new test that checks the values of the exported control was written instead. A pair of date format functions were added to datetimeutils.hxx. TODO: to avoid supporting all the posible custom formats that can be specified in the tag, it is forced to dd/mm/yyyy on export. Change-Id: I9d1b6f840ee9e133831fdb04ad399fe31bcb2063 --- include/tools/datetimeutils.hxx | 6 +++ sw/qa/extras/ooxmlexport/data/date-control.docx | Bin 0 -> 21367 bytes sw/qa/extras/ooxmlexport/data/form-control.docx | Bin 13507 -> 0 bytes sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 26 ++++++++---- sw/source/filter/ww8/docxattributeoutput.cxx | 52 +++++++++++++++++++++++- tools/source/datetime/datetimeutils.cxx | 20 +++++++++ 6 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/date-control.docx delete mode 100755 sw/qa/extras/ooxmlexport/data/form-control.docx diff --git a/include/tools/datetimeutils.hxx b/include/tools/datetimeutils.hxx index 840403bf002d..28766ee8a968 100644 --- a/include/tools/datetimeutils.hxx +++ b/include/tools/datetimeutils.hxx @@ -15,6 +15,12 @@ // This function converts a 'DateTime' object to an 'OString' object TOOLS_DLLPUBLIC OString DateTimeToOString( const DateTime& rDateTime ); +// This function converts a 'Date' object to an 'OString' object in ISO-8601 representation +TOOLS_DLLPUBLIC OString DateToOString( const Date& rDate ); + +// This function converts a 'Date' object to an 'OString' object in DD/MM/YYYY format +TOOLS_DLLPUBLIC OString DateToDDMMYYYYOString( const Date& rDate ); + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/data/date-control.docx b/sw/qa/extras/ooxmlexport/data/date-control.docx new file mode 100644 index 000000000000..0563d56aac35 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/date-control.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/form-control.docx b/sw/qa/extras/ooxmlexport/data/form-control.docx deleted file mode 100755 index 4f6305a8ca74..000000000000 Binary files a/sw/qa/extras/ooxmlexport/data/form-control.docx and /dev/null differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index f9fda5fb1eb3..b870866495a3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -2046,14 +2047,6 @@ DECLARE_OOXMLEXPORT_TEST(testAutofit, "autofit.docx") CPPUNIT_ASSERT_EQUAL(false, bool(getProperty(getShape(2), "FrameIsAutomaticHeight"))); } -DECLARE_OOXMLEXPORT_TEST(testFormControl, "form-control.docx") -{ - if (!m_bExported) - return; - // "[Date]" was missing. - getParagraph(1, "Foo [Date] bar."); -} - DECLARE_OOXMLEXPORT_TEST(testTrackChangesDeletedParagraphMark, "testTrackChangesDeletedParagraphMark.docx") { xmlDocPtr pXmlDoc = parseExport("word/document.xml"); @@ -2963,6 +2956,23 @@ DECLARE_OOXMLEXPORT_TEST(testGenericTextField, "Unsupportedtextfields.docx") CPPUNIT_ASSERT(contents.match("PRINTDATE \\* MERGEFORMAT")); } +DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") +{ + // check XML + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + return; + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date", "fullDate", "2014-03-05T00:00:00Z"); + assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", "05/03/2014"); + + // check imported control + uno::Reference xControl(getShape(1), uno::UNO_QUERY); + util::Date aDate = getProperty(xControl->getControl(), "Date"); + CPPUNIT_ASSERT_EQUAL(5, sal_Int32(aDate.Day)); + CPPUNIT_ASSERT_EQUAL(3, sal_Int32(aDate.Month)); + CPPUNIT_ASSERT_EQUAL(2014, sal_Int32(aDate.Year)); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 980f4fb3086f..294927108bc3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3597,11 +3597,59 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) uno::Reference xInfo(xControlModel, uno::UNO_QUERY); if (xInfo->supportsService("com.sun.star.form.component.DateField")) { + // gather component properties + uno::Reference xPropertySet(xControlModel, uno::UNO_QUERY); - OUString aHelpText = xPropertySet->getPropertyValue("HelpText").get(); + + OString sDate; + OUString aContentText; + bool bHasDate = false; + css::util::Date aUNODate; + if (xPropertySet->getPropertyValue("Date") >>= aUNODate) + { + bHasDate = true; + Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year); + sDate = DateToOString(aDate); + aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr()); + } + else + aContentText = xPropertySet->getPropertyValue("HelpText").get(); + + // output component + + m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND); + m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND); + + if (bHasDate) + m_pSerializer->startElementNS(XML_w, XML_date, + FSNS( XML_w, XML_fullDate ), sDate.getStr(), + FSEND); + else + m_pSerializer->startElementNS(XML_w, XML_date, FSEND); + + m_pSerializer->singleElementNS(XML_w, XML_dateFormat, + FSNS(XML_w, XML_val), "dd/MM/yyyy", //TODO: hardwired + FSEND); + m_pSerializer->singleElementNS(XML_w, XML_lid, + FSNS(XML_w, XML_val), "en-US", //TODO: hardwired + FSEND); + m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs, + FSNS(XML_w, XML_val), "dateTime", + FSEND); + m_pSerializer->singleElementNS(XML_w, XML_calendar, + FSNS(XML_w, XML_val), "gregorian", + FSEND); + + m_pSerializer->endElementNS(XML_w, XML_date); + m_pSerializer->endElementNS(XML_w, XML_sdtPr); + + m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND); m_pSerializer->startElementNS(XML_w, XML_r, FSEND); - RunText(aHelpText); + RunText(aContentText); m_pSerializer->endElementNS(XML_w, XML_r); + m_pSerializer->endElementNS(XML_w, XML_sdtContent); + + m_pSerializer->endElementNS(XML_w, XML_sdt); } } } diff --git a/tools/source/datetime/datetimeutils.cxx b/tools/source/datetime/datetimeutils.cxx index 512ae8230f11..417271c60eee 100644 --- a/tools/source/datetime/datetimeutils.cxx +++ b/tools/source/datetime/datetimeutils.cxx @@ -54,3 +54,23 @@ OString DateTimeToOString( const DateTime& rDateTime ) return aBuffer.makeStringAndClear(); } + +OString DateToOString( const Date& rDate ) +{ + Time aTime( Time::EMPTY ); + return DateTimeToOString( DateTime( rDate, aTime ) ); +} + +OString DateToDDMMYYYYOString( const Date& rDate ) +{ + OStringBuffer aBuffer( 25 ); + lcl_AppendTwoDigits( aBuffer, rDate.GetDay() ); + aBuffer.append( '/' ); + + lcl_AppendTwoDigits( aBuffer, rDate.GetMonth() ); + aBuffer.append( '/' ); + + aBuffer.append( sal_Int32( rDate.GetYear() ) ); + + return aBuffer.makeStringAndClear(); +} -- cgit