[Libreoffice-commits] core.git: sw/qa writerfilter/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Thu Oct 31 11:36:33 UTC 2019
sw/qa/extras/ooxmlexport/data/tdf125038c.docx |binary
sw/qa/extras/ooxmlexport/ooxmlexport14.cxx | 10 ++
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 82 ++++++++++++++++++++++
3 files changed, 92 insertions(+)
New commits:
commit d09336fbdceaafd9320466b660a2b32a07dcc16a
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Oct 31 10:40:41 2019 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu Oct 31 12:35:56 2019 +0100
tdf#125038 DOCX import: fix lost MERGEFIELD result inside an IF field
The problem here was that the IF field result didn't have a plain text
string, rather it had a MERGEFIELD in it. Writer's conditional text
field expects a plain text string, so just use the result of the
MERGEFIELD for an IF parent. Do this in a generic way, it's likely that
other parent-child field combinations want to do the same in the future.
With this, all lost strings are fixed from the original bugdoc + all
unexpected content is hidden in Writer as well.
Change-Id: Ic5c03b1df2f08a2cd851647b625e0c303cc5d6c5
Reviewed-on: https://gerrit.libreoffice.org/81825
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/sw/qa/extras/ooxmlexport/data/tdf125038c.docx b/sw/qa/extras/ooxmlexport/data/tdf125038c.docx
new file mode 100644
index 000000000000..10234b864627
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf125038c.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 82237bffa368..2c2d94821acf 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -66,6 +66,16 @@ DECLARE_OOXMLIMPORT_TEST(testTdf125038b, "tdf125038b.docx")
CPPUNIT_ASSERT(!xParagraphs->hasMoreElements());
}
+DECLARE_OOXMLIMPORT_TEST(testTdf125038c, "tdf125038c.docx")
+{
+ OUString aActual = getParagraph(1)->getString();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: email: test at test.test
+ // - Actual : email:
+ // I.e. the result of the MERGEFIELD field inside an IF field was lost.
+ CPPUNIT_ASSERT_EQUAL(OUString("email: test at test.test"), aActual);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 36f17c5cebb6..7d2b7545de20 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -174,6 +174,52 @@ struct FieldConversion
typedef std::unordered_map<OUString, FieldConversion> FieldConversionMap_t;
+/// Gives access to the parent field contenxt of the topmost one, if there is any.
+static FieldContextPtr GetParentFieldContext(const std::deque<FieldContextPtr>& rFieldStack)
+{
+ if (rFieldStack.size() < 2)
+ {
+ return nullptr;
+ }
+
+ return rFieldStack[rFieldStack.size() - 2];
+}
+
+/// 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())
+ {
+ return true;
+ }
+
+ if (!pInner->GetFieldId())
+ {
+ return true;
+ }
+
+ switch (pOuter->GetFieldId().get())
+ {
+ case FIELD_IF:
+ {
+ switch (pInner->GetFieldId().get())
+ {
+ case FIELD_MERGEFIELD:
+ {
+ return false;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+
uno::Any FloatingTableInfo::getPropertyValue(const OUString &propertyName)
{
for( beans::PropertyValue const & propVal : m_aFrameProperties )
@@ -4490,8 +4536,20 @@ void DomainMapper_Impl::CloseFieldCommand()
break;
}
default:
+ {
+ FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack);
+ if (pOuter)
+ {
+ if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back()))
+ {
+ // Parent field can't host this child field: don't create a child field
+ // in this case.
+ bCreateField = false;
+ }
+ }
break;
}
+ }
if (m_bStartTOC && (aIt->second.eFieldId == FIELD_PAGEREF) )
{
bCreateField = false;
@@ -5202,6 +5260,19 @@ bool DomainMapper_Impl::IsFieldResultAsString()
{
bRet = pContext->GetTextField().is() || pContext->GetFieldId() == FIELD_FORMDROPDOWN;
}
+
+ if (!bRet)
+ {
+ FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack);
+ if (pOuter)
+ {
+ if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back()))
+ {
+ // Child field has no backing SwField, but the parent has: append is still possible.
+ bRet = pOuter->GetTextField().is();
+ }
+ }
+ }
return bRet;
}
@@ -5212,6 +5283,17 @@ void DomainMapper_Impl::AppendFieldResult(OUString const& rString)
SAL_WARN_IF(!pContext.get(), "writerfilter.dmapper", "no field context");
if (pContext.get())
{
+ FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack);
+ if (pOuter)
+ {
+ if (!IsFieldNestingAllowed(pOuter, pContext))
+ {
+ // Child can't host the field result, forward to parent.
+ pOuter->AppendResult(rString);
+ return;
+ }
+ }
+
pContext->AppendResult(rString);
}
}
More information about the Libreoffice-commits
mailing list