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 <vmiklos@collabora.com>
Tested-by: Jenkins
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index ae720f5..ebe5abb 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())
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pMarkAccess->getAllMarksCount());
int nIndex = 0;
for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
{
pResult->second >>= sDateFormat;
::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 sLang;
pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
if (pResult != pParameters->end())
{
pResult->second >>= sLang;
}
OUString sCurrentDate = pFieldmark->GetContent();
// 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);
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());
}
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());
}
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;
}
OUString sLang;
pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
if (pResult != pParameters->end())
{
pResult->second >>= sLang;
}
OUString sCurrentDate = pFieldmark->GetContent();
// 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);
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());
}
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());
}
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;
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(5), nIndex);
}
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())
{
uno::Reference<beans::XPropertySet> xTextPortion(xTextPortions->nextElement(), uno::UNO_QUERY);
OUString aPortionType;
xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
if (aPortionType != "ContentControl")
{
continue;
}
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;
}
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();
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());
// 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"));
// 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 0435f42..e3525b5 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)
continue;
CPPUNIT_ASSERT(pFieldmark);
CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
// Check date 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())
uno::Reference<beans::XPropertySet> xTextPortion(xPortions->nextElement(), uno::UNO_QUERY);
OUString aPortionType;
xTextPortion->getPropertyValue("TextPortionType") >>= aPortionType;
if (aPortionType != "ContentControl")
{
pResult->second >>= sDateFormat;
continue;
}
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 content control's parameters.
OUString 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 b52c25c..62c754a 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());
::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())
if (mbExported)
{
pResult->second >>= sDateFormat;
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);
}
CPPUNIT_ASSERT_EQUAL(OUString("M.d.yyyy"), sDateFormat);
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());
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;
}
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 a630c00..d5fd169 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());
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());
::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());
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());
::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());
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());
::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 4a2c6771..fd148cd 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;
}
xContentControlProps->getPropertyValue("DateLanguage") >>= sLang;
OUString sCurrentDate = pFieldmark->GetContent();
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 181fbfac..f6f542a 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 cefb05f..5d2549f 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 4e769e1..fd63005 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 9401985..8f5e809e 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 3fab668..c817285 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