sw/qa/extras/globalfilter/globalfilter.cxx | 276 +++++++++++++++------- sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 97 ++----- sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 54 +++- sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 136 ++++++++-- sw/qa/extras/ooxmlimport/ooxmlimport2.cxx | 42 +-- sw/source/filter/ww8/docxattributeoutput.cxx | 2 writerfilter/source/dmapper/DomainMapper.cxx | 35 ++ writerfilter/source/dmapper/DomainMapper_Impl.cxx | 50 +++ writerfilter/source/dmapper/SdtHelper.cxx | 11 writerfilter/source/dmapper/SdtHelper.hxx | 17 + 10 files changed, 495 insertions(+), 225 deletions(-)
New commits: commit 5ee8670f18cb8b1913a23d04590d6a31ac9730de Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon May 30 09:00:25 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon May 30 09:36:51 2022 +0200 sw content controls, date: add DOCX import - map <w:date> <w:dateFormat w:val="..."/> <w:lid w:val="..."/> </w:date> to the Date, DateFormat and DateLanguage UNO properties of content controls instead of fieldmarks, which model content controls poorly - fix CppunitTest_sw_ooxmlexport8's testN820509: date SDT is now a content control - add current date DOCX import - fix CppunitTest_sw_ooxmlexport13's testDateControl: date SDT is now a content control - fix CppunitTest_sw_ooxmlexport13's testInvalidDateFormField: date SDT is now a content control - fix CppunitTest_sw_ooxmlexport5's testfdo83048: minimal support for nested SDTs in DomainMapper::lcl_attribute() - fix CppunitTest_sw_ooxmlfieldexport's testDateFieldAtEndOfParagraph: date SDT is now a content control - fix CppunitTest_sw_ooxmlfieldexport's testDateFieldInShape: date SDT is now a content control - fix CppunitTest_sw_ooxmlfieldexport's testSdtDateDuplicate: date SDT is now a content control - fix CppunitTest_sw_ooxmlfieldexport's testSdtDatePicker: - retain placeholder - retain data binding - retain color - fix CppunitTest_sw_ooxmlimport2's testTdf121203: date SDT is now a content control - fix CppunitTest_sw_globalfilter's testDateFormFieldCharacterFormatting: date SDT is now a content control - fix CppunitTest_sw_globalfilter's testDateFormField: date SDT is now a content control Change-Id: I5a4c34217d23ed6fa0916e4dd6290351456b7232 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135109 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index ae720f503f56..ebe5abb81804 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -1650,92 +1650,170 @@ void Test::testDateFormField() mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument"); // Check the document after round trip - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pMarkAccess->getAllMarksCount()); - - int nIndex = 0; - for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) + if (rFilterName == "writer8") { - ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*aIter); - CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - // Check date form 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; - } + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pMarkAccess->getAllMarksCount()); - OUString sLang; - pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); - if (pResult != pParameters->end()) + int nIndex = 0; + for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) { - pResult->second >>= sLang; - } + ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*aIter); + CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + + // Check date form 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 sCurrentDate = pFieldmark->GetContent(); + OUString sLang; + pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); + if (pResult != pParameters->end()) + { + pResult->second >>= sLang; + } - // The first one has the default field content - if(nIndex == 0) - { + OUString sCurrentDate = pFieldmark->GetContent(); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang); - sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194}; - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), sCurrentDate); + // The first one has the default field content + if(nIndex == 0) + { - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(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("06/12/19"), sCurrentDate); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang); + sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194}; + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), sCurrentDate); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(20), pFieldmark->GetMarkStart().nContent.GetIndex()); - } - else if (nIndex == 2) // 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. febr. 12."), sCurrentDate); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(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("06/12/19"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(20), pFieldmark->GetMarkStart().nContent.GetIndex()); + } + else if (nIndex == 2) // 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. febr. 12."), sCurrentDate); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(40), pFieldmark->GetMarkStart().nContent.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(40), pFieldmark->GetMarkStart().nContent.GetIndex()); - } - else if (nIndex == 3) // The fourth one has placeholder text - { - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("D, MMM YY"), sDateFormat); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("bm-ML"), sLang); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[select date]"), sCurrentDate); + } + else if (nIndex == 3) // The fourth one has placeholder text + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("D, MMM YY"), sDateFormat); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("bm-ML"), sLang); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[select date]"), sCurrentDate); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(62), pFieldmark->GetMarkStart().nContent.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(62), pFieldmark->GetMarkStart().nContent.GetIndex()); + } + else // The last one is really empty + { + 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(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(82), pFieldmark->GetMarkStart().nContent.GetIndex()); + + } + ++nIndex; } - else // The last one is really empty + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(5), nIndex); + } + else + { + // Import from DOCX, so the fieldmark is now a content control. + uno::Reference<container::XEnumerationAccess> xEnumAccess(getParagraph(1), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xTextPortions = xEnumAccess->createEnumeration(); + + int nIndex = 0; + while (xTextPortions->hasMoreElements()) { - 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); + uno::Reference<beans::XPropertySet> xTextPortion(xTextPortions->nextElement(), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + if (aPortionType != "ContentControl") + { + continue; + } - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(82), pFieldmark->GetMarkStart().nContent.GetIndex()); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + + // Check date form field's parameters. + OUString sDateFormat; + xContentControlProps->getPropertyValue("DateFormat") >>= sDateFormat; + + OUString sLang; + xContentControlProps->getPropertyValue("DateLanguage") >>= sLang; + + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum + = xContentControlEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xContentControlTextPortion(xContentControlEnum->nextElement(), uno::UNO_QUERY); + OUString sCurrentDate = xContentControlTextPortion->getString(); + + // The first one has the default field content + if(nIndex == 0) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang); + sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194}; + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), sCurrentDate); + } + 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("06/12/19"), sCurrentDate); + } + else if (nIndex == 2) // 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. febr. 12."), sCurrentDate); + } + else if (nIndex == 3) // The fourth one has placeholder text + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("D, MMM YY"), sDateFormat); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("bm-ML"), sLang); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[select date]"), sCurrentDate); + } + else // The last one is really empty + { + 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); + } + ++nIndex; } - ++nIndex; + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(5), nIndex); } - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(5), nIndex); } } @@ -1766,24 +1844,52 @@ void Test::testDateFormFieldCharacterFormatting() mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument"); // Check the document after round trip - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - - // Check that we have the field at the right place - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(1), pMarkAccess->getAllMarksCount()); - ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0), pFieldmark->GetMarkStart().nContent.GetIndex()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(11), pFieldmark->GetMarkEnd().nContent.GetIndex()); - - // We have one date field, first half of the field has bold character weight and second part has red character color - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(1), 3), "CharWeight")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), COL_AUTO, getProperty<Color>(getRun(getParagraph(1), 3), "CharColor")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(getRun(getParagraph(1), 4), "CharWeight")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), Color(0xff0000), getProperty<Color>(getRun(getParagraph(1), 4), "CharColor")); + if (rFilterName == "writer8") + { + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + + // Check that we have the field at the right place + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(1), pMarkAccess->getAllMarksCount()); + ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); + CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0), pFieldmark->GetMarkStart().nContent.GetIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(11), pFieldmark->GetMarkEnd().nContent.GetIndex()); + + // We have one date field, first half of the field has bold character weight and second part has red character color + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(1), 3), "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), COL_AUTO, getProperty<Color>(getRun(getParagraph(1), 3), "CharColor")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(getRun(getParagraph(1), 4), "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), Color(0xff0000), getProperty<Color>(getRun(getParagraph(1), 4), "CharColor")); + } + else + { + uno::Reference<beans::XPropertySet> xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum + = xContentControlEnumAccess->createEnumeration(); + xTextPortion.set(xContentControlEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(xTextPortion, "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), COL_AUTO, getProperty<Color>(xTextPortion, "CharColor")); + xTextPortion.set(xContentControlEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(xTextPortion, "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), Color(0xff0000), getProperty<Color>(xTextPortion, "CharColor")); + } } } diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index 0435f4254f1b..e3525b5991ab 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -528,39 +528,25 @@ CPPUNIT_TEST_FIXTURE(Test, testDateControl) // Check that we exported the empty date control correctly // Date form field is converted to date content control. - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - + uno::Reference<beans::XPropertySet> xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); - 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()); - - 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; - } + xContentControlProps->getPropertyValue("DateFormat") >>= sDateFormat; OUString sLang; - pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); - if (pResult != pParameters->end()) - { - pResult->second >>= sLang; - } + xContentControlProps->getPropertyValue("DateLanguage") >>= sLang; OUString sCurrentDate; - pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); - if (pResult != pParameters->end()) - { - pResult->second >>= sCurrentDate; - } + xContentControlProps->getPropertyValue("CurrentDate") >>= sCurrentDate; CPPUNIT_ASSERT_EQUAL(OUString("dd/MM/yyyy"), sDateFormat); CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang); @@ -1033,45 +1019,36 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf121663) DECLARE_OOXMLEXPORT_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()); + uno::Reference<container::XEnumerationAccess> xParagraph(getParagraph(1), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration(); int nIndex = 0; - for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter) + while (xPortions->hasMoreElements()) { - ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*aIter); - - if(!pFieldmark) + uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + if (aPortionType != "ContentControl") + { continue; + } - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); - // Check date field's parameters. - const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters(); + // Check date content control's parameters. OUString sDateFormat; - auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT); - if (pResult != pParameters->end()) - { - pResult->second >>= sDateFormat; - } + xContentControlProps->getPropertyValue("DateFormat") >>= sDateFormat; OUString sLang; - pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); - if (pResult != pParameters->end()) - { - pResult->second >>= sLang; - } + xContentControlProps->getPropertyValue("DateLanguage") >>= sLang; OUString sCurrentDate; - pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); - if (pResult != pParameters->end()) - { - pResult->second >>= sCurrentDate; - } + xContentControlProps->getPropertyValue("CurrentDate") >>= sCurrentDate; // The first one has invalid date format (invalid = LO can't parse it) if(nIndex == 0) @@ -1081,26 +1058,20 @@ DECLARE_OOXMLEXPORT_TEST(testInvalidDateFormField, "invalid_date_form_field.docx CPPUNIT_ASSERT_EQUAL(OUString("en-US"), sLang); CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate); - CPPUNIT_ASSERT_EQUAL(SwNodeOffset(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(OUString("2019.06.34T00:00:00Z"), sCurrentDate); - CPPUNIT_ASSERT_EQUAL(SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL(sal_Int32(15), 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(OUString("2019.06.11T00:00:00Z"), sCurrentDate); - CPPUNIT_ASSERT_EQUAL(SwNodeOffset(9), pFieldmark->GetMarkStart().nNode.GetIndex()); - CPPUNIT_ASSERT_EQUAL(sal_Int32(35), pFieldmark->GetMarkStart().nContent.GetIndex()); } ++nIndex; } diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index b52c25c01544..62c754af3d0f 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -999,23 +999,51 @@ DECLARE_OOXMLEXPORT_TEST(testN820509, "n820509.docx") // M.d.yyyy date format was unhandled. SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); + if (mbExported) + { + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); + uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xCell, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration(); + uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + OUString aDateFormat; + xContentControlProps->getPropertyValue("DateFormat") >>= aDateFormat; + CPPUNIT_ASSERT_EQUAL(OUString("M.d.yyyy"), aDateFormat); + } + else + { + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); - ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*pMarkAccess->getAllMarksBegin()); + ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + CPPUNIT_ASSERT(pFieldmark); + 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; + 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); } - CPPUNIT_ASSERT_EQUAL(OUString("M.d.yyyy"), sDateFormat); } DECLARE_OOXMLEXPORT_TEST(testN830205, "n830205.docx") diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index a630c00d1b71..d5fd1691c2a3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -11,6 +11,7 @@ #include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/XTextTable.hpp> #include <xmloff/odffields.hxx> #include <o3tl/string_view.hxx> @@ -496,19 +497,44 @@ DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx") { // Single <w:sdt> was exported as 2 <w:sdt> elements. assertXPath(pXmlDoc, "//w:sdt", 1); + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); + uno::Reference<container::XEnumerationAccess> xParagraphsAccess(xCell, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParagraphs = xParagraphsAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration(); + uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum = xContentControlEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xTextPortionRange(xContentControlEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("4/26/2012"), xTextPortionRange->getString()); + } + else + { + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); + + ::sw::mark::IDateFieldmark* pFieldmark + = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); + CPPUNIT_ASSERT(pFieldmark); + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + CPPUNIT_ASSERT_EQUAL(OUString("4/26/2012"), pFieldmark->GetContent()); } - - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); - - ::sw::mark::IDateFieldmark* pFieldmark - = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); - CPPUNIT_ASSERT_EQUAL(OUString("4/26/2012"), pFieldmark->GetContent()); } CPPUNIT_TEST_FIXTURE(Test, testFdo81492) @@ -670,33 +696,75 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf66401) DECLARE_OOXMLEXPORT_TEST( testDateFieldInShape, "date_field_in_shape.docx" ) { // This was crashed on export. - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); - - ::sw::mark::IDateFieldmark* pFieldmark - = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); - CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), pFieldmark->GetContent()); + if (mbExported) + { + uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY); + uno::Reference<text::XText> xShapeText = xShape->getText(); + uno::Reference<beans::XPropertySet> xTextPortion(getRun(getParagraphOfText(1, xShapeText), 1), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum = xContentControlEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xTextPortionRange(xContentControlEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), xTextPortionRange->getString()); + } + else + { + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); + + ::sw::mark::IDateFieldmark* pFieldmark + = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); + CPPUNIT_ASSERT(pFieldmark); + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), pFieldmark->GetContent()); + } } DECLARE_OOXMLEXPORT_TEST( testDateFieldAtEndOfParagraph, "date_field_at_end_of_paragraph.docx" ) { // Additional line end was added by import and it was crashed on export - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); - - ::sw::mark::IDateFieldmark* pFieldmark - = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); - CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), pFieldmark->GetContent()); + if (mbExported) + { + uno::Reference<beans::XPropertySet> xTextPortion(getRun(getParagraph(2), 1), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum = xContentControlEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xTextPortionRange(xContentControlEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), xTextPortionRange->getString()); + } + else + { + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getAllMarksCount()); + + ::sw::mark::IDateFieldmark* pFieldmark + = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); + CPPUNIT_ASSERT(pFieldmark); + CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + CPPUNIT_ASSERT_EQUAL(OUString("Click here to enter a date."), pFieldmark->GetContent()); + } } DECLARE_OOXMLEXPORT_TEST(testDropDownFieldEntryLimit, "tdf126792.odt" ) diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index 4a2c6771674d..fd148cd8db49 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -172,34 +172,32 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf121203) { load(mpTestDocumentPath, "tdf121203.docx"); // We imported the 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(1), pMarkAccess->getAllMarksCount()); + uno::Reference<beans::XPropertySet> xTextPortion(getRun(getParagraph(1), 1), uno::UNO_QUERY); + OUString aPortionType; + xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aPortionType); // Custom sdt date content is imported correctly - ::sw::mark::IDateFieldmark* pFieldmark - = dynamic_cast<::sw::mark::IDateFieldmark*>(*pMarkAccess->getAllMarksBegin()); - CPPUNIT_ASSERT(pFieldmark); - CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + uno::Reference<text::XTextContent> xContentControl; + xTextPortion->getPropertyValue("ContentControl") >>= xContentControl; + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + bool bDate{}; + xContentControlProps->getPropertyValue("Date") >>= bDate; + CPPUNIT_ASSERT(bDate); - 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; - } + xContentControlProps->getPropertyValue("DateFormat") >>= sDateFormat; OUString sLang; - pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); - if (pResult != pParameters->end()) - { - pResult->second >>= sLang; - } - - OUString sCurrentDate = pFieldmark->GetContent(); + xContentControlProps->getPropertyValue("DateLanguage") >>= sLang; + + uno::Reference<container::XEnumerationAccess> xContentControlEnumAccess(xContentControl, + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xContentControlEnum + = xContentControlEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xTextPortionRange(xContentControlEnum->nextElement(), + uno::UNO_QUERY); + OUString sCurrentDate = xTextPortionRange->getString(); CPPUNIT_ASSERT_EQUAL(OUString("dd-MMM-yy"), sDateFormat); CPPUNIT_ASSERT_EQUAL(OUString("en-GB"), sLang); CPPUNIT_ASSERT_EQUAL(OUString("17-Oct-2018 09:00"), sCurrentDate); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 181fbfac0508..f6f542ad4b39 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2405,7 +2405,7 @@ void DocxAttributeOutput::WriteContentControlStart() { m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), aCurrentDate); } - OUString aDateFormat = m_pContentControl->GetDateFormat(); + OUString aDateFormat = m_pContentControl->GetDateFormat().replaceAll("\"", "'"); if (!aDateFormat.isEmpty()) { m_pSerializer->singleElementNS(XML_w, XML_dateFormat, FSNS(XML_w, XML_val), diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index cefb05fd5292..5d2549f6a9c8 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1074,12 +1074,12 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) { // Still not determined content type? and it is even not unsupported? Then it is plain text field m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText); - if (nName == NS_ooxml::LN_CT_SdtRun_sdtContent) - { - m_pImpl->m_pSdtHelper->setControlType(SdtControlType::richText); - m_pImpl->PushSdt(); - break; - } + } + if (nName == NS_ooxml::LN_CT_SdtRun_sdtContent) + { + m_pImpl->m_pSdtHelper->setControlType(SdtControlType::richText); + m_pImpl->PushSdt(); + break; } m_pImpl->SetSdt(true); break; @@ -1094,6 +1094,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) case SdtControlType::checkBox: case SdtControlType::dropDown: case SdtControlType::picture: + case SdtControlType::datePicker: m_pImpl->PopSdt(); break; default: @@ -1180,9 +1181,11 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) break; case NS_ooxml::LN_CT_SdtPlaceholder_docPart_val: m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtPlaceholder_docPart_val", sStringValue); + m_pImpl->m_pSdtHelper->SetPlaceholderDocPart(sStringValue); break; case NS_ooxml::LN_CT_SdtColor_val: m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtColor_val", sStringValue); + m_pImpl->m_pSdtHelper->SetColor(sStringValue); break; case NS_ooxml::LN_CT_SdtText_multiLine: m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtText_multiLine", sStringValue); @@ -2766,6 +2769,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) { if (!m_pImpl->GetSdtStarts().empty()) { + if (nSprmId == NS_ooxml::LN_CT_SdtPr_color) + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties) + { + pProperties->resolve(*this); + } + break; + } + if (nSprmId == NS_ooxml::LN_CT_SdtPr_checkbox) { m_pImpl->m_pSdtHelper->setControlType(SdtControlType::checkBox); @@ -2786,6 +2799,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) } break; } + else if (nSprmId == NS_ooxml::LN_CT_SdtPr_date) + { + m_pImpl->m_pSdtHelper->setControlType(SdtControlType::datePicker); + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties) + { + pProperties->resolve(*this); + } + break; + } } // this is an unsupported SDT property, create a grab bag for it diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 4e769e15b0cf..fd6300504de5 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -875,7 +875,15 @@ void DomainMapper_Impl::PopSdt() if (aPosition.m_bIsStartOfText) { - xCursor->gotoStart(/*bExpand=*/false); + // Go to the start of the end's paragraph. This helps in case + // DomainMapper_Impl::AddDummyParaForTableInSection() would make our range multi-paragraph, + // while the intention is to keep start/end inside the same paragraph for run SDTs. + uno::Reference<text::XParagraphCursor> xParagraphCursor(xCursor, uno::UNO_QUERY); + if (xParagraphCursor.is()) + { + xCursor->gotoRange(xEnd, /*bExpand=*/false); + xParagraphCursor->gotoStartOfParagraph(/*bExpand=*/false); + } } else { @@ -892,6 +900,34 @@ void DomainMapper_Impl::PopSdt() uno::Any(m_pSdtHelper->GetShowingPlcHdr())); } + if (!m_pSdtHelper->GetPlaceholderDocPart().isEmpty()) + { + xContentControlProps->setPropertyValue("PlaceholderDocPart", + uno::Any(m_pSdtHelper->GetPlaceholderDocPart())); + } + + if (!m_pSdtHelper->GetDataBindingPrefixMapping().isEmpty()) + { + xContentControlProps->setPropertyValue("DataBindingPrefixMappings", + uno::Any(m_pSdtHelper->GetDataBindingPrefixMapping())); + } + if (!m_pSdtHelper->GetDataBindingXPath().isEmpty()) + { + xContentControlProps->setPropertyValue("DataBindingXpath", + uno::Any(m_pSdtHelper->GetDataBindingXPath())); + } + if (!m_pSdtHelper->GetDataBindingStoreItemID().isEmpty()) + { + xContentControlProps->setPropertyValue("DataBindingStoreItemID", + uno::Any(m_pSdtHelper->GetDataBindingStoreItemID())); + } + + if (!m_pSdtHelper->GetColor().isEmpty()) + { + xContentControlProps->setPropertyValue("Color", + uno::Any(m_pSdtHelper->GetColor())); + } + if (m_pSdtHelper->getControlType() == SdtControlType::checkBox) { xContentControlProps->setPropertyValue("Checkbox", uno::Any(true)); @@ -930,6 +966,18 @@ void DomainMapper_Impl::PopSdt() xContentControlProps->setPropertyValue("Picture", uno::Any(true)); } + if (m_pSdtHelper->getControlType() == SdtControlType::datePicker) + { + xContentControlProps->setPropertyValue("Date", uno::Any(true)); + OUString aDateFormat = m_pSdtHelper->getDateFormat().makeStringAndClear(); + xContentControlProps->setPropertyValue("DateFormat", + uno::Any(aDateFormat.replaceAll("'", "\""))); + xContentControlProps->setPropertyValue("DateLanguage", + uno::Any(m_pSdtHelper->getLocale().makeStringAndClear())); + xContentControlProps->setPropertyValue("CurrentDate", + uno::Any(m_pSdtHelper->getDate().makeStringAndClear())); + } + xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); m_pSdtHelper->clear(); diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index 94019850f7dc..8f5e809efdec 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -453,6 +453,17 @@ void SdtHelper::clear() m_aUncheckedState.clear(); } +void SdtHelper::SetPlaceholderDocPart(const OUString& rPlaceholderDocPart) +{ + m_aPlaceholderDocPart = rPlaceholderDocPart; +} + +OUString SdtHelper::GetPlaceholderDocPart() const { return m_aPlaceholderDocPart; } + +void SdtHelper::SetColor(const OUString& rColor) { m_aColor = rColor; } + +OUString SdtHelper::GetColor() const { return m_aColor; } + } // namespace writerfilter::dmapper /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 3fab668c1f19..c817285095e7 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -119,6 +119,12 @@ class SdtHelper final : public virtual SvRefBase void loadPropertiesXMLs(); + /// <w:placeholder>'s <w:docPart w:val="...">. + OUString m_aPlaceholderDocPart; + + /// <w:sdtPr>'s <w15:color w:val="...">. + OUString m_aColor; + public: explicit SdtHelper(DomainMapper_Impl& rDM_Impl, css::uno::Reference<css::uno::XComponentContext> const& xContext); @@ -136,8 +142,13 @@ public: { m_sDataBindingPrefixMapping = sValue; } + OUString GetDataBindingPrefixMapping() const { return m_sDataBindingPrefixMapping; } + void setDataBindingXPath(const OUString& sValue) { m_sDataBindingXPath = sValue; } + OUString GetDataBindingXPath() const { return m_sDataBindingXPath; } + void setDataBindingStoreItemID(const OUString& sValue) { m_sDataBindingStoreItemID = sValue; } + OUString GetDataBindingStoreItemID() const { return m_sDataBindingStoreItemID; } void setDateFieldStartRange(const css::uno::Reference<css::text::XTextRange>& xStartRange) { @@ -183,6 +194,12 @@ public: /// Clear all collected attributes for further reuse void clear(); + + void SetPlaceholderDocPart(const OUString& rPlaceholderDocPart); + OUString GetPlaceholderDocPart() const; + + void SetColor(const OUString& rColor); + OUString GetColor() const; }; } // namespace writerfilter::dmapper