sw/qa/extras/ww8export/data/tdf147861_customField.doc |binary sw/qa/extras/ww8export/ww8export3.cxx | 19 ++++++++++++++++++ sw/source/filter/ww8/ww8atr.cxx | 10 --------- sw/source/filter/ww8/ww8par5.cxx | 13 ++++++++++-- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 13 ++++++------ 5 files changed, 38 insertions(+), 17 deletions(-)
New commits: commit 94ff56946fb09b2086fe6c569df3e513da69e599 Author: Justin Luth <[email protected]> AuthorDate: Wed Mar 9 11:38:26 2022 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Fri Apr 1 08:11:41 2022 +0200 tdf#147861 ww8import: use GetFieldResult, not current DocProperty In all the testing I could think of on DOCX and DOC examples (and only a very few exist in the unit tests) the actual value of the DocProperty was irrelevant to what Word shows as the document loads. It always takes the in-document, as-last-seen static text. As a way to hack a fix using existing capabilities, I marked as FIXEDFLD the unknown custom fields that weren't handled separately. That fixes what is displayed as the import value, (which of course means that F9 will no longer return a modification back to the DocProperty value). It also means the (fixed) field is lost on export, but a follow-up patch handles that for DOC/RTF/DOCX. There were NO DI_CUSTOM examples in existing ww8 tests, but: -ooxmlexport8: fdo74745.docx, fdo81486.docx -ooxmlexport10: tdf92157.docx and in these cases the plain text matched the variable anyway, but a manual manipulation showed that LO is importing DOCX wrong as well, so a similar import fix needs to happen for RTF/DOCX. My fear is that there are some special-magic-associations that worked properly the old way by accident that I will break by marking them as fixed. No backporting please since obviously very few people report bugs about fields. (cherry picked from commit 377e6f7e8556516b6d1698c58857a5662e6f5660) Conflicts: sw/qa/extras/ww8export/ww8export3.cxx Change-Id: I3f167eb3bd570b66ee829241bf9d31d557fc8749 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132344 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/qa/extras/ww8export/data/tdf147861_customField.doc b/sw/qa/extras/ww8export/data/tdf147861_customField.doc new file mode 100644 index 000000000000..f18d65f4059e Binary files /dev/null and b/sw/qa/extras/ww8export/data/tdf147861_customField.doc differ diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx index 3836db666088..631560732e0c 100644 --- a/sw/qa/extras/ww8export/ww8export3.cxx +++ b/sw/qa/extras/ww8export/ww8export3.cxx @@ -17,6 +17,7 @@ #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/text/XFormField.hpp> +#include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> #include <com/sun/star/text/WritingMode2.hpp> @@ -69,6 +70,24 @@ DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.d CPPUNIT_ASSERT_EQUAL_MESSAGE("Last printed date", sal_Int16(2009), xDPS->getDocumentProperties()->getPrintDate().Year); } +DECLARE_WW8EXPORT_TEST(testTdf147861_customField, "tdf147861_customField.doc") +{ + // These should each be specific values, not a shared DocProperty + getParagraph(1, "CustomEditedTitle"); // edited + getParagraph(2, " INSERT Custom Title here"); // matches current DocProperty + getParagraph(3, "My Title"); // edited + + if (mbExported) + return; + + // Verify that these are fields, and not just plain text + 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); + CPPUNIT_ASSERT_EQUAL(OUString("CustomEditedTitle"), xField->getPresentation(false)); +} + DECLARE_WW8EXPORT_TEST(testTdf104596_wrapInHeaderTable, "tdf104596_wrapInHeaderTable.doc") { xmlDocUniquePtr pXmlDoc = parseLayoutDump(); diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index c37ee40fb6de..338d1eeef137 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -1638,8 +1638,17 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) if( !bFieldFound ) { - SwDocInfoField aField( static_cast<SwDocInfoFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), DI_CUSTOM|nReg, aDocProperty, GetFieldResult( pF ) ); + // LO always automatically updates a DocInfo field from the File-Properties-Custom Prop + // while MS Word requires the user to manually refresh the field (with F9). + // In other words, Word lets the field to be out of sync with the controlling variable. + // Marking as FIXEDFLD solves the automatic replacement problem, but of course prevents + // Writer from making any changes, even on an F9 refresh. + // TODO: If the field already matches the DocProperty, no need to mark as fixed. + // TODO: Extend LO to allow a linked field that doesn't automatically update. + const auto pType(static_cast<SwDocInfoFieldType*>( + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo))); + const OUString sDisplayed = GetFieldResult(pF); + SwDocInfoField aField(pType, DI_CUSTOM | DI_SUB_FIXED | nReg, aDocProperty, sDisplayed); m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField)); return eF_ResT::OK; commit 8838e88b48e24f8210aa1aaa5e891e37ecae1f10 Author: Justin Luth <[email protected]> AuthorDate: Sat Mar 12 09:32:20 2022 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Fri Apr 1 08:11:19 2022 +0200 related tdf#147861: cleanup + a function provides the name This is not quite a NonFunctionalChange because it avoids adding " (fixed)" to the name. But that is what I want anyway for bug 147861, so this is an all-around good simplification. Plus, the writerfilter loop doesn't need to run if an inside clause will never be true anyway. Putting this cleanup separately helps highlight the actual fix and not clutter the real patches. (cherry picked from commit a13faccd7e8c6503e96e9342a8615b4542b0601f) Change-Id: I12f345cc92627398ad00fe32b64b98b54e5ed14b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132343 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index de0b2b6ed6ee..1bb40eff2793 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -2886,15 +2886,7 @@ void AttributeOutputBase::TextField( const SwFormatField& rField ) dynamic_cast<const SwDocInfoField *> (pField); if (pDocInfoField != nullptr) - { - OUString sFieldname = pDocInfoField->GetFieldName(); - - const sal_Int32 nIndex = sFieldname.indexOf(':'); - if (nIndex >= 0) - sFieldname = sFieldname.copy(nIndex + 1); - - sStr = "\"" + sFieldname + "\""; - } + sStr = "\"" + pDocInfoField->GetName() + "\""; } break; default: diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 689201035d3c..accf1148f916 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -4782,14 +4782,15 @@ void DomainMapper_Impl::handleAuthor //search for a field mapping OUString sFieldServiceName; size_t nMap = 0; - for( ; nMap < SAL_N_ELEMENTS(aDocProperties); ++nMap ) + if (!xPropertySetInfo->hasPropertyByName(rFirstParam)) { - if ((rFirstParam.equalsAscii(aDocProperties[nMap].pDocPropertyName)) && (!xPropertySetInfo->hasPropertyByName(rFirstParam))) + for( ; nMap < SAL_N_ELEMENTS(aDocProperties); ++nMap ) { - sFieldServiceName = - OUString::createFromAscii - (aDocProperties[nMap].pServiceName); - break; + if (rFirstParam.equalsAscii(aDocProperties[nMap].pDocPropertyName)) + { + sFieldServiceName = OUString::createFromAscii(aDocProperties[nMap].pServiceName); + break; + } } } OUString sServiceName("com.sun.star.text.TextField.");
