[Libreoffice-commits] core.git: 2 commits - sw/qa sw/source xmloff/source
Tamás Zolnai (via logerrit)
logerrit at kemper.freedesktop.org
Fri Jul 12 01:18:54 UTC 2019
sw/qa/extras/globalfilter/data/date_form_field.odt |binary
sw/qa/extras/globalfilter/globalfilter.cxx | 97 +++++++++++++++++++++
sw/source/core/doc/docbm.cxx | 6 -
sw/source/filter/ww8/docxattributeoutput.cxx | 93 ++++++++++++++++++++
sw/source/filter/ww8/docxattributeoutput.hxx | 2
sw/source/filter/ww8/fields.hxx | 3
sw/source/filter/ww8/wrtw8nds.cxx | 40 +++++---
xmloff/source/text/XMLTextMarkImportContext.cxx | 5 -
8 files changed, 228 insertions(+), 18 deletions(-)
New commits:
commit 865bfe5cc95c11ab7273bd3ac74cd4f4bd9e097e
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Jun 21 20:40:27 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Jul 12 03:17:36 2019 +0200
MSForms: DOCX export of date content control
Change-Id: I546af6d552e5e3801925285d0095fc8502896a15
Reviewed-on: https://gerrit.libreoffice.org/75446
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index e5167a264f41..0ccf7001c0e1 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -239,6 +239,7 @@ public:
m_pSerializer->endElementNS( XML_w, XML_checkBox );
writeFinish();
}
+
void WriteFormText( const OUString& rName,
const OUString& rEntryMacro,
const OUString& rExitMacro,
@@ -1877,6 +1878,84 @@ void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
}
}
+void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang)
+{
+ m_pSerializer->startElementNS(XML_w, XML_sdt);
+ m_pSerializer->startElementNS(XML_w, XML_sdtPr);
+
+ if (!sCurrentDate.isEmpty())
+ {
+ OString sDate = sCurrentDate.toUtf8() + "T00:00:00Z";
+ m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), sDate);
+ }
+ else
+ m_pSerializer->startElementNS(XML_w, XML_date);
+
+ m_pSerializer->singleElementNS(XML_w, XML_dateFormat,
+ FSNS(XML_w, XML_val), sDateFormat.toUtf8());
+ m_pSerializer->singleElementNS(XML_w, XML_lid,
+ FSNS(XML_w, XML_val), sLang.toUtf8());
+ m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs,
+ FSNS(XML_w, XML_val), "dateTime");
+ m_pSerializer->singleElementNS(XML_w, XML_calendar,
+ FSNS(XML_w, XML_val), "gregorian");
+
+ m_pSerializer->endElementNS(XML_w, XML_date);
+ m_pSerializer->endElementNS(XML_w, XML_sdtPr);
+
+ m_pSerializer->startElementNS(XML_w, XML_sdtContent);
+ m_pSerializer->startElementNS(XML_w, XML_r);
+
+ if (!sCurrentDate.isEmpty())
+ {
+ // Convert the current date to the right format
+ if (!sCurrentDate.isEmpty())
+ {
+ SvNumberFormatter* pFormatter = m_rExport.m_pDoc->GetNumberFormatter();
+
+ double dCurrentDate = 0.0;
+ // First get the date internal double representation
+ sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE); if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
+ pFormatter->PutEntry(sFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ ODF_FORMDATE_CURRENTDATE_LANGUAGE);
+ }
+ pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate);
+
+ // Then convert the date to a fromatter string
+ OUString sOutput;
+ Color* pCol = nullptr;
+ nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sNonConstDateFormat = sDateFormat;
+ pFormatter->PutEntry(sNonConstDateFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+ pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false);
+
+ RunText(sOutput);
+ }
+ }
+
+ m_pSerializer->endElementNS(XML_w, XML_r);
+ m_pSerializer->endElementNS(XML_w, XML_sdtContent);
+
+ m_pSerializer->endElementNS(XML_w, XML_sdt);
+}
+
void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun )
{
if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
@@ -1884,6 +1963,20 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP
// Expand unsupported fields
RunText( rInfos.pField->GetFieldName() );
}
+ else if ( rInfos.eType == ww::eFORMDATE )
+ {
+ const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
+ FieldMarkParamsHelper params( rFieldmark );
+
+ OUString sCurrentDate;
+ params.extractParam( ODF_FORMDATE_CURRENTDATE, sCurrentDate );
+ OUString sDateFormat;
+ params.extractParam( ODF_FORMDATE_DATEFORMAT, sDateFormat );
+ OUString sLang;
+ params.extractParam( ODF_FORMDATE_DATEFORMAT_LANGUAGE, sLang );
+
+ WriteFormDate( sCurrentDate, sDateFormat, sLang );
+ }
else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
{
if ( bWriteRun )
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2d4726bbebdb..b4c8204052af 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -707,6 +707,8 @@ private:
/// Closes a currently open SDT block.
void EndSdtBlock();
+ void WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang);
+
void StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun = false );
void DoWriteCmd( const OUString& rCmd );
void CmdField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun );
diff --git a/sw/source/filter/ww8/fields.hxx b/sw/source/filter/ww8/fields.hxx
index 4bdd5641d8c4..8e24ca11d37b 100644
--- a/sw/source/filter/ww8/fields.hxx
+++ b/sw/source/filter/ww8/fields.hxx
@@ -124,7 +124,8 @@ namespace ww
// NOTE: values > 95 / 0x5F do not correspond to documented WW8 fields
// and thus need special handling in WW8Export::OutputField()!
eBIBLIOGRPAHY=96,
- eCITATION = 97
+ eCITATION = 97,
+ eFORMDATE = 98,
};
/** Find the English Field Name from a winword index
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 19b901fe0e31..a322da5f9ed3 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -128,6 +128,8 @@ static OUString lcl_getFieldCode( const IFieldmark* pFieldmark )
return OUString(" FORMDROPDOWN ");
if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
return OUString(" FORMCHECKBOX ");
+ if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
+ return OUString(" ODFFORMDATE ");
if ( pFieldmark->GetFieldname( ) == ODF_TOC )
return OUString(" TOC ");
if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
@@ -147,6 +149,8 @@ static ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) {
return ww::eFORMDROPDOWN;
if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
return ww::eFORMCHECKBOX;
+ if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
+ return ww::eFORMDATE;
if ( pFieldmark->GetFieldname( ) == ODF_TOC )
return ww::eTOC;
if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
@@ -2406,21 +2410,31 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
{
SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
- OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
-
- bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
- pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
- if ( isDropdownOrCheckbox )
- AppendBookmark( pFieldmark->GetName() );
- OutputField( nullptr, lcl_getFieldId( pFieldmark ),
- lcl_getFieldCode( pFieldmark ),
- FieldFlags::Start | FieldFlags::CmdStart );
- if ( isDropdownOrCheckbox )
+ // Date field is exported as content control, not as a simple field
+ if(pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMDATE &&
+ GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
+ {
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ),
+ lcl_getFieldCode( pFieldmark ),
+ FieldFlags::Start | FieldFlags::CmdStart );
WriteFormData( *pFieldmark );
- OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close );
- if ( isDropdownOrCheckbox )
- AppendBookmark( pFieldmark->GetName() );
+ }
+ else
+ {
+ bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
+ pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
+ if ( isDropdownOrCheckbox )
+ AppendBookmark( pFieldmark->GetName() );
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ),
+ lcl_getFieldCode( pFieldmark ),
+ FieldFlags::Start | FieldFlags::CmdStart );
+ if ( isDropdownOrCheckbox )
+ WriteFormData( *pFieldmark );
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close );
+ if ( isDropdownOrCheckbox )
+ AppendBookmark( pFieldmark->GetName() );
+ }
}
nLen -= ofs;
commit 46a59d10dbbe3cb9bb9962df93e5a79a5318dcfd
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Jun 21 17:56:30 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Fri Jul 12 03:17:16 2019 +0200
MSForms: ODF import / export of text-based date field
Change-Id: Ib535f1ce065a7f298fcccf95e82d1ffab4d1e1e2
Reviewed-on: https://gerrit.libreoffice.org/75445
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
diff --git a/sw/qa/extras/globalfilter/data/date_form_field.odt b/sw/qa/extras/globalfilter/data/date_form_field.odt
new file mode 100644
index 000000000000..8e15793c2d59
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/date_form_field.odt differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index 337d182b4809..87a28cd3676b 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -50,6 +50,7 @@ public:
void testTextFormField();
void testCheckBoxFormField();
void testDropDownFormField();
+ void testDateFormField();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testEmbeddedGraphicRoundtrip);
@@ -68,6 +69,7 @@ public:
CPPUNIT_TEST(testTextFormField);
CPPUNIT_TEST(testCheckBoxFormField);
CPPUNIT_TEST(testDropDownFormField);
+ CPPUNIT_TEST(testDateFormField);
CPPUNIT_TEST_SUITE_END();
};
@@ -1237,6 +1239,101 @@ void Test::testDropDownFormField()
}
}
+void Test::testDateFormField()
+{
+ const OUString aFilterNames[] = {
+ "writer8",
+ //"MS Word 97",
+ //"Office Open XML Text",
+ };
+
+ for (const OUString& rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/date_form_field.odt"), "com.sun.star.text.TextDocument");
+
+ const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8();
+
+ // Export the document and import again for a check
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY);
+ xComponent->dispose();
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check the document after round trip
+ 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(3), pMarkAccess->getAllMarksCount());
+
+ int nIndex = 0;
+ for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(*aIter);
+
+ if(!pFieldmark)
+ continue;
+
+ CPPUNIT_ASSERT_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;
+ pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sCurrentDate;
+ }
+
+ // The first one is empty
+ if(nIndex == 0)
+ {
+
+ 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);
+ }
+ else if (nIndex == 1) // The second has the default format
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-12"), sCurrentDate);
+ }
+ else // The third one has special format
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[NatNum12 MMMM=abbreviation]YYYY\". \"MMMM D."), sDateFormat);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("hu-HU"), sLang);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-11"), sCurrentDate);
+ }
+ ++nIndex;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(3), nIndex);
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index b02d8a68730f..012914060003 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1279,17 +1279,17 @@ namespace sw { namespace mark
bool bActualChange = false;
if(rNewType == ODF_FORMDROPDOWN)
{
- if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
+ if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
bActualChange = true;
}
else if(rNewType == ODF_FORMCHECKBOX)
{
- if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
+ if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
bActualChange = true;
}
else if(rNewType == ODF_FORMDATE)
{
- if (dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark))
+ if (!dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark))
bActualChange = true;
}
diff --git a/xmloff/source/text/XMLTextMarkImportContext.cxx b/xmloff/source/text/XMLTextMarkImportContext.cxx
index 62e58c8a84c1..aff9a18c38d1 100644
--- a/xmloff/source/text/XMLTextMarkImportContext.cxx
+++ b/xmloff/source/text/XMLTextMarkImportContext.cxx
@@ -137,6 +137,8 @@ static const char *lcl_getFormFieldmarkName(OUString const &name)
else if (name == ODF_FORMDROPDOWN ||
name == "ecma.office-open-xml.field.FORMDROPDOWN")
return ODF_FORMDROPDOWN;
+ else if (name == ODF_FORMDATE)
+ return ODF_FORMDATE;
else
return nullptr;
}
@@ -330,7 +332,8 @@ void XMLTextMarkImportContext::EndElement()
OUString const type(m_rHelper.getCurrentFieldType());
fieldmarkTypeName = lcl_getFieldmarkName(type);
if (fieldmarkTypeName == ODF_FORMCHECKBOX ||
- fieldmarkTypeName == ODF_FORMDROPDOWN)
+ fieldmarkTypeName == ODF_FORMDROPDOWN ||
+ fieldmarkTypeName == ODF_FORMDATE)
{ // sw can't handle checkbox with start+end
SAL_INFO("xmloff.text", "invalid fieldmark-start/fieldmark-end ignored");
isInvalid = true;
More information about the Libreoffice-commits
mailing list