sw/source/filter/ww8/ww8par.cxx | 4 writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 88 +-------- writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2 writerfilter/source/dmapper/PropertyMap.cxx | 143 --------------- writerfilter/source/dmapper/PropertyMap.hxx | 3 5 files changed, 19 insertions(+), 221 deletions(-)
New commits: commit c50bf5a5daaae3d40f89ea0784a75a8a571c208d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Apr 12 09:20:12 2023 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Apr 12 10:41:35 2023 +0200 sw floattable: remove no longer needed DOCX import heuristics Now that IsFlySplitAllowed() is true, m_aPendingFloatingTables and related code can go in writerfilter/. Change-Id: Id69e13e82fc447ad56b9f3926e353c203e600141 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150257 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 7c07fc0e94ec..4782992c2986 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -2623,10 +2623,6 @@ bool SwWW8ImplReader::FloatingTableConversion(WW8PLCFx_Cp_FKP* pPap) { // This is ww8 version of the code deciding if the table needs to be // in a floating frame. - // For OOXML code, see SectionPropertyMap::FloatingTableConversion in - // writerfilter/source/dmapper/PropertyMap.cxx - // The two should do ~same, so if you make changes here, please check - // that the other is in sync. // Note that this is just a list of heuristics till sw core can have a // table that is floating and can span over multiple pages at the same diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 51de86e89fe6..5bd89ee41289 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -59,22 +59,6 @@ #include <utility> #endif -namespace -{ -bool IsFlySplitAllowed() -{ - bool bRet - = officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::get(); - - if (bRet) - { - bRet = getenv("SW_DISABLE_FLY_SPLIT") == nullptr; - } - - return bRet; -} -} - namespace writerfilter::dmapper { using namespace ::com::sun::star; @@ -374,29 +358,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo comphelper::SequenceAsHashMap aGrabBag; - if (nullptr != m_rDMapper_Impl.getTableManager().getCurrentTableRealPosition()) - { - TablePositionHandler *pTablePositions = m_rDMapper_Impl.getTableManager().getCurrentTableRealPosition(); - - uno::Sequence< beans::PropertyValue > aGrabBagTS{ - comphelper::makePropertyValue("bottomFromText", pTablePositions->getBottomFromText()), - comphelper::makePropertyValue("horzAnchor", pTablePositions->getHorzAnchor()), - comphelper::makePropertyValue("leftFromText", pTablePositions->getLeftFromText()), - comphelper::makePropertyValue("rightFromText", pTablePositions->getRightFromText()), - comphelper::makePropertyValue("tblpX", pTablePositions->getX()), - comphelper::makePropertyValue("tblpXSpec", pTablePositions->getXSpec()), - comphelper::makePropertyValue("tblpY", pTablePositions->getY()), - comphelper::makePropertyValue("tblpYSpec", pTablePositions->getYSpec()), - comphelper::makePropertyValue("topFromText", pTablePositions->getTopFromText()), - comphelper::makePropertyValue("vertAnchor", pTablePositions->getVertAnchor()) - }; - - if (!IsFlySplitAllowed()) - { - aGrabBag["TablePosition"] <<= aGrabBagTS; - } - } - else if (bConvertToFloatingInFootnote) + if (bConvertToFloatingInFootnote) { // define empty "TablePosition" to avoid export temporary floating aGrabBag["TablePosition"] = uno::Any(); @@ -1586,10 +1548,8 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab comphelper::makePropertyValue("IsFollowingTextFlow", true)); } - if (IsFlySplitAllowed()) - { - aFrameProperties.push_back(comphelper::makePropertyValue("IsSplitAllowed", true)); - } + // A text frame created for floating tables is always allowed to split. + aFrameProperties.push_back(comphelper::makePropertyValue("IsSplitAllowed", true)); // In case the document ends with a table, we're called after // SectionPropertyMap::CloseSectionGroup(), so we'll have no idea @@ -1604,35 +1564,25 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); sal_Int32 nTableWidthType = text::SizeType::FIX; m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); - // Split flys don't need to go via m_aPendingFloatingTables. - if (m_rDMapper_Impl.GetSectionContext() && nestedTableLevel <= 1 && !m_rDMapper_Impl.IsInHeaderFooter() && !IsFlySplitAllowed()) + // m_xText points to the body text, get the current xText from m_rDMapper_Impl, in case e.g. we would be in a header. + uno::Reference<text::XTextAppendAndConvert> xTextAppendAndConvert(m_rDMapper_Impl.GetTopTextAppend(), uno::UNO_QUERY); + // Only execute the conversion if the table is not anchored at + // the start of an outer table cell, that's not yet + // implemented. + // Multi-page floating tables works if an outer/toplevel table is floating, but not + // when an inner table would float. + bool bToplevelSplitFly = nestedTableLevel <= 1; + if (xTextAppendAndConvert.is() && (!bTableStartsAtCellStart || bToplevelSplitFly)) { - m_rDMapper_Impl.m_aPendingFloatingTables.emplace_back(xStart, xEnd, - comphelper::containerToSequence(aFrameProperties), - nTableWidth, nTableWidthType, bConvertToFloating); - } - else - { - // m_xText points to the body text, get the current xText from m_rDMapper_Impl, in case e.g. we would be in a header. - uno::Reference<text::XTextAppendAndConvert> xTextAppendAndConvert(m_rDMapper_Impl.GetTopTextAppend(), uno::UNO_QUERY); - // Only execute the conversion if the table is not anchored at - // the start of an outer table cell, that's not yet - // implemented. - // Multi-page floating tables works if an outer/toplevel table is floating, but not - // when an inner table would float. - bool bToplevelSplitFly = IsFlySplitAllowed() && nestedTableLevel <= 1; - if (xTextAppendAndConvert.is() && (!bTableStartsAtCellStart || bToplevelSplitFly)) - { - std::deque<css::uno::Any> aFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; - std::vector<sal_Int32> redPos, redLen; - std::vector<OUString> redCell; - std::vector<OUString> redTable; - BeforeConvertToTextFrame(aFramedRedlines, redPos, redLen, redCell, redTable); + std::deque<css::uno::Any> aFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; + std::vector<sal_Int32> redPos, redLen; + std::vector<OUString> redCell; + std::vector<OUString> redTable; + BeforeConvertToTextFrame(aFramedRedlines, redPos, redLen, redCell, redTable); - xTextAppendAndConvert->convertToTextFrame(xStart, xEnd, comphelper::containerToSequence(aFrameProperties)); + xTextAppendAndConvert->convertToTextFrame(xStart, xEnd, comphelper::containerToSequence(aFrameProperties)); - AfterConvertToTextFrame(m_rDMapper_Impl, aFramedRedlines, redPos, redLen, redCell, redTable); - } + AfterConvertToTextFrame(m_rDMapper_Impl, aFramedRedlines, redPos, redLen, redCell, redTable); } } diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 5d935b5e3664..15cf63dec626 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -1145,8 +1145,6 @@ public: /// If the next tab should be ignored, used for footnotes. bool m_bCheckFirstFootnoteTab; bool m_bIgnoreNextTab; - /// Pending floating tables: they may be converted to text frames at the section end. - std::vector<FloatingTableInfo> m_aPendingFloatingTables; /// Paragraphs with anchored objects in the current section. std::vector<AnchoredObjectsInfo> m_aAnchoredObjectAnchors; diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 7794249350e8..96fed09f617f 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1131,99 +1131,6 @@ void SectionPropertyMap::HandleMarginsHeaderFooter( bool bFirstPage, DomainMappe rDM_Impl.ConvertHeaderFooterToTextFrame(m_bDynamicHeightTop, m_bDynamicHeightBottom); } -bool SectionPropertyMap::FloatingTableConversion( const DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo ) -{ - // always convert non-floating tables to floating ones in footnotes and endnotes - if ( rInfo.m_bConvertToFloatingInFootnote ) - return true; - // This is OOXML version of the code deciding if the table needs to be - // in a floating frame. - // For ww8 code, see SwWW8ImplReader::FloatingTableConversion in - // sw/source/filter/ww8/ww8par.cxx - // The two should do the same, so if you make changes here, please check - // that the other is in sync. - - // Note that this is just a list of heuristics till sw core can have a - // table that is floating and can span over multiple pages at the same - // time. - - // If there is an explicit section break right after a table, then there - // will be no wrapping anyway. - if (rDM_Impl.m_bConvertedTable && !rDM_Impl.GetIsLastSectionGroup() && rInfo.m_nBreakType == NS_ooxml::LN_Value_ST_SectionMark_nextPage) - return false; - - sal_Int32 nVertOrientPosition = rInfo.getPropertyValue(u"VertOrientPosition").get<sal_Int32>(); - sal_Int16 nHoriOrientRelation = rInfo.getPropertyValue( u"HoriOrientRelation" ).get<sal_Int16>(); - if (nVertOrientPosition < 0 && nHoriOrientRelation != text::RelOrientation::PAGE_FRAME) - { - // Negative vertical position: then need a floating table, as normal tables can't have - // negative top margins. - return true; - } - - sal_Int32 nPageWidth = GetPageWidth(); - sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin(); - // Count the layout width of the table. - sal_Int32 nTableWidth = rInfo.m_nTableWidth; - if (rInfo.m_nTableWidthType == text::SizeType::VARIABLE) - { - nTableWidth *= nTextAreaWidth / 100.0; - } - sal_Int32 nLeftMargin = 0; - if ( rInfo.getPropertyValue( u"LeftMargin" ) >>= nLeftMargin ) - nTableWidth += nLeftMargin; - sal_Int32 nRightMargin = 0; - if ( rInfo.getPropertyValue( u"RightMargin" ) >>= nRightMargin ) - nTableWidth += nRightMargin; - - sal_Int16 nVertOrientRelation = rInfo.getPropertyValue( u"VertOrientRelation" ).get<sal_Int16>(); - if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME && nVertOrientRelation == text::RelOrientation::PAGE_FRAME ) - { - sal_Int16 nHoriOrient = rInfo.getPropertyValue( u"HoriOrient" ).get<sal_Int16>(); - sal_Int16 nVertOrient = rInfo.getPropertyValue( u"VertOrient" ).get<sal_Int16>(); - if ( nHoriOrient == text::HoriOrientation::NONE && nVertOrient == text::VertOrientation::NONE ) - { - // Anchor position is relative to the page horizontally and vertically as well and is an absolute position. - // The more close we are to the left edge, the less likely there will be any wrapping. - // The more close we are to the bottom, the more likely the table will span over to the next page - // So if we're in the bottom left quarter, don't do any conversion. - sal_Int32 nHoriOrientPosition = rInfo.getPropertyValue( u"HoriOrientPosition" ).get<sal_Int32>(); - sal_Int32 nPageHeight = getProperty( PROP_HEIGHT )->second.get<sal_Int32>(); - if ( nHoriOrientPosition < (nPageWidth / 2) && nVertOrientPosition >( nPageHeight / 2 ) ) - return false; - } - } - - // It seems Word has a limit here, so that in case the table width is quite - // close to the text area width, then it won't perform a wrapping, even in - // case the content (e.g. an empty paragraph) would fit. The magic constant - // here represents this limit. - const sal_Int32 nMagicNumber = 469; - - // If the table's width is smaller than the text area width, text might - // be next to the table and so it should behave as a floating table. - if ( (nTableWidth + nMagicNumber) < nTextAreaWidth ) - return true; - - // If the position is relative to the edge of the page, then we need to check the whole - // page width to see whether text can fit next to the table. - if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME ) - { - // If the table is wide enough so that no text fits next to it, then don't create a fly - // for the table: no wrapping will be performed anyway, but multi-page - // tables will be broken. - if ((nTableWidth + nMagicNumber) < (nPageWidth - std::min(GetLeftMargin(), GetRightMargin()))) - return true; - } - - // If there are columns, always create the fly, otherwise the columns would - // restrict geometry of the table. - if ( ColumnCount() > 1 ) - return true; - - return false; -} - void SectionPropertyMap::InheritOrFinalizePageStyles( DomainMapper_Impl& rDM_Impl ) { // if no new styles have been created for this section, inherit from the previous section, @@ -1485,56 +1392,6 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) } } - // Text area width is known at the end of a section: decide if tables should be converted or not. - std::vector<FloatingTableInfo>& rPendingFloatingTables = rDM_Impl.m_aPendingFloatingTables; - for ( FloatingTableInfo & rInfo : rPendingFloatingTables ) - { - rInfo.m_nBreakType = m_nBreakType; - if ( FloatingTableConversion( rDM_Impl, rInfo ) ) - { - uno::Reference<text::XTextAppendAndConvert> xBodyText( - rInfo.m_bConvertToFloatingInFootnote - ? rInfo.m_xStart->getText() - : rDM_Impl.GetBodyText(), uno::UNO_QUERY ); - std::deque<css::uno::Any> aFramedRedlines = rDM_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; - try - { - std::vector<sal_Int32> redPos, redLen; - std::vector<OUString> redCell; - std::vector<OUString> redTable; - BeforeConvertToTextFrame(aFramedRedlines, redPos, redLen, redCell, redTable); - const uno::Reference< text::XTextContent >& xTextContent = - xBodyText->convertToTextFrame(rInfo.m_xStart, rInfo.m_xEnd, - rInfo.m_aFrameProperties); - - // paragraph of the anchoring point of the floating table needs zero top and bottom - // margins, if the table was a not floating table in the footnote, otherwise - // docDefault margins could result bigger vertical spaces around the table - if ( rInfo.m_bConvertToFloatingInFootnote && xTextContent.is() ) - { - uno::Reference<beans::XPropertySet> xParagraph( - xTextContent->getAnchor(), uno::UNO_QUERY); - if ( xParagraph.is() ) - { - xParagraph->setPropertyValue("ParaTopMargin", - uno::Any(static_cast<sal_Int32>(0))); - xParagraph->setPropertyValue("ParaBottomMargin", - uno::Any(static_cast<sal_Int32>(0))); - } - } - - AfterConvertToTextFrame(rDM_Impl, aFramedRedlines, redPos, redLen, redCell, redTable); - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "convertToTextFrame() failed"); - } - - aFramedRedlines.clear(); - } - } - rPendingFloatingTables.clear(); - try { HandleIncreasedAnchoredObjectSpacing(rDM_Impl); diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index b458b70967b1..650a51506bf8 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -324,9 +324,6 @@ private: sal_uInt32 nLineWidth, DomainMapper_Impl& rDM_Impl ); - // Determines if conversion of a given floating table is wanted or not. - bool FloatingTableConversion( const DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo ); - /// Increases paragraph spacing according to Word 2013+ needs if necessary. void HandleIncreasedAnchoredObjectSpacing(DomainMapper_Impl& rDM_Impl);