summaryrefslogtreecommitdiff
path: root/writerfilter/source
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-10-31 10:40:41 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-10-31 12:35:56 +0100
commitd09336fbdceaafd9320466b660a2b32a07dcc16a (patch)
tree2c5ef78ca58314fe249223aafd9b0b752f585721 /writerfilter/source
parent25c608dc3508843845f117e526c0788e92e44214 (diff)
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@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'writerfilter/source')
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx82
1 files changed, 82 insertions, 0 deletions
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);
}
}