Rebased ref, commits from common ancestor: commit 92b89ecb11d96bcaab3c1c0ba96508129ece540d Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Jul 3 19:57:19 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Wed Jul 3 21:40:17 2019 +0200
MSForms: DOCX filter: The new text-based field is allowed in the header. Change-Id: I71d61c702ccd0470c4c3df09531704783c1b3e01 diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index 3d3c528ef41a..b5b6b6040216 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -589,13 +589,13 @@ DECLARE_OOXMLEXPORT_TEST(testfdo82492, "fdo82492.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent/w:r",1); } -/*DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx") +DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx") { // Problem was that w:sdt elements in headers were lost on import. if (xmlDocPtr pXmlDoc = parseExport("word/header1.xml")) // This was 0, w:sdt (and then w:date) was missing. assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1); -}*/ +} DECLARE_OOXMLEXPORT_TEST(testSdtCompanyMultipara, "sdt-company-multipara.docx") { diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index b24e258645d9..2f31031d7c19 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1018,7 +1018,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) if (!m_pImpl->m_pSdtHelper->getDropDownItems().empty()) m_pImpl->m_pSdtHelper->createDropDownControl(); - else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) + else if (m_pImpl->m_pSdtHelper->validateDateFormat()) m_pImpl->m_pSdtHelper->createDateContentControl(); break; case NS_ooxml::LN_CT_SdtListItem_displayText: @@ -2427,30 +2427,20 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) break; case NS_ooxml::LN_CT_SdtDate_dateFormat: { - if (!IsInHeaderFooter()) - m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue); - else - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDate_dateFormat", sStringValue); + m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue); } break; case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs: { - if (IsInHeaderFooter()) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDate_storeMappedDataAs", sStringValue); } break; case NS_ooxml::LN_CT_SdtDate_calendar: { - if (IsInHeaderFooter()) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDate_calendar", sStringValue); } break; case NS_ooxml::LN_CT_SdtDate_lid: { - if (!IsInHeaderFooter()) - m_pImpl->m_pSdtHelper->getLocale().append(sStringValue); - else - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDate_lid", sStringValue); + m_pImpl->m_pSdtHelper->getLocale().append(sStringValue); } break; case NS_ooxml::LN_CT_SdtPr_dataBinding: @@ -3213,13 +3203,13 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) return; } } - // Form controls are not allowed in headers / footers; see sw::DocumentContentOperationsManager::InsertDrawObj() - else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) + else if (m_pImpl->m_pSdtHelper->validateDateFormat()) { // Date field will be imported, so we don't need the corresponding date text in most of the cases // however when fullDate is not specified, but we have a date string we need to import it as // simple text (this is the case when user sets date field manually in MSO). - if(!m_pImpl->m_pSdtHelper->getDate().toString().isEmpty() || sText.isEmpty()) + if((!m_pImpl->m_pSdtHelper->getDate().toString().isEmpty() || sText.isEmpty()) && + (!IsInHeaderFooter() || !m_pImpl->IsDiscardHeaderFooter())) // discard date control with header / footer { return; } commit a4601341a70b296a02faf8ae8a92b7aad7be70e4 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Jul 3 19:46:48 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Wed Jul 3 19:46:48 2019 +0200 MSForms: DOCX filter: update testN820509() test Now we import date field as date form field and not as date form control. Design mode has no interaction with this kind of field, so we don't need check the design mode status. Change-Id: I5dc2abc33f307d934771e4f6608d1c3a9ed71b0b diff --git a/sw/qa/extras/ooxmlexport/data/n820509.docx b/sw/qa/extras/ooxmlexport/data/n820509.docx index a6da1e16842c..bfaea9075652 100644 Binary files a/sw/qa/extras/ooxmlexport/data/n820509.docx and b/sw/qa/extras/ooxmlexport/data/n820509.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 0ab2ee04f42c..59ab8b015be6 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -44,6 +44,9 @@ #include <unotools/fltrcfg.hxx> #include <comphelper/sequenceashashmap.hxx> #include <oox/drawingml/drawingmltypes.hxx> +#include <xmloff/odffields.hxx> +#include <IDocumentMarkAccess.hxx> +#include <IMark.hxx> #include <bordertest.hxx> @@ -958,19 +961,34 @@ DECLARE_OOXMLEXPORT_TEST(testN816593, "n816593.docx") CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount()); } -/*DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") +DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") { - // Design mode was enabled. - uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); - uno::Reference<view::XFormLayerAccess> xFormLayerAccess(xModel->getCurrentController(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(false, bool(xFormLayerAccess->isFormDesignMode())); - // M.d.yyyy date format was unhandled. - 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_EQUAL(sal_Int16(8), getProperty<sal_Int16>(xPropertySet, "DateFormat")); -}*/ + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount()); + + for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) + { + ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*aIter); + + if(!pFieldmark) + continue; + + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + + const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters(); + OUString sDateFormat; + auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT); + if (pResult != pParameters->end()) + { + pResult->second >>= sDateFormat; + } + CPPUNIT_ASSERT_EQUAL(OUString("M.d.yyyy"), sDateFormat); + } +} DECLARE_OOXMLEXPORT_TEST(testN830205, "n830205.docx") { commit 98a4afd6f81510039d02088171cae9449b6b70c6 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Jul 3 19:21:35 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Wed Jul 3 19:21:35 2019 +0200 MSForms: DOCX filter: reenable passing test Change-Id: I566a65fa4ece6500128ceeb497c01f1c6e38470c diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 2d717f106b54..0ab2ee04f42c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -527,21 +527,21 @@ DECLARE_OOXMLEXPORT_TEST(testN780563, "n780563.docx") CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount( )); } -/*DECLARE_OOXMLEXPORT_TEST(testN780853, "n780853.docx") -{*/ +DECLARE_OOXMLEXPORT_TEST(testN780853, "n780853.docx") +{ /* * The problem was that the table was not imported. * * xray ThisComponent.TextTables.Count 'was 0 */ - /*uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); //tdf#102619 - I would have expected this to be "Standard", but MSO 2013/2010/2003 all give FollowStyle==Date uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("Date"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Date"), getProperty<OUString>(properties, "FollowStyle")); -}*/ +} DECLARE_OOXMLEXPORT_TEST(testN780843, "n780843.docx") { commit b7d374f51b98eb1adb47762c9cede6917734695e Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Jul 3 14:43:54 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Wed Jul 3 14:45:10 2019 +0200 MSForms: DOCX filter: handle date formats with quotation marks. Change-Id: I61cc6d47200acdd55f147b4f1829330dec8562a0 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx index c6d67de8bd25..6e4fd349935f 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx @@ -661,7 +661,7 @@ DECLARE_OOXMLEXPORT_TEST(testTableCurruption, "tableCurrupt.docx") CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), aHeaderBottomBorder.LineWidth); } -/*DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") +DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") { // check XML xmlDocPtr pXmlDoc = parseExport("word/document.xml"); @@ -671,7 +671,7 @@ DECLARE_OOXMLEXPORT_TEST(testTableCurruption, "tableCurrupt.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:dateFormat", "val", "dddd, dd' de 'MMMM' de 'yyyy"); assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:lid", "val", "es-ES"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", u"mi\u00E9rcoles, 05 de marzo de 2014"); -}*/ +} DECLARE_OOXMLEXPORT_TEST(test_OpeningBrace, "2120112713_OpenBrace.docx") { diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 0a708d0bc6f0..eac660544018 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1884,8 +1884,11 @@ void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUSt else m_pSerializer->startElementNS(XML_w, XML_date); + OString sUTF8DateFormat = sDateFormat.toUtf8(); + // Replace quotation mark used for mark static strings in date format + sUTF8DateFormat = sUTF8DateFormat.replaceAll("\"", "'"); m_pSerializer->singleElementNS(XML_w, XML_dateFormat, - FSNS(XML_w, XML_val), sDateFormat.toUtf8()); + FSNS(XML_w, XML_val), sUTF8DateFormat); m_pSerializer->singleElementNS(XML_w, XML_lid, FSNS(XML_w, XML_val), sLang.toUtf8()); m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs, diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index c55ceaec0d65..1c7c04563f09 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -122,7 +122,10 @@ void SdtHelper::createDateContentControl() uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); if(xNameCont.is()) { - xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, uno::makeAny(m_sDateFormat.makeStringAndClear())); + OUString sDateFormat = m_sDateFormat.makeStringAndClear(); + // Replace quotation mark used for mark static strings in date format + sDateFormat = sDateFormat.replaceAll("'", "\""); + xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, uno::makeAny(sDateFormat)); xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT_LANGUAGE, uno::makeAny(m_sLocale.makeStringAndClear())); OUString sDate = m_sDate.makeStringAndClear(); if(!sDate.isEmpty()) commit eb478589629189680ea0e980902fec4609b089d8 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Wed Jul 3 14:43:12 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Wed Jul 3 14:45:05 2019 +0200 MSForms: date format: better searching of date format entries GetEntryKey and PutEntry methods are not consistent. It can happen that GetEntryKey does not found the format we are searching for, however the PutEntry() method finds it among the entries and so returns with failure. Let's check the nFormat instead, PutEntry returns the found entry key if the entry exists. Change-Id: Ia7e8702b03999950adfa649d1adc3a839dc5a178 diff --git a/sw/source/core/crsr/DateFormFieldButton.cxx b/sw/source/core/crsr/DateFormFieldButton.cxx index f9586c14b3fb..db4275746176 100644 --- a/sw/source/core/crsr/DateFormFieldButton.cxx +++ b/sw/source/core/crsr/DateFormFieldButton.cxx @@ -56,20 +56,19 @@ SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pResult->second >>= sDateString; sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); - bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - bValidFormat = m_pNumberFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + m_pNumberFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); } - if (bValidFormat) + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) { double dCurrentDate = 0; m_pNumberFormatter->IsNumberFormat(sDateString, nFormat, dCurrentDate); @@ -100,20 +99,19 @@ IMPL_LINK(SwDatePickerDialog, ImplSelectHdl, Calendar*, pCalendar, void) if (m_pFieldmark != nullptr) { sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); - bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - bValidFormat = m_pNumberFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + m_pNumberFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); } - if (bValidFormat) + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) { Color* pCol = nullptr; OUString sOutput; diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 9040eb3f6362..905b427c44e9 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -891,20 +891,19 @@ namespace sw { namespace mark { pResult->second >>= sFormattedDate; sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); - bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - bValidFormat = pFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); } - if (bValidFormat) + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) { pFormatter->IsNumberFormat(sFormattedDate, nFormat, dCurrentDate); bHasCurrentDate = true; @@ -914,20 +913,19 @@ namespace sw { namespace mark { if (!sDateFormat.isEmpty() && !sLang.isEmpty() && bHasCurrentDate) { sal_uInt32 nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); - bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; - bValidFormat = pFormatter->PutEntry(sDateFormat, - nCheckPos, - nType, - nFormat, - LanguageTag(sLang).getLanguageType()); + pFormatter->PutEntry(sDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); } OUString sOutput; - if (bValidFormat) + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) { Color* pCol = nullptr; pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index abd054ce32cb..0a708d0bc6f0 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1899,57 +1899,52 @@ void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUSt m_pSerializer->startElementNS(XML_w, XML_sdtContent); m_pSerializer->startElementNS(XML_w, XML_r); + // Convert the current date to the right format if (!sCurrentDate.isEmpty()) { - // Convert the current date to the right format - if (!sCurrentDate.isEmpty()) - { - SvNumberFormatter* pFormatter = m_rExport.m_pDoc->GetNumberFormatter(); + SvNumberFormatter* pFormatter = m_rExport.m_pDoc->GetNumberFormatter(); - double dCurrentDate = 0.0; - // First get the date internal double representation - sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); - bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; - if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) - { - sal_Int32 nCheckPos = 0; - SvNumFormatType nType; - OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - bValidFormat = pFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); - } - if (bValidFormat) - { - pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate); - } - - // Then convert the date to a fromatter string - nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); - bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; - if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) - { - sal_Int32 nCheckPos = 0; - SvNumFormatType nType; - OUString sNonConstDateFormat = sDateFormat; - bValidFormat = pFormatter->PutEntry(sNonConstDateFormat, - nCheckPos, - nType, - nFormat, - LanguageTag(sLang).getLanguageType()); - } + double dCurrentDate = 0.0; + // First get the date internal double representation + sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + SvNumFormatType nType; + OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; + pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) + { + pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate); + } - OUString sOutput; - if (bValidFormat) - { - Color* pCol = nullptr; - pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); - } + // Then convert the date to a fromatter string + nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + SvNumFormatType nType; + OUString sNonConstDateFormat = sDateFormat; + pFormatter->PutEntry(sNonConstDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); + } - RunText(sOutput); + OUString sOutput; + if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND) + { + Color* pCol = nullptr; + pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); } + + RunText(sOutput); } m_pSerializer->endElementNS(XML_w, XML_r); diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx index 6b8fbaf35d38..30b97178f44e 100644 --- a/sw/source/ui/fldui/DateFormFieldDialog.cxx +++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx @@ -77,19 +77,18 @@ void DateFormFieldDialog::InitControls() { LanguageType aLangType = LanguageTag(sLang).getLanguageType(); sal_uInt32 nFormatKey = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType); - bool bValidFormat = nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; - bValidFormat = m_pNumberFormatter->PutEntry(sFormatString, - nCheckPos, - nType, - nFormatKey, - LanguageTag(sLang).getLanguageType()); + m_pNumberFormatter->PutEntry(sFormatString, + nCheckPos, + nType, + nFormatKey, + LanguageTag(sLang).getLanguageType()); } - if(aLangType != LANGUAGE_DONTKNOW && bValidFormat) + if(aLangType != LANGUAGE_DONTKNOW && nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND) { if (m_xFormatLB->GetCurLanguage() == aLangType) { commit 8e638ce0fa11eb8d9d24b1d825280fbbd767a98e Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 15:49:01 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 23:11:55 2019 +0200 MSForms: DOCX filter: import manually set date field as plain text In MSO the user can add any text in the date field without having it in the specified date format. We import this kind of date as plain text. Change-Id: Ied4bf03a3ac4c9b6f1cfc78d91e6a52ad3d6e179 diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index 0a989161fba6..9bae9e7fab91 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -34,13 +34,19 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108545_embeddedDocxIcon, "tdf108545_embeddedDocx CPPUNIT_ASSERT_EQUAL(embed::Aspects::MSOLE_ICON, xSupplier->getAspect()); } -/*DECLARE_OOXMLIMPORT_TEST(testTdf121203, "tdf121203.docx") +DECLARE_OOXMLIMPORT_TEST(testTdf121203, "tdf121203.docx") { - // Make sure that the date SDT's content is imported as plain text, as it - // has no ISO date, so we have no idea how to represent that with our date - // control. + // Make sure that the date SDT's content is imported as plain text, as + // the field has no fullDate attribute which we can use to find out the actual date. CPPUNIT_ASSERT_EQUAL(OUString("17-Oct-2018 09:00"), getRun(getParagraph(1), 1)->getString()); -}*/ + + // Make sure we did not import a date field. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount()); +} DECLARE_OOXMLIMPORT_TEST(testTdf109053, "tdf109053.docx") { diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 749102c4e903..b24e258645d9 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1028,10 +1028,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue); break; case NS_ooxml::LN_CT_SdtDate_fullDate: - if (!IsInHeaderFooter()) - m_pImpl->m_pSdtHelper->getDate().append(sStringValue); - else - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDate_fullDate", sStringValue); + m_pImpl->m_pSdtHelper->getDate().append(sStringValue); break; case NS_ooxml::LN_CT_Background_color: if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape()) @@ -3219,8 +3216,16 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) // Form controls are not allowed in headers / footers; see sw::DocumentContentOperationsManager::InsertDrawObj() else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) { - // date field is imported, we don't need the corresponding date text - return; + // Date field will be imported, so we don't need the corresponding date text in most of the cases + // however when fullDate is not specified, but we have a date string we need to import it as + // simple text (this is the case when user sets date field manually in MSO). + if(!m_pImpl->m_pSdtHelper->getDate().toString().isEmpty() || sText.isEmpty()) + { + return; + } + // Remove date field attributes to avoid to import an actual date field + m_pImpl->m_pSdtHelper->getDateFormat().truncate(); + m_pImpl->m_pSdtHelper->getLocale().truncate(); } else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty()) { commit 8a744de7e5e7d3934919d76658b9f73bde4691d6 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 14:51:38 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 22:10:18 2019 +0200 MSForms: DOCX filter: add a test case about invalid date fields Change-Id: I2048198d81ea4abf58b2b499b89495cd51b5c7ff diff --git a/sw/qa/extras/ooxmlexport/data/invalid_date_form_field.docx b/sw/qa/extras/ooxmlexport/data/invalid_date_form_field.docx new file mode 100644 index 000000000000..9dc24e768b0f Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/invalid_date_form_field.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index 8b2cab87042e..64de29ac9175 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -351,6 +351,83 @@ DECLARE_OOXMLIMPORT_TEST(testTdf121784, "tdf121784.docx") CPPUNIT_ASSERT_EQUAL( OUString( "i" ), getRun( getParagraph( 2 ), 3 )->getString()); } +DECLARE_OOXMLIMPORT_TEST(testInvalidDateFormField, "invalid_date_form_field.docx") +{ + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMarkAccess->getAllMarksCount()); + + int nIndex = 0; + for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) + { + ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*aIter); + + if(!pFieldmark) + continue; + + CPPUNIT_ASSERT(pFieldmark); + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + + // Check drop down field's parameters. + const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters(); + OUString sDateFormat; + auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT); + if (pResult != pParameters->end()) + { + pResult->second >>= sDateFormat; + } + + OUString sLang; + pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); + if (pResult != pParameters->end()) + { + pResult->second >>= sLang; + } + + OUString sCurrentDate; + pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); + if (pResult != pParameters->end()) + { + pResult->second >>= sCurrentDate; + } + + // The first one has invalid date format (invalid = LO can't parse it) + if(nIndex == 0) + { + + CPPUNIT_ASSERT_EQUAL(OUString("YYYY.MM.DDT00:00:00Z"), sDateFormat); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang); + CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL(sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pFieldmark->GetMarkStart().nContent.GetIndex()); + } + else if (nIndex == 1) // The second has wrong date + { + CPPUNIT_ASSERT_EQUAL(OUString("MM/DD/YY"), sDateFormat); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang); + CPPUNIT_ASSERT_EQUAL(OUString("2019.06.34"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL(sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(13), pFieldmark->GetMarkStart().nContent.GetIndex()); + } + else // The third one has wrong local + { + CPPUNIT_ASSERT_EQUAL(OUString("[NatNum12 MMMM=abbreviation]YYYY\". \"MMMM D."), sDateFormat); + CPPUNIT_ASSERT_EQUAL(OUString("xxxx"), sLang); + CPPUNIT_ASSERT_EQUAL(OUString("2019.06.11"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL(sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(23), pFieldmark->GetMarkStart().nContent.GetIndex()); + } + ++nIndex; + } + CPPUNIT_ASSERT_EQUAL(int(3), nIndex); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 25cd9566ed28da2c04bc304af6e8920bd0393503 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 14:24:08 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:14:02 2019 +0200 MSForms: date form field dialog: create the format entry if it does not exist Change-Id: I62da736efeabc2da634d9a7a38512d7e908b03fc diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx index a265dc130826..6b8fbaf35d38 100644 --- a/sw/source/ui/fldui/DateFormFieldDialog.cxx +++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx @@ -77,8 +77,19 @@ void DateFormFieldDialog::InitControls() { LanguageType aLangType = LanguageTag(sLang).getLanguageType(); sal_uInt32 nFormatKey = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType); + bool bValidFormat = nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND; + if (nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + SvNumFormatType nType; + bValidFormat = m_pNumberFormatter->PutEntry(sFormatString, + nCheckPos, + nType, + nFormatKey, + LanguageTag(sLang).getLanguageType()); + } - if(aLangType != LANGUAGE_DONTKNOW && nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND) + if(aLangType != LANGUAGE_DONTKNOW && bValidFormat) { if (m_xFormatLB->GetCurLanguage() == aLangType) { commit b7c5bfb0d9f34689840c8914675e3a74d95d362d Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 13:45:09 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:14:02 2019 +0200 MSForms: date field converions: better error handling Change-Id: Ia518c7c50079e443ddf135f1c32c5c39d2c85552 diff --git a/sw/source/core/crsr/DateFormFieldButton.cxx b/sw/source/core/crsr/DateFormFieldButton.cxx index 5ad43faf1ebb..f9586c14b3fb 100644 --- a/sw/source/core/crsr/DateFormFieldButton.cxx +++ b/sw/source/core/crsr/DateFormFieldButton.cxx @@ -55,24 +55,28 @@ SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* OUString sDateString; pResult->second >>= sDateString; - double dCurrentDate = 0; sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - m_pNumberFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bValidFormat = m_pNumberFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); } - m_pNumberFormatter->IsNumberFormat(sDateString, nFormat, dCurrentDate); + if (bValidFormat) + { + double dCurrentDate = 0; + m_pNumberFormatter->IsNumberFormat(sDateString, nFormat, dCurrentDate); - const Date& rNullDate = m_pNumberFormatter->GetNullDate(); - m_pCalendar->SetCurDate(rNullDate + dCurrentDate); + const Date& rNullDate = m_pNumberFormatter->GetNullDate(); + m_pCalendar->SetCurDate(rNullDate + dCurrentDate); + } } } m_pCalendar->SetSelectHdl(LINK(this, SwDatePickerDialog, ImplSelectHdl)); @@ -95,28 +99,33 @@ IMPL_LINK(SwDatePickerDialog, ImplSelectHdl, Calendar*, pCalendar, void) { if (m_pFieldmark != nullptr) { - Color* pCol = nullptr; - OUString sOutput; sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - m_pNumberFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bValidFormat = m_pNumberFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); } - const Date& rNullDate = m_pNumberFormatter->GetNullDate(); - double dDate = pCalendar->GetFirstSelectedDate() - rNullDate; + if (bValidFormat) + { + Color* pCol = nullptr; + OUString sOutput; - m_pNumberFormatter->GetOutputString(dDate, nFormat, sOutput, &pCol, false); + const Date& rNullDate = m_pNumberFormatter->GetNullDate(); + double dDate = pCalendar->GetFirstSelectedDate() - rNullDate; - sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters(); - (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= sOutput; + m_pNumberFormatter->GetOutputString(dDate, nFormat, sOutput, &pCol, false); + + sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters(); + (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= sOutput; + } } EndPopupMode(); } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 131ef946d8a6..9040eb3f6362 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -890,38 +890,48 @@ namespace sw { namespace mark { OUString sFormattedDate; pResult->second >>= sFormattedDate; - sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - pFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bValidFormat = pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + + if (bValidFormat) + { + pFormatter->IsNumberFormat(sFormattedDate, nFormat, dCurrentDate); + bHasCurrentDate = true; } - pFormatter->IsNumberFormat(sFormattedDate, nFormat, dCurrentDate); - bHasCurrentDate = true; } - Color* pCol = nullptr; if (!sDateFormat.isEmpty() && !sLang.isEmpty() && bHasCurrentDate) { - OUString sOutput; sal_uInt32 nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); + bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; - pFormatter->PutEntry(sDateFormat, - nCheckPos, - nType, - nFormat, - LanguageTag(sLang).getLanguageType()); + bValidFormat = pFormatter->PutEntry(sDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); + } + + OUString sOutput; + if (bValidFormat) + { + Color* pCol = nullptr; + pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); } - pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); return sOutput; } diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 0d1864115099..abd054ce32cb 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1908,36 +1908,45 @@ void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUSt double dCurrentDate = 0.0; // First get the date internal double representation - sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bool bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; - pFormatter->PutEntry(sFormat, - nCheckPos, - nType, - nFormat, - ODF_FORMDATE_CURRENTDATE_LANGUAGE); + bValidFormat = pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + if (bValidFormat) + { + pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate); } - pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate); // Then convert the date to a fromatter string - OUString sOutput; - Color* pCol = nullptr; nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); + bValidFormat = nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND; if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_Int32 nCheckPos = 0; SvNumFormatType nType; OUString sNonConstDateFormat = sDateFormat; - pFormatter->PutEntry(sNonConstDateFormat, - nCheckPos, - nType, - nFormat, - LanguageTag(sLang).getLanguageType()); + bValidFormat = pFormatter->PutEntry(sNonConstDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); + } + + OUString sOutput; + if (bValidFormat) + { + Color* pCol = nullptr; + pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); } - pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); RunText(sOutput); } diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx index e5cc6961b05e..a265dc130826 100644 --- a/sw/source/ui/fldui/DateFormFieldDialog.cxx +++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx @@ -78,20 +78,23 @@ void DateFormFieldDialog::InitControls() LanguageType aLangType = LanguageTag(sLang).getLanguageType(); sal_uInt32 nFormatKey = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType); - if (m_xFormatLB->GetCurLanguage() == aLangType) + if(aLangType != LANGUAGE_DONTKNOW && nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND) { - m_xFormatLB->SetAutomaticLanguage(true); - } - else - { - m_xFormatLB->SetAutomaticLanguage(false); - m_xFormatLB->SetLanguage(aLangType); + if (m_xFormatLB->GetCurLanguage() == aLangType) + { + m_xFormatLB->SetAutomaticLanguage(true); + } + else + { + m_xFormatLB->SetAutomaticLanguage(false); + m_xFormatLB->SetLanguage(aLangType); - // Change format and change back for regenerating the list - m_xFormatLB->SetFormatType(SvNumFormatType::ALL); - m_xFormatLB->SetFormatType(SvNumFormatType::DATE); + // Change format and change back for regenerating the list + m_xFormatLB->SetFormatType(SvNumFormatType::ALL); + m_xFormatLB->SetFormatType(SvNumFormatType::DATE); + } + m_xFormatLB->SetDefFormat(nFormatKey); } - m_xFormatLB->SetDefFormat(nFormatKey); } } } commit 864a034fdc70e05f7f453351f7ccd5c1e1c9fb4a Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 13:27:31 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:14:01 2019 +0200 MSForms: DOCX filter: reenable passing test Change-Id: Ic82e2edddce7e46740f74f7b20bb849b6735a3b8 diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index 3b7f928facdb..3d3c528ef41a 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -510,14 +510,14 @@ DECLARE_OOXMLEXPORT_TEST(testTableStart2Sdt, "table-start-2-sdt.docx") } } -/*DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx") +DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx") { if (xmlDocPtr pXmlDoc = parseExport()) { // Single <w:sdt> was exported as 2 <w:sdt> elements. assertXPath(pXmlDoc, "//w:sdt", 1); } -}*/ +} DECLARE_OOXMLEXPORT_TEST(testFdo81492, "fdo81492.docx") { commit 7e39851ce08d92de713694c8265fd7b0e1c64061 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Mon Jul 1 12:20:45 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:14:00 2019 +0200 MSForms: DOCX filter: handle export of empty date from control It's converted to date content control which is imported as text-based date control. By now, we don't need to set a dummy text for empty date. Change-Id: I29b2a72e3ae2722c1d765c4fcb9bd13052619372 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index d921551e5020..8b2cab87042e 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -14,6 +14,7 @@ #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> #include <IDocumentSettingAccess.hxx> +#include <xmloff/odffields.hxx> #include <editsh.hxx> @@ -138,24 +139,51 @@ DECLARE_OOXMLEXPORT_TEST(tdf123912_protectedForm, "tdf123912_protectedForm.odt") CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", false, getProperty<bool>(xSect, "IsProtected")); } -/*DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") +DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") { - // Check that we did not lost the date control - uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDraws->getCount()); - uno::Reference<drawing::XControlShape> xControl(getShape(1), uno::UNO_QUERY); - CPPUNIT_ASSERT(xControl->getControl().is()); - - // check XML - xmlDocPtr pXmlDoc = parseExport("word/document.xml"); - if (!pXmlDoc) - return; + // Check that we exported the empty date control correctly + // Date form field is converted to date content control. + if (!mbExported) + return ; + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + + + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount()); + ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*pMarkAccess->getAllMarksBegin()); + + CPPUNIT_ASSERT(pFieldmark); + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); - // We need to export date format and a dummy character (" ") for empty date control - assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:dateFormat", "val", "dd/MM/yyyy"); - assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", u" "); -}*/ + const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters(); + OUString sDateFormat; + auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT); + if (pResult != pParameters->end()) + { + pResult->second >>= sDateFormat; + } + + OUString sLang; + pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); + if (pResult != pParameters->end()) + { + pResult->second >>= sLang; + } + + OUString sCurrentDate; + pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); + if (pResult != pParameters->end()) + { + pResult->second >>= sCurrentDate; + } + + CPPUNIT_ASSERT_EQUAL(OUString("dd/MM/yyyy"), sDateFormat); + CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang); + CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate); +} DECLARE_OOXMLEXPORT_TEST(testTdf121867, "tdf121867.odt") { diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 1aecd9474600..0d1864115099 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5193,8 +5193,6 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) else { aContentText = xPropertySet->getPropertyValue("HelpText").get<OUString>(); - if(aContentText.isEmpty()) - aContentText = " "; // Need to write out something to have it imported by MS Word if(sDateFormat.isEmpty()) sDateFormat = "dd/MM/yyyy"; // Need to set date format even if there is no date set } commit 23fd89b9c0dc81d5d7436485f9124a0253a77399 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Fri Jun 28 15:40:31 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:14:00 2019 +0200 MSForms: DOCX import of text-based date field Before the date content control was imported as LO specific date form control, but now I changed it to be imported into the compatible text-based date field. Also removed the things stored in the grabbag, which are useless now. Disabled some unit tests, I'll update them for the new field in other patches. Change-Id: Ide8f4b27ec6b2dbb182abb4180229736bf9c434f diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 91300b73a7bc..1aecd9474600 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5174,34 +5174,8 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) { // gather component properties - Date aOriginalDate(Date::EMPTY); - OUString sOriginalContent, sDateFormat, sAlias; + OUString sDateFormat; OUString sLocale("en-US"); - uno::Sequence<beans::PropertyValue> aGrabBag; - uno::Reference<beans::XPropertySet> xShapePropertySet(pFormObj->getUnoShape(), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aCharFormat; - if (xShapePropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag) - { - for (sal_Int32 i=0; i < aGrabBag.getLength(); ++i) - { - if (aGrabBag[i].Name == "DateFormat") - aGrabBag[i].Value >>= sDateFormat; - else if (aGrabBag[i].Name == "Locale") - aGrabBag[i].Value >>= sLocale; - else if (aGrabBag[i].Name == "OriginalContent") - aGrabBag[i].Value >>= sOriginalContent; - else if (aGrabBag[i].Name == "OriginalDate") - { - css::util::Date aUNODate; - aGrabBag[i].Value >>= aUNODate; - aOriginalDate = aUNODate; - } - else if (aGrabBag[i].Name == "CharFormat") - aGrabBag[i].Value >>= aCharFormat; - else if (aGrabBag[i].Name == "ooxml:CT_SdtPr_alias") - aGrabBag[i].Value >>= sAlias; - } - } uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY); OString sDate; @@ -5213,17 +5187,8 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) bHasDate = true; Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year); sDate = DateToOString(aDate); - - if (aOriginalDate == aDate) - { - aContentText = sOriginalContent; - // sDateFormat was extracted from the grab bag - } - else - { - aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr()); - sDateFormat = "dd/MM/yyyy"; - } + aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr()); + sDateFormat = "dd/MM/yyyy"; } else { @@ -5239,10 +5204,6 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) m_pSerializer->startElementNS(XML_w, XML_sdt); m_pSerializer->startElementNS(XML_w, XML_sdtPr); - if (!sAlias.isEmpty()) - m_pSerializer->singleElementNS(XML_w, XML_alias, - FSNS(XML_w, XML_val), OUStringToOString(sAlias, RTL_TEXTENCODING_UTF8)); - if (bHasDate) m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), sDate); else @@ -5263,12 +5224,6 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject) m_pSerializer->startElementNS(XML_w, XML_sdtContent); m_pSerializer->startElementNS(XML_w, XML_r); - if (aCharFormat.hasElements()) - { - m_pTableStyleExport->SetSerializer(m_pSerializer); - m_pTableStyleExport->CharFormat(aCharFormat); - } - RunText(aContentText); m_pSerializer->endElementNS(XML_w, XML_r); m_pSerializer->endElementNS(XML_w, XML_sdtContent); commit 63cc04dc1554528040d072ea86cc79681f5202cb Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Tue Jul 2 21:09:25 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:09:25 2019 +0200 MSForms: DOCX import of text-based date field Before the date content control was imported as LO specific date form control, but now I changed it to be imported into the compatible text-based date field. Also removed the things stored in the grabbag, which are useless now. Disabled some unit tests, I'll update them for the new field in other patches. Change-Id: Ide8f4b27ec6b2dbb182abb4180229736bf9c434f diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 9bce252a7512..b25bbf7ae999 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -1244,8 +1244,7 @@ void Test::testDateFormField() { const OUString aFilterNames[] = { "writer8", - //"MS Word 97", - //"Office Open XML Text", + "Office Open XML Text", }; for (const OUString& rFilterName : aFilterNames) @@ -1273,7 +1272,10 @@ void Test::testDateFormField() SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(3), pMarkAccess->getAllMarksCount()); + if(rFilterName == "Office Open XML Text") + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(6), pMarkAccess->getAllMarksCount()); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(3), pMarkAccess->getAllMarksCount()); int nIndex = 0; for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) @@ -1316,18 +1318,28 @@ void Test::testDateFormField() CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(""), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pFieldmark->GetMarkStart().nContent.GetIndex()); } else if (nIndex == 1) // The second has the default format { CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-12"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(13), pFieldmark->GetMarkStart().nContent.GetIndex()); } else // The third one has special format { CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[NatNum12 MMMM=abbreviation]YYYY\". \"MMMM D."), sDateFormat); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("hu-HU"), sLang); CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-11"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(23), pFieldmark->GetMarkStart().nContent.GetIndex()); + } ++nIndex; } diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 23eb22cb8d03..bd1cf12450af 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -71,7 +71,7 @@ DECLARE_OOXMLEXPORT_TEST(testSdtAlias, "sdt-alias.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:alias", "val", "Subtitle"); } -DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx") +/*DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx") { if (xmlDocPtr pXmlDoc = parseExport()) { @@ -80,7 +80,7 @@ DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx") // alias was also missing. assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:alias", 1); } -} +}*/ DECLARE_OOXMLEXPORT_TEST(testFooterBodyDistance, "footer-body-distance.docx") { diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index edbc0964685d..d921551e5020 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -138,7 +138,7 @@ DECLARE_OOXMLEXPORT_TEST(tdf123912_protectedForm, "tdf123912_protectedForm.odt") CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", false, getProperty<bool>(xSect, "IsProtected")); } -DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") +/*DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") { // Check that we did not lost the date control uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); @@ -155,7 +155,7 @@ DECLARE_OOXMLEXPORT_TEST(testDateControl, "empty-date-control.odt") // We need to export date format and a dummy character (" ") for empty date control assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:dateFormat", "val", "dd/MM/yyyy"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", u" "); -} +}*/ DECLARE_OOXMLEXPORT_TEST(testTdf121867, "tdf121867.odt") { diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx index 9405ff7e29bc..c6d67de8bd25 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx @@ -661,7 +661,7 @@ DECLARE_OOXMLEXPORT_TEST(testTableCurruption, "tableCurrupt.docx") CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), aHeaderBottomBorder.LineWidth); } -DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") +/*DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") { // check XML xmlDocPtr pXmlDoc = parseExport("word/document.xml"); @@ -671,14 +671,7 @@ DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:dateFormat", "val", "dddd, dd' de 'MMMM' de 'yyyy"); assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:lid", "val", "es-ES"); assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", u"mi\u00E9rcoles, 05 de marzo de 2014"); - - // check imported control - uno::Reference<drawing::XControlShape> xControl(getShape(1), uno::UNO_QUERY); - util::Date aDate = getProperty<util::Date>(xControl->getControl(), "Date"); - CPPUNIT_ASSERT_EQUAL(sal_Int32(5), sal_Int32(aDate.Day)); - CPPUNIT_ASSERT_EQUAL(sal_Int32(3), sal_Int32(aDate.Month)); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2014), sal_Int32(aDate.Year)); -} +}*/ DECLARE_OOXMLEXPORT_TEST(test_OpeningBrace, "2120112713_OpenBrace.docx") { diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index f798ad98000e..2d717f106b54 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -527,21 +527,21 @@ DECLARE_OOXMLEXPORT_TEST(testN780563, "n780563.docx") CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount( )); } -DECLARE_OOXMLEXPORT_TEST(testN780853, "n780853.docx") -{ +/*DECLARE_OOXMLEXPORT_TEST(testN780853, "n780853.docx") +{*/ /* * The problem was that the table was not imported. * * xray ThisComponent.TextTables.Count 'was 0 */ - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + /*uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount()); //tdf#102619 - I would have expected this to be "Standard", but MSO 2013/2010/2003 all give FollowStyle==Date uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("Date"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("Date"), getProperty<OUString>(properties, "FollowStyle")); -} +}*/ DECLARE_OOXMLEXPORT_TEST(testN780843, "n780843.docx") { @@ -919,19 +919,10 @@ DECLARE_OOXMLEXPORT_TEST(testN592908_Picture, "n592908-picture.docx") DECLARE_OOXMLEXPORT_TEST(testN779630, "n779630.docx") { - // First shape: date picker + // A combo box is imported 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_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.DateField"))); - CPPUNIT_ASSERT_EQUAL(OUString("date default text"), getProperty<OUString>(xPropertySet, "HelpText")); - CPPUNIT_ASSERT_EQUAL(sal_Int16(8), getProperty<sal_Int16>(xPropertySet, "DateFormat")); - CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPropertySet, "Dropdown")); - - // Second shape: combo box - xControlShape.set(getShape(2), uno::UNO_QUERY); - xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY); - xServiceInfo.set(xPropertySet, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.ComboBox"))); CPPUNIT_ASSERT_EQUAL(OUString("dropdown default text"), getProperty<OUString>(xPropertySet, "DefaultText")); CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty< uno::Sequence<OUString> >(xPropertySet, "StringItemList").getLength()); @@ -967,7 +958,7 @@ DECLARE_OOXMLEXPORT_TEST(testN816593, "n816593.docx") CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount()); } -DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") +/*DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") { // Design mode was enabled. uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); @@ -979,7 +970,7 @@ DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY); uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int16(8), getProperty<sal_Int16>(xPropertySet, "DateFormat")); -} +}*/ DECLARE_OOXMLEXPORT_TEST(testN830205, "n830205.docx") { diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index b5b6b6040216..3b7f928facdb 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -510,14 +510,14 @@ DECLARE_OOXMLEXPORT_TEST(testTableStart2Sdt, "table-start-2-sdt.docx") } } -DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx") +/*DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx") { if (xmlDocPtr pXmlDoc = parseExport()) { // Single <w:sdt> was exported as 2 <w:sdt> elements. assertXPath(pXmlDoc, "//w:sdt", 1); } -} +}*/ DECLARE_OOXMLEXPORT_TEST(testFdo81492, "fdo81492.docx") { @@ -589,13 +589,13 @@ DECLARE_OOXMLEXPORT_TEST(testfdo82492, "fdo82492.docx") assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent/w:r",1); } -DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx") +/*DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx") { // Problem was that w:sdt elements in headers were lost on import. if (xmlDocPtr pXmlDoc = parseExport("word/header1.xml")) // This was 0, w:sdt (and then w:date) was missing. assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1); -} +}*/ DECLARE_OOXMLEXPORT_TEST(testSdtCompanyMultipara, "sdt-company-multipara.docx") { diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index 1c7282623b00..0a989161fba6 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -34,13 +34,13 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108545_embeddedDocxIcon, "tdf108545_embeddedDocx CPPUNIT_ASSERT_EQUAL(embed::Aspects::MSOLE_ICON, xSupplier->getAspect()); } -DECLARE_OOXMLIMPORT_TEST(testTdf121203, "tdf121203.docx") +/*DECLARE_OOXMLIMPORT_TEST(testTdf121203, "tdf121203.docx") { // Make sure that the date SDT's content is imported as plain text, as it // has no ISO date, so we have no idea how to represent that with our date // control. CPPUNIT_ASSERT_EQUAL(OUString("17-Oct-2018 09:00"), getRun(getParagraph(1), 1)->getString()); -} +}*/ DECLARE_OOXMLIMPORT_TEST(testTdf109053, "tdf109053.docx") { diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 08bb7e2e690b..91300b73a7bc 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -8929,28 +8929,6 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) } else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id") m_bParagraphSdtHasId = true; - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_date") - { - m_nParagraphSdtPrToken = FSNS(XML_w, XML_date); - uno::Sequence<beans::PropertyValue> aGrabBag = aPropertyValue.Value.get< uno::Sequence<beans::PropertyValue> >(); - for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j) - { - OString sValue = OUStringToOString(aGrabBag[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8); - - if (aGrabBag[j].Name == "ooxml:CT_SdtDate_fullDate") - AddToAttrList(m_pParagraphSdtPrTokenAttributes, FSNS(XML_w, XML_fullDate), sValue.getStr()); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_dateFormat") - AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_dateFormat), sValue.getStr()); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_lid") - AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_lid), sValue.getStr()); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_storeMappedDataAs") - AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_storeMappedDataAs), sValue.getStr()); - else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_calendar") - AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_calendar), sValue.getStr()); - else - SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr / ooxml:CT_SdtPr_date grab bag property " << aGrabBag[j].Name); - } - } else SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr grab bag property " << aPropertyValue.Name); } diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 6276d56a1b01..749102c4e903 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1018,6 +1018,8 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) if (!m_pImpl->m_pSdtHelper->getDropDownItems().empty()) m_pImpl->m_pSdtHelper->createDropDownControl(); + else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) + m_pImpl->m_pSdtHelper->createDateContentControl(); break; case NS_ooxml::LN_CT_SdtListItem_displayText: // TODO handle when this is != value @@ -2423,16 +2425,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) break; case NS_ooxml::LN_CT_SdtPr_date: { - if (!IsInHeaderFooter()) - resolveSprmProps(*this, rSprm); - else - { - OUString sName = "ooxml:CT_SdtPr_date"; - enableInteropGrabBag(sName); - resolveSprmProps(*this, rSprm); - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag()); - m_pImpl->disableInteropGrabBag(); - } + resolveSprmProps(*this, rSprm); } break; case NS_ooxml::LN_CT_SdtDate_dateFormat: @@ -3226,12 +3219,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) // Form controls are not allowed in headers / footers; see sw::DocumentContentOperationsManager::InsertDrawObj() else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) { - /* - * Here we assume w:sdt only contains a single text token. We need to - * create the control early, as in Writer, it's part of the cell, but - * in OOXML, the sdt contains the cell. - */ - m_pImpl->m_pSdtHelper->createDateControl(sText, getInteropGrabBag()); + // date field is imported, we don't need the corresponding date text return; } else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty()) @@ -3248,7 +3236,6 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_date") || (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") && m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph()) { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index eb852bf943d4..258b829aafc7 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -617,6 +617,10 @@ PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId) return pRet; } +bool DomainMapper_Impl::HasTopText() const +{ + return !m_aTextAppendStack.empty(); +} uno::Reference< text::XTextAppend > const & DomainMapper_Impl::GetTopTextAppend() { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 793631530d66..a98e24cf180b 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -666,6 +666,7 @@ public: } PropertyMapPtr GetTopContextOfType(ContextType eId); + bool HasTopText() const; css::uno::Reference<css::text::XTextAppend> const & GetTopTextAppend(); FieldContextPtr const & GetTopFieldContext(); diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index 0b870749313b..c55ceaec0d65 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -21,30 +21,11 @@ #include <vcl/outdev.hxx> #include <unotools/datetime.hxx> #include <comphelper/sequence.hxx> +#include <xmloff/odffields.hxx> #include "DomainMapper_Impl.hxx" #include "StyleSheetTable.hxx" -namespace -{ -/// Maps OOXML <w:dateFormat> values to UNO date format values. -sal_Int16 getUNODateFormat(const OUString& rDateFormat) -{ - // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly - // there are no constants. - sal_Int16 nDateFormat = -1; - - if (rDateFormat == "M/d/yyyy" || rDateFormat == "M.d.yyyy") - // MMDDYYYY - nDateFormat = 8; - else if (rDateFormat == "dd/MM/yyyy") - // DDMMYYYY - nDateFormat = 7; - - return nDateFormat; -} -} - namespace writerfilter { namespace dmapper @@ -115,70 +96,46 @@ void SdtHelper::createDropDownControl() bool SdtHelper::validateDateFormat() { - bool bRet = !m_sDate.isEmpty() || getUNODateFormat(m_sDateFormat.toString()) != -1; - if (!bRet) - m_sDateFormat.setLength(0); - return bRet; + return !m_sDateFormat.toString().isEmpty() && !m_sLocale.toString().isEmpty(); } -void SdtHelper::createDateControl(OUString const& rContentText, const beans::PropertyValue& rCharFormat) +void SdtHelper::createDateContentControl() { - uno::Reference<awt::XControlModel> xControlModel; - try + uno::Reference<text::XTextCursor> xCrsr; + if(m_rDM_Impl.HasTopText()) { - xControlModel.set(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY_THROW); + uno::Reference<text::XTextAppend> xTextAppend = m_rDM_Impl.GetTopTextAppend(); + if (xTextAppend.is()) + xCrsr = xTextAppend->createTextCursorByRange(xTextAppend->getEnd()); } - catch (css::uno::RuntimeException&) + if (xCrsr.is()) { - throw; + uno::Reference< uno::XInterface > xFieldInterface; + xFieldInterface = m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.text.FormFieldmark"); + uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY ); + uno::Reference< text::XTextContent > xToInsert(xFormField, uno::UNO_QUERY); + if ( xFormField.is() && xToInsert.is() ) + { + xCrsr->gotoEnd(true); + xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW )); + xFormField->setFieldType(ODF_FORMDATE); + uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); + if(xNameCont.is()) + { + xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, uno::makeAny(m_sDateFormat.makeStringAndClear())); + xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT_LANGUAGE, uno::makeAny(m_sLocale.makeStringAndClear())); + OUString sDate = m_sDate.makeStringAndClear(); + if(!sDate.isEmpty()) + { + // Remove time part of the full date + sal_Int32 nTimeSep = sDate.indexOf("T"); + if(nTimeSep != -1) + sDate = sDate.copy(0, nTimeSep); + xNameCont->insertByName(ODF_FORMDATE_CURRENTDATE, uno::makeAny(sDate)); + } + } + } } - catch (css::uno::Exception& e) - { - css::uno::Any a(cppu::getCaughtException()); - throw css::lang::WrappedTargetRuntimeException("wrapped " + a.getValueTypeName() + ": " + e.Message, css::uno::Reference<css::uno::XInterface>(), a); - } - uno::Reference<beans::XPropertySet> xPropertySet( - xControlModel, uno::UNO_QUERY_THROW); - - xPropertySet->setPropertyValue("Dropdown", uno::makeAny(true)); - - // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants - OUString sDateFormat = m_sDateFormat.makeStringAndClear(); - sal_Int16 nDateFormat = getUNODateFormat(sDateFormat); - if (nDateFormat == -1) - { - // Set default format, so at least the date picker is created. - SAL_WARN("writerfilter", "unhandled w:dateFormat value"); - if (m_sDate.isEmpty()) - return; - nDateFormat = 0; - } - xPropertySet->setPropertyValue("DateFormat", uno::makeAny(nDateFormat)); - - util::Date aDate; - util::DateTime aDateTime; - if (utl::ISO8601parseDateTime(m_sDate.makeStringAndClear(), aDateTime)) - { - utl::extractDate(aDateTime, aDate); - xPropertySet->setPropertyValue("Date", uno::makeAny(aDate)); - } - else - xPropertySet->setPropertyValue("HelpText", uno::makeAny(rContentText.trim())); - - // append date format to grab bag - comphelper::SequenceAsHashMap aGrabBag; - aGrabBag["OriginalDate"] <<= aDate; - aGrabBag["OriginalContent"] <<= rContentText; - aGrabBag["DateFormat"] <<= sDateFormat; - aGrabBag["Locale"] <<= m_sLocale.makeStringAndClear(); - aGrabBag["CharFormat"] = rCharFormat.Value; - // merge in properties like ooxml:CT_SdtPr_alias and friends. - aGrabBag.update(comphelper::SequenceAsHashMap(comphelper::containerToSequence(m_aGrabBag))); - // and empty the property list, so they won't end up on the next sdt as well - m_aGrabBag.clear(); - - std::vector<OUString> aItems; - createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel, aGrabBag.getAsConstPropertyValueList()); } void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> const& xControlModel, const uno::Sequence<beans::PropertyValue>& rGrabBag) diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 91f005f9d544..01abd4117adb 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -114,7 +114,7 @@ public: /// Create drop-down control from w:sdt's w:dropDownList. void createDropDownControl(); /// Create date control from w:sdt's w:date. - void createDateControl(OUString const& rContentText, const css::beans::PropertyValue& rCharFormat); + void createDateContentControl(); void appendToInteropGrabBag(const css::beans::PropertyValue& rValue); css::uno::Sequence<css::beans::PropertyValue> getInteropGrabBagAndClear(); commit d0ff65b24610b2808a34e56784a39f9eb340f822 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Fri Jun 21 20:40:27 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:08:36 2019 +0200 MSForms: DOCX export of date content control Change-Id: I546af6d552e5e3801925285d0095fc8502896a15 diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 6e7fa0632e0d..08bb7e2e690b 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -238,6 +238,7 @@ public: m_pSerializer->endElementNS( XML_w, XML_checkBox ); writeFinish(); } + void WriteFormText( const OUString& rName, const OUString& rEntryMacro, const OUString& rExitMacro, @@ -1870,6 +1871,84 @@ void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos ) } } +void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang) +{ + m_pSerializer->startElementNS(XML_w, XML_sdt); + m_pSerializer->startElementNS(XML_w, XML_sdtPr); + + if (!sCurrentDate.isEmpty()) + { + OString sDate = sCurrentDate.toUtf8() + "T00:00:00Z"; + m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), sDate); + } + else + m_pSerializer->startElementNS(XML_w, XML_date); + + m_pSerializer->singleElementNS(XML_w, XML_dateFormat, + FSNS(XML_w, XML_val), sDateFormat.toUtf8()); + m_pSerializer->singleElementNS(XML_w, XML_lid, + FSNS(XML_w, XML_val), sLang.toUtf8()); + m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs, + FSNS(XML_w, XML_val), "dateTime"); + m_pSerializer->singleElementNS(XML_w, XML_calendar, + FSNS(XML_w, XML_val), "gregorian"); + + m_pSerializer->endElementNS(XML_w, XML_date); + m_pSerializer->endElementNS(XML_w, XML_sdtPr); + + m_pSerializer->startElementNS(XML_w, XML_sdtContent); + m_pSerializer->startElementNS(XML_w, XML_r); + + if (!sCurrentDate.isEmpty()) + { + // Convert the current date to the right format + if (!sCurrentDate.isEmpty()) + { + SvNumberFormatter* pFormatter = m_rExport.m_pDoc->GetNumberFormatter(); + + double dCurrentDate = 0.0; + // First get the date internal double representation + sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + SvNumFormatType nType; + OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; + pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate); + + // Then convert the date to a fromatter string + OUString sOutput; + Color* pCol = nullptr; + nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + SvNumFormatType nType; + OUString sNonConstDateFormat = sDateFormat; + pFormatter->PutEntry(sNonConstDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); + } + pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false); + + RunText(sOutput); + } + } + + m_pSerializer->endElementNS(XML_w, XML_r); + m_pSerializer->endElementNS(XML_w, XML_sdtContent); + + m_pSerializer->endElementNS(XML_w, XML_sdt); +} + void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun ) { if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN ) @@ -1877,6 +1956,20 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP // Expand unsupported fields RunText( rInfos.pField->GetFieldName() ); } + else if ( rInfos.eType == ww::eFORMDATE ) + { + const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark; + FieldMarkParamsHelper params( rFieldmark ); + + OUString sCurrentDate; + params.extractParam( ODF_FORMDATE_CURRENTDATE, sCurrentDate ); + OUString sDateFormat; + params.extractParam( ODF_FORMDATE_DATEFORMAT, sDateFormat ); + OUString sLang; + params.extractParam( ODF_FORMDATE_DATEFORMAT_LANGUAGE, sLang ); + + WriteFormDate( sCurrentDate, sDateFormat, sLang ); + } else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands { if ( bWriteRun ) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 2ea64b8f207b..189a2400d8d6 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -706,6 +706,8 @@ private: /// Closes a currently open SDT block. void EndSdtBlock(); + void WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang); + void StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun = false ); void DoWriteCmd( const OUString& rCmd ); void CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun ); diff --git a/sw/source/filter/ww8/fields.hxx b/sw/source/filter/ww8/fields.hxx index 4bdd5641d8c4..8e24ca11d37b 100644 --- a/sw/source/filter/ww8/fields.hxx +++ b/sw/source/filter/ww8/fields.hxx @@ -124,7 +124,8 @@ namespace ww // NOTE: values > 95 / 0x5F do not correspond to documented WW8 fields // and thus need special handling in WW8Export::OutputField()! eBIBLIOGRPAHY=96, - eCITATION = 97 + eCITATION = 97, + eFORMDATE = 98, }; /** Find the English Field Name from a winword index diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index dc7e4e18c6e8..293da7625a8e 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -128,6 +128,8 @@ static OUString lcl_getFieldCode( const IFieldmark* pFieldmark ) return OUString(" FORMDROPDOWN "); if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) return OUString(" FORMCHECKBOX "); + if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE ) + return OUString(" ODFFORMDATE "); if ( pFieldmark->GetFieldname( ) == ODF_TOC ) return OUString(" TOC "); if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) @@ -147,6 +149,8 @@ static ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) { return ww::eFORMDROPDOWN; if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) return ww::eFORMCHECKBOX; + if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE ) + return ww::eFORMDATE; if ( pFieldmark->GetFieldname( ) == ODF_TOC ) return ww::eTOC; if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) @@ -2380,21 +2384,31 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) { SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) ); ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition ); - OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" ); - - bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN || - pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ); - if ( isDropdownOrCheckbox ) - AppendBookmark( pFieldmark->GetName() ); - OutputField( nullptr, lcl_getFieldId( pFieldmark ), - lcl_getFieldCode( pFieldmark ), - FieldFlags::Start | FieldFlags::CmdStart ); - if ( isDropdownOrCheckbox ) + // Date field is exported as content control, not as a simple field + if(pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMDATE && + GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only + { + OutputField( nullptr, lcl_getFieldId( pFieldmark ), + lcl_getFieldCode( pFieldmark ), + FieldFlags::Start | FieldFlags::CmdStart ); WriteFormData( *pFieldmark ); - OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close ); - if ( isDropdownOrCheckbox ) - AppendBookmark( pFieldmark->GetName() ); + } + else + { + bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN || + pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ); + if ( isDropdownOrCheckbox ) + AppendBookmark( pFieldmark->GetName() ); + OutputField( nullptr, lcl_getFieldId( pFieldmark ), + lcl_getFieldCode( pFieldmark ), + FieldFlags::Start | FieldFlags::CmdStart ); + if ( isDropdownOrCheckbox ) + WriteFormData( *pFieldmark ); + OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close ); + if ( isDropdownOrCheckbox ) + AppendBookmark( pFieldmark->GetName() ); + } } nLen -= ofs; commit 937bd70aa7633086f43be841e6ee8a188664bbc8 Author: Tamás Zolnai <tamas.zol...@collabora.com> AuthorDate: Fri Jun 21 17:56:30 2019 +0200 Commit: Tamás Zolnai <tamas.zol...@collabora.com> CommitDate: Tue Jul 2 21:08:29 2019 +0200 MSForms: ODF import / export of text based date field Change-Id: Ib535f1ce065a7f298fcccf95e82d1ffab4d1e1e2 diff --git a/sw/qa/extras/globalfilter/data/date_form_field.odt b/sw/qa/extras/globalfilter/data/date_form_field.odt new file mode 100644 index 000000000000..8e15793c2d59 Binary files /dev/null and b/sw/qa/extras/globalfilter/data/date_form_field.odt differ diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 012e16eb3de2..9bce252a7512 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -50,6 +50,7 @@ public: void testTextFormField(); void testCheckBoxFormField(); void testDropDownFormField(); + void testDateFormField(); CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testEmbeddedGraphicRoundtrip); @@ -68,6 +69,7 @@ public: CPPUNIT_TEST(testTextFormField); CPPUNIT_TEST(testCheckBoxFormField); CPPUNIT_TEST(testDropDownFormField); + CPPUNIT_TEST(testDateFormField); CPPUNIT_TEST_SUITE_END(); }; @@ -1238,6 +1240,101 @@ void Test::testDropDownFormField() } } +void Test::testDateFormField() +{ + const OUString aFilterNames[] = { + "writer8", + //"MS Word 97", + //"Office Open XML Text", + }; + + for (const OUString& rFilterName : aFilterNames) + { + if (mxComponent.is()) + mxComponent->dispose(); + mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/date_form_field.odt"), "com.sun.star.text.TextDocument"); + + const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8(); + + // Export the document and import again for a check + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= rFilterName; + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY); + xComponent->dispose(); + mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument"); + + // Check the document after round trip ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits