diff options
Diffstat (limited to 'writerfilter')
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 1 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 79 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 9 |
3 files changed, 86 insertions, 3 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 80bcfa67175d..443be5a54930 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -688,6 +688,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) } if (nIntValue) // If auto spacing is set, then only store set value in InteropGrabBag { + m_pImpl->SetParaAutoAfter(true); 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 7a055b629c20..00effcd10081 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -251,7 +251,12 @@ DomainMapper_Impl::DomainMapper_Impl( m_bIsSplitPara(false), m_vTextFramesForChaining(), m_bParaHadField(false), - m_bParaAutoBefore(false) + m_bParaAutoBefore(false), + m_bParaAutoAfter(false), + m_bPrevParaAutoAfter(false), + m_bParaChangedBottomMargin(false), + m_bFirstParagraphInCell(true), + m_bSaveFirstParagraphInCell(false) { m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_DOCUMENTBASEURL(), OUString()); @@ -1103,7 +1108,6 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) { if (m_bDiscardHeaderFooter) return; - #ifdef DEBUG_WRITERFILTER TagLogger::getInstance().startElement("finishParagraph"); #endif @@ -1114,7 +1118,6 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) return; TextAppendContext& rAppendContext = m_aTextAppendStack.top(); uno::Reference< text::XTextAppend > xTextAppend(rAppendContext.xTextAppend); - #ifdef DEBUG_WRITERFILTER TagLogger::getInstance().attribute("isTextAppend", sal_uInt32(xTextAppend.is())); #endif @@ -1383,6 +1386,35 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY ); CheckParaMarkerRedline( xParaEnd ); } + + // set top margin of the previous auto paragraph in cells, keeping zero bottom margin only at the first one + if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth && m_xPreviousParagraph.is()) + { + bool bParaChangedTopMargin = false; + auto itParaTopMargin = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue) + { + return rValue.Name == "ParaTopMargin"; + }); + if (itParaTopMargin != aProperties.end()) + bParaChangedTopMargin = true; + + uno::Sequence<beans::PropertyValue> aPrevPropertiesSeq; + m_xPreviousParagraph->getPropertyValue("ParaInteropGrabBag") >>= aPrevPropertiesSeq; + auto aPrevProperties = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aPrevPropertiesSeq); + auto itPrevParaAutoBefore = std::find_if(aPrevProperties.begin(), aPrevProperties.end(), [](const beans::PropertyValue& rValue) + { + return rValue.Name == "ParaTopMarginBeforeAutoSpacing"; + }); + bool bPrevParaAutoBefore = itPrevParaAutoBefore != aPrevProperties.end(); + + if ((bPrevParaAutoBefore && !bParaChangedTopMargin) || (bParaChangedTopMargin && m_bParaAutoBefore)) + { + sal_Int32 nSize = m_bFirstParagraphInCell ? 0 : 280; + // Previous before spacing is set to auto, set previous before space to 280, except in the first paragraph. + m_xPreviousParagraph->setPropertyValue("ParaTopMargin", + uno::makeAny( ConversionHelper::convertTwipToMM100(nSize))); + } + } } if( !bKeepLastParagraphProperties ) rAppendContext.pLastParagraphProperties = pToBeSavedProperties; @@ -1395,6 +1427,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) { SAL_WARN( "writerfilter.dmapper", "finishParagraph() " << e ); } + } bool bIgnoreFrameState = IsInHeaderFooter(); @@ -1413,6 +1446,12 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) if (m_bIsFirstParaInShape) m_bIsFirstParaInShape = false; + // keep m_bParaAutoAfter for table paragraphs + m_bPrevParaAutoAfter = m_bParaAutoAfter || m_bPrevParaAutoAfter; + + // not auto margin in this paragraph + m_bParaChangedBottomMargin = (pParaContext && pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN) && !m_bParaAutoAfter); + if (pParaContext) { // Reset the frame properties for the next paragraph @@ -1421,10 +1460,18 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap ) SetIsOutsideAParagraph(true); m_bParaHadField = false; + + // don't overwrite m_bFirstParagraphInCell in table separator nodes + if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth) + m_bFirstParagraphInCell = false; + m_bParaAutoBefore = false; + m_bParaAutoAfter = false; + #ifdef DEBUG_WRITERFILTER TagLogger::getInstance().endElement(); #endif + } void DomainMapper_Impl::appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap ) @@ -1818,6 +1865,7 @@ void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) { m_bInFootOrEndnote = true; m_bCheckFirstFootnoteTab = true; + m_bSaveFirstParagraphInCell = m_bFirstParagraphInCell; try { // Redlines outside the footnote should not affect footnote content @@ -1984,6 +2032,7 @@ void DomainMapper_Impl::PopFootOrEndnote() m_aRedlines.pop(); m_bSeenFootOrEndnoteSeparator = false; m_bInFootOrEndnote = false; + m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell; } void DomainMapper_Impl::SeenFootOrEndnoteSeparator() @@ -2333,9 +2382,33 @@ bool DomainMapper_Impl::IsDiscardHeaderFooter() return m_bDiscardHeaderFooter; } +// called from TableManager::closeCell() void DomainMapper_Impl::ClearPreviousParagraph() { + // in table cells, set bottom auto margin of last paragraph to 0, except in paragraphs with numbering + if ((m_nTableDepth == (m_nTableCellDepth + 1)) && m_xPreviousParagraph.is() && !m_bParaChangedBottomMargin) + { + 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(); + + bool bPrevNumberingRules = false; + uno::Reference<container::XNamed> xPreviousNumberingRules(m_xPreviousParagraph->getPropertyValue("NumberingRules"), uno::UNO_QUERY); + if (xPreviousNumberingRules.is()) + bPrevNumberingRules = !xPreviousNumberingRules->getName().isEmpty(); + if (!bPrevNumberingRules && (bPrevParaAutoAfter || m_bPrevParaAutoAfter)) + m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", uno::makeAny(static_cast<sal_Int32>(0))); + } + m_xPreviousParagraph.clear(); + + // next table paragraph will be first paragraph in a cell + m_bFirstParagraphInCell = true; } static sal_Int16 lcl_ParseNumberingType( const OUString& rCommand ) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 187c6f435d30..555c2dd35bb9 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -975,6 +975,7 @@ public: bool IsDiscardHeaderFooter(); void SetParaAutoBefore(bool bParaAutoBefore) { m_bParaAutoBefore = bParaAutoBefore; } + void SetParaAutoAfter(bool bParaAutoAfter) { m_bParaAutoAfter = bParaAutoAfter; } /// Forget about the previous paragraph, as it's not inside the same /// start/end node. @@ -988,6 +989,14 @@ private: css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph; /// Current paragraph has automatic before spacing. bool m_bParaAutoBefore; + /// Current paragraph has automatic after spacing. + bool m_bParaAutoAfter; + /// Paragraph has direct top or bottom margin formattings + bool m_bPrevParaAutoAfter; + bool m_bParaChangedBottomMargin; + /// Current paragraph in a table is first paragraph of a cell + bool m_bFirstParagraphInCell; + bool m_bSaveFirstParagraphInCell; }; } //namespace dmapper |