summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx22
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docxbin0 -> 12778 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx46
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
new file mode 100644
index 000000000000..93aaab52d497
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/field-if-inside-if.docx
Binary files differ
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;
}
}