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 <jluth@mail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
Justin Luth 2022-04-12 12:06:56 +02:00 committed by Miklos Vajna
parent e678e013a9
commit 4a8ea3d086
8 changed files with 60 additions and 3 deletions

Binary file not shown.

View file

@ -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

Binary file not shown.

View file

@ -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);

View file

@ -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;

View file

@ -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 );

View file

@ -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"))))

View file

@ -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>