diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-10-31 10:40:41 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-10-31 12:35:56 +0100 |
commit | d09336fbdceaafd9320466b660a2b32a07dcc16a (patch) | |
tree | 2c5ef78ca58314fe249223aafd9b0b752f585721 /writerfilter/source | |
parent | 25c608dc3508843845f117e526c0788e92e44214 (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.cxx | 82 |
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); } } |