sw/qa/extras/ooxmlexport/data/tdf148380_fldLocked.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport17.cxx | 21 +++++++++++++++++ sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc |binary sw/qa/extras/ww8export/ww8export3.cxx | 21 +++++++++++++++++ sw/source/filter/ww8/ww8par5.cxx | 7 +++-- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 5 ++++ writerfilter/source/ooxml/factoryimpl_ns.py | 8 ++++++ writerfilter/source/ooxml/model.xml | 1 8 files changed, 60 insertions(+), 3 deletions(-)
New commits: commit 4a8ea3d086e03098fcff2a744ccb632f50f173dd Author: Justin Luth <justin_l...@sil.org> AuthorDate: Tue Apr 12 12:06:56 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Apr 27 12:04:01 2022 +0200 tdf#148380 sw ms: import select fldLock'd fields as FIXED Many fields we are locking just because we can't trust that what is seen in MSWord is what will be seen in LO. Of the unlocked fields which normally should be updated (SAVEDATE and PRINTDATE), if MS Word secretly has also locked them (via Ctrl-F11), then we also need to lock them. Currently, on export these will be exported as plain text, which IMHO is perfect because them we never need to mess with these nasty fields again. WriterFilter import was already handling the complicated FldChar's fldLock OK, but nothing happened with the one for fldSimple. Proving once again that a monkey can program, I randomly made copy-changes to model.xml until I got the result I wanted... The unit test has one of each. Change-Id: Ia197794f4ea7e105b67cb1805c5def5347d7690d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133087 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/extras/ooxmlexport/data/tdf148380_fldLocked.docx b/sw/qa/extras/ooxmlexport/data/tdf148380_fldLocked.docx new file mode 100644 index 000000000000..2ac77223b235 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf148380_fldLocked.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx index 8ebe824449c9..414a20789c81 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx @@ -83,6 +83,27 @@ DECLARE_OOXMLEXPORT_TEST(testTdf148380_createField, "tdf148380_createField.docx" CPPUNIT_ASSERT_EQUAL(OUString("yesterday at noon"), xField->getPresentation(false)); } +DECLARE_OOXMLEXPORT_TEST(testTdf148380_fldLocked, "tdf148380_fldLocked.docx") +{ + getParagraph(2, "4/5/2022 4:29:00 PM"); + getParagraph(4, "1/23/4567 8:9:10 PM"); + + // Verify that these are fields, and not just plain text + // (import only, since export thankfully just dumps these fixed fields as plain text + if (mbExported) + return; + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + // This should NOT be updated at FILEOPEN to match the last modified time - it is locked. + CPPUNIT_ASSERT_EQUAL(OUString("4/5/2022 4:29:00 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Modified (fixed)"), xField->getPresentation(true)); + xField.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1/23/4567 8:9:10 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Last printed (fixed)"), xField->getPresentation(true)); +} + DECLARE_OOXMLEXPORT_TEST(testTdf148380_modifiedField, "tdf148380_modifiedField.docx") { getParagraph(2, "4/5/2022 3:29:00 PM"); // default (unspecified) date format diff --git a/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc b/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc new file mode 100644 index 000000000000..cee6982ee6a0 Binary files /dev/null and b/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc differ diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx index 5f0bf54078cd..4d009663d007 100644 --- a/sw/qa/extras/ww8export/ww8export3.cxx +++ b/sw/qa/extras/ww8export/ww8export3.cxx @@ -132,6 +132,27 @@ DECLARE_WW8EXPORT_TEST(testTdf148380_createField, "tdf148380_createField.doc") CPPUNIT_ASSERT_EQUAL(OUString("yesterday at noon"), xField->getPresentation(false)); } +DECLARE_WW8EXPORT_TEST(testTdf148380_fldLocked, "tdf148380_fldLocked.doc") +{ + getParagraph(2, "4/5/2022 4:29:00 PM"); + getParagraph(4, "1/23/4567 8:9:10 PM"); + + // Verify that these are fields, and not just plain text + // (import only, since export thankfully just dumps these fixed fields as plain text + if (mbExported) + return; + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + // This should NOT be updated at FILEOPEN to match the last modified time - it is locked. + CPPUNIT_ASSERT_EQUAL(OUString("4/5/2022 4:29:00 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Modified (fixed)"), xField->getPresentation(true)); + xField.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1/23/4567 8:9:10 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Last printed (fixed)"), xField->getPresentation(true)); +} + DECLARE_WW8EXPORT_TEST(testTdf138345_paraCharHighlight, "tdf138345_paraCharHighlight.doc") { uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(9), 1, "A side benefit is that "), uno::UNO_QUERY_THROW); diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index e6ec2353e9c3..a55495404760 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -1548,6 +1548,7 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) // RegInfoFormat, DefaultFormat for DocInfoFields sal_uInt16 nReg = DI_SUB_AUTHOR; bool bDateTime = false; + const sal_uInt16 nFldLock = (pF->nOpt & 0x10) ? DI_SUB_FIXED : 0; if( 85 == pF->nId ) { @@ -1721,7 +1722,7 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) bDateTime = true; break; case 23: - nSub = DI_PRINT; + nSub = DI_PRINT | nFldLock; nReg = DI_SUB_DATE; bDateTime = true; break; @@ -1729,12 +1730,12 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) nSub = DI_DOCNO; break; case 22: - nSub = DI_CHANGE; + nSub = DI_CHANGE | nFldLock; nReg = DI_SUB_DATE; bDateTime = true; break; case 25: - nSub = DI_CHANGE; + nSub = DI_CHANGE | nFldLock; nReg = DI_SUB_TIME; bDateTime = true; break; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 949fafd7252a..c95bbf568678 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -6395,6 +6395,11 @@ void DomainMapper_Impl::CloseFieldCommand() case FIELD_PRINTDATE: case FIELD_SAVEDATE: { + if (pContext->IsFieldLocked()) + { + xFieldProperties->setPropertyValue( + getPropertyName(PROP_IS_FIXED), uno::makeAny( true )); + } xFieldProperties->setPropertyValue( getPropertyName( PROP_IS_DATE ), uno::makeAny( true )); SetNumberFormat( pContext->GetCommand(), xFieldProperties ); diff --git a/writerfilter/source/ooxml/factoryimpl_ns.py b/writerfilter/source/ooxml/factoryimpl_ns.py index 73d2022902d6..b17e0c8ffa97 100644 --- a/writerfilter/source/ooxml/factoryimpl_ns.py +++ b/writerfilter/source/ooxml/factoryimpl_ns.py @@ -463,6 +463,14 @@ def factoryChooseAction(actionNode): ret.append(" %sif (aHandler.getValue())" % (extra_space)) ret.append(" %spHandler->lockField();" % (extra_space)) ret.append(" %s}" % (extra_space)) + elif actionNode.getAttribute("action") == "fieldlock_simple": + ret.append(" %s{" % (extra_space)) + ret.append(" %sOOXMLPropertySetEntryToBool aHandler(NS_ooxml::LN_CT_SimpleField_fldLock);" % (extra_space)) + ret.append(" %sif (OOXMLFastContextHandlerStream* pStream = dynamic_cast<OOXMLFastContextHandlerStream*>(pHandler))" % (extra_space)) + ret.append(" %spStream->getPropertySetAttrs()->resolve(aHandler);" % (extra_space)) + ret.append(" %sif (aHandler.getValue())" % (extra_space)) + ret.append(" %spHandler->lockField();" % (extra_space)) + ret.append(" %s}" % (extra_space)) elif actionNode.getAttribute("action") == "printproperty": ret.append(" %sif (OOXMLFastContextHandlerStream* pStream = dynamic_cast<OOXMLFastContextHandlerStream*>(pHandler))" % extra_space) ret.append(" %s pStream->sendProperty(%s);" % (extra_space, idToLabel(actionNode.getAttribute("sendtokenid")))) diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 04fb1934b8d5..439f5e8d8a20 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -17676,6 +17676,7 @@ <action name="start" action="startCharacterGroup"/> <action name="start" action="printproperty" sendtokenid="ooxml:CT_SimpleField_instr"/> <action name="start" action="endCharacterGroup"/> + <action name="start" action="fieldlock_simple"/> <action name="start" action="fieldsep"/> <action name="end" action="fieldend"/> </resource>