summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-04-04 09:12:34 +0200
committerMichael Stahl <mstahl@redhat.com>2017-04-12 14:41:57 +0200
commit776839b8bfc6eed905ce97c6fe32af8deb8d1451 (patch)
tree4fd1aa0a944347e79b3bacc038699e3057606d32 /writerfilter
parent3247dce15d041d178fa2a855b53415a80df16a28 (diff)
tdf#106690 DOCX import: fix automatic spacing before/after numbered para block
The context is text nodes with automatic before/after spacing and numbering rules set, like: A * B * C * D E The correct behavior seems to be (though I haven't found this explicitly written in the OOXML spec) to drop spacing between B and C and C and D, but not before B and not after D. Originally no spacing was dropped, then commit c486e875de7c8e845594f5043a37ee8800865782 (tdf#95031 DOCX import: auto spacing inside numbering means no spacing, 2016-10-18) removed spacing around all B/C/D. Fix the problem by checking the numbering rules and automatic after spacing of the previous paragraph, so spacing before B and after D is not removed. Change-Id: Icbdb36e31057ab0e8ac033888cf5cc7c52dad5d0 Reviewed-on: https://gerrit.libreoffice.org/36062 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 1bf7f6a1a50ee9f24a3687240fe6ae390b905a6b) Reviewed-on: https://gerrit.libreoffice.org/36142 Reviewed-by: Michael Stahl <mstahl@redhat.com>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx7
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx45
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx5
3 files changed, 50 insertions, 7 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 79a12523f999..f2dfd37e727c 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -620,9 +620,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
}
if (nIntValue) // If auto spacing is set, then only store set value in InteropGrabBag
{
- if (m_pImpl->GetTopContext()->isSet(PROP_NUMBERING_RULES))
- // Numbering is set -> auto space is 0.
- default_spacing = 0;
+ m_pImpl->SetParaAutoBefore(true);
m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ) );
}
else
@@ -645,9 +643,6 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
}
if (nIntValue) // If auto spacing is set, then only store set value in InteropGrabBag
{
- if (m_pImpl->GetTopContext()->isSet(PROP_NUMBERING_RULES))
- // Numbering is set -> auto space is 0.
- default_spacing = 0;
m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ) );
}
else
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index bebfaa7f8e02..236436cbd362 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -242,7 +242,8 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bFrameBtLr(false),
m_bIsSplitPara(false),
m_vTextFramesForChaining(),
- m_bParaHadField(false)
+ m_bParaHadField(false),
+ m_bParaAutoBefore(false)
{
m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault(
@@ -1169,7 +1170,48 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap )
appendTextPortion(sMarker, pEmpty);
}
+ // Check if top / bottom margin has to be updated, now that we know the numbering status of both the previous and
+ // the current text node.
+ auto itNumberingRules = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue)
+ {
+ return rValue.Name == "NumberingRules";
+ });
+ if (itNumberingRules != aProperties.end())
+ {
+ // This textnode has numbering.
+ if (m_xPreviousParagraph.is() && m_xPreviousParagraph->getPropertyValue("NumberingRules").hasValue())
+ {
+ // There was a previous textnode and it had numbering.
+ if (m_bParaAutoBefore)
+ {
+ // This before spacing is set to auto, set before space to 0.
+ auto itParaTopMargin = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue)
+ {
+ return rValue.Name == "ParaTopMargin";
+ });
+ if (itParaTopMargin != aProperties.end())
+ itParaTopMargin->Value <<= static_cast<sal_Int32>(0);
+ else
+ aProperties.push_back(comphelper::makePropertyValue("ParaTopMargin", static_cast<sal_Int32>(0)));
+ }
+ uno::Sequence<beans::PropertyValue> aPrevPropertiesSeq;
+ m_xPreviousParagraph->getPropertyValue("ParaInteropGrabBag") >>= aPrevPropertiesSeq;
+ auto aPrevProperties = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aPrevPropertiesSeq);
+ auto itPrevParaAutoAfter = std::find_if(aPrevProperties.begin(), aPrevProperties.end(), [](const beans::PropertyValue& rValue)
+ {
+ return rValue.Name == "ParaBottomMarginAfterAutoSpacing";
+ });
+ bool bPrevParaAutoAfter = itPrevParaAutoAfter != aPrevProperties.end();
+ if (bPrevParaAutoAfter)
+ {
+ // Previous after spacing is set to auto, set previous after space to 0.
+ m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", uno::makeAny(static_cast<sal_Int32>(0)));
+ }
+ }
+ }
+
xTextRange = xTextAppend->finishParagraph( comphelper::containerToSequence(aProperties) );
+ m_xPreviousParagraph.set(xTextRange, uno::UNO_QUERY);
if (xCursor.is())
{
@@ -1225,6 +1267,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap )
SetIsOutsideAParagraph(true);
m_bParaHadField = false;
+ m_bParaAutoBefore = false;
#ifdef DEBUG_WRITERFILTER
TagLogger::getInstance().endElement();
#endif
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 8540dd1943a0..7ec425151ee9 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -874,11 +874,16 @@ public:
bool IsDiscardHeaderFooter();
+ void SetParaAutoBefore(bool bParaAutoBefore) { m_bParaAutoBefore = bParaAutoBefore; }
+
private:
void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType);
std::vector<css::uno::Reference< css::drawing::XShape > > m_vTextFramesForChaining ;
/// Current paragraph had at least one field in it.
bool m_bParaHadField;
+ css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph;
+ /// Current paragraph has automatic before spacing.
+ bool m_bParaAutoBefore;
};
} //namespace dmapper