diff options
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx | 22 | ||||
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx | bin | 0 -> 12778 bytes | |||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 46 |
3 files changed, 55 insertions, 13 deletions
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx index 0ea06a41bf31..c7df72b25703 100644 --- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx @@ -16,6 +16,8 @@ #include <com/sun/star/style/BreakType.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/text/XTextTablesSupplier.hpp> +#include <com/sun/star/text/XTextTable.hpp> using namespace ::com::sun::star; @@ -158,6 +160,26 @@ CPPUNIT_TEST_FIXTURE(Test, testAltChunk) xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(OUString("inner doc, first para"), xPara->getString()); } + +CPPUNIT_TEST_FIXTURE(Test, testFieldIfInsideIf) +{ + // Load a document with a field in a table cell: it contains an IF field with various nested + // fields. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "field-if-inside-if.docx"; + getComponent() = loadFromDesktop(aURL); + uno::Reference<text::XTextTablesSupplier> xTextDocument(getComponent(), uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextDocument->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + + // Get the result of the topmost field. + uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2 + // - Actual : 0** Expression is faulty **2 + // i.e. some of the inner fields escaped outside the outer field. + CPPUNIT_ASSERT_EQUAL(OUString("2"), xCell->getString()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx Binary files differnew file mode 100644 index 000000000000..93aaab52d497 --- /dev/null +++ b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 08fe93e46a42..0a7ae26d937e 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -205,7 +205,14 @@ static FieldContextPtr GetParentFieldContext(const std::deque<FieldContextPtr>& /// Decides if the pInner field inside pOuter is allowed in Writer core, depending on their type. static bool IsFieldNestingAllowed(const FieldContextPtr& pOuter, const FieldContextPtr& pInner) { - if (!pOuter->GetFieldId()) + std::optional<FieldId> oOuterFieldId = pOuter->GetFieldId(); + if (!oOuterFieldId && pOuter->GetCommand().startsWith(" IF ")) + { + // This will be FIELD_IF once the command is closed. + oOuterFieldId = FIELD_IF; + } + + if (!oOuterFieldId) { return true; } @@ -215,12 +222,15 @@ static bool IsFieldNestingAllowed(const FieldContextPtr& pOuter, const FieldCont return true; } - switch (*pOuter->GetFieldId()) + switch (*oOuterFieldId) { case FIELD_IF: { switch (*pInner->GetFieldId()) { + case FIELD_DOCVARIABLE: + case FIELD_FORMULA: + case FIELD_IF: case FIELD_MERGEFIELD: { return false; @@ -5404,12 +5414,16 @@ void DomainMapper_Impl::CloseFieldCommand() break; case FIELD_DOCVARIABLE : { - //create a user field and type - uno::Reference< beans::XPropertySet > xMaster = - FindOrCreateFieldMaster("com.sun.star.text.FieldMaster.User", sFirstParam); - uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW ); - xDependentField->attachTextFieldMaster( xMaster ); - m_bSetUserFieldContent = true; + if (bCreateField) + { + //create a user field and type + uno::Reference<beans::XPropertySet> xMaster = FindOrCreateFieldMaster( + "com.sun.star.text.FieldMaster.User", sFirstParam); + uno::Reference<text::XDependentTextField> xDependentField( + xFieldInterface, uno::UNO_QUERY_THROW); + xDependentField->attachTextFieldMaster(xMaster); + m_bSetUserFieldContent = true; + } } break; case FIELD_EDITTIME : @@ -5480,7 +5494,10 @@ void DomainMapper_Impl::CloseFieldCommand() break; case FIELD_FILESIZE : break; case FIELD_FORMULA : - handleFieldFormula(pContext, xFieldProperties); + if (bCreateField) + { + handleFieldFormula(pContext, xFieldProperties); + } break; case FIELD_FORMCHECKBOX : case FIELD_FORMDROPDOWN : @@ -6031,8 +6048,8 @@ bool DomainMapper_Impl::IsFieldResultAsString() { if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back())) { - // Child field has no backing SwField, but the parent has: append is still possible. - bRet = pOuter->GetTextField().is(); + // If nesting is not allowed, then the result can only be a string. + bRet = true; } } } @@ -6052,8 +6069,11 @@ void DomainMapper_Impl::AppendFieldResult(OUString const& rString) { if (!IsFieldNestingAllowed(pOuter, pContext)) { - // Child can't host the field result, forward to parent. - pOuter->AppendResult(rString); + if (pOuter->IsCommandCompleted()) + { + // Child can't host the field result, forward to parent's result. + pOuter->AppendResult(rString); + } return; } } |