diff options
-rw-r--r-- | sw/qa/extras/ooxmlimport/data/tdf99140.docx | bin | 0 -> 13349 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 15 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 13 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.cxx | 78 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.hxx | 3 |
5 files changed, 84 insertions, 25 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/tdf99140.docx b/sw/qa/extras/ooxmlimport/data/tdf99140.docx Binary files differnew file mode 100644 index 000000000000..42fa73d2f8e0 --- /dev/null +++ b/sw/qa/extras/ooxmlimport/data/tdf99140.docx diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index a5b5cac303e7..39c469a86630 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -2917,6 +2917,21 @@ DECLARE_OOXMLIMPORT_TEST(testTdf98882, "tdf98882.docx") CPPUNIT_ASSERT_EQUAL(nFlyHeight, nContentHeight); } +DECLARE_OOXMLIMPORT_TEST(testTdf99140, "tdf99140.docx") +{ + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xTextDocument, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + // This was 1: a multi-page floating table was imported as a TextFrame. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount()); + + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xTableProperties(xTables->getByIndex(1), uno::UNO_QUERY); + // This was text::HoriOrientation::NONE, the second table was too wide due to this. + CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::LEFT_AND_WIDTH, getProperty<sal_Int16>(xTableProperties, "HoriOrient")); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 5dcae2b81843..f1c393f4bbe4 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -286,20 +286,21 @@ bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const Prope return false; } -} - -bool lcl_extractHoriOrient(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32& nHoriOrient) +void lcl_extractHoriOrient(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32& nHoriOrient) { // Shifts the frame left by the given value. for (size_t i = 0; i < rFrameProperties.size(); ++i) { if (rFrameProperties[i].Name == "HoriOrient") { - nHoriOrient = rFrameProperties[i].Value.get<sal_Int32>(); - return true; + sal_Int32 nValue = rFrameProperties[i].Value.get<sal_Int32>(); + if (nValue != text::HoriOrientation::NONE) + nHoriOrient = nValue; + return; } } - return false; +} + } void lcl_DecrementHoriOrientPosition(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount) diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index ad06b9eee043..d2e1b41801e8 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -36,6 +36,8 @@ #include <com/sun/star/style/XStyle.hpp> #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> #include <com/sun/star/text/WritingMode.hpp> #include <com/sun/star/text/XTextColumns.hpp> #include <com/sun/star/text/XText.hpp> @@ -1021,34 +1023,72 @@ void SectionPropertyMap::HandleMarginsHeaderFooter(DomainMapper_Impl& rDM_Impl) PrepareHeaderFooterProperties( false ); } +bool SectionPropertyMap::FloatingTableConversion(FloatingTableInfo& rInfo) +{ + // 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. + + sal_Int32 nPageWidth = GetPageWidth(); + sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin(); + // Count the layout width of the table. + sal_Int32 nTableWidth = rInfo.m_nTableWidth; + sal_Int32 nLeftMargin = 0; + if (rInfo.getPropertyValue("LeftMargin") >>= nLeftMargin) + nTableWidth += nLeftMargin; + sal_Int32 nRightMargin = 0; + if (rInfo.getPropertyValue("RightMargin") >>= nRightMargin) + nTableWidth += nRightMargin; + + sal_Int16 nHoriOrientRelation = rInfo.getPropertyValue("HoriOrientRelation").get<sal_Int16>(); + sal_Int16 nVertOrientRelation = rInfo.getPropertyValue("VertOrientRelation").get<sal_Int16>(); + if (nHoriOrientRelation == text::RelOrientation::PAGE_FRAME && nVertOrientRelation == text::RelOrientation::PAGE_FRAME) + { + sal_Int16 nHoriOrient = rInfo.getPropertyValue("HoriOrient").get<sal_Int16>(); + sal_Int16 nVertOrient = rInfo.getPropertyValue("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("HoriOrientPosition").get<sal_Int32>(); + sal_Int32 nVertOrientPosition = rInfo.getPropertyValue("VertOrientPosition").get<sal_Int32>(); + sal_Int32 nPageHeight = getProperty(PROP_HEIGHT)->second.get<sal_Int32>(); + if (nHoriOrientPosition < (nPageWidth / 2) && nVertOrientPosition > (nPageHeight / 2)) + return false; + } + } + + // If the table is wider than the text area, then don't create a fly + // for the table: no wrapping will be performed anyway, but multi-page + // tables will be broken. + if (nTableWidth < nTextAreaWidth) + return true; + + // If the position is relative to the edge of the page, then we always + // create the fly. + if (rInfo.getPropertyValue("HoriOrientRelation") == text::RelOrientation::PAGE_FRAME) + return true; + + // If there are columns, always create the fly, otherwise the columns would + // restrict geometry of the table. + if (ColumnCount() + 1 >= 2) + return true; + + return false; +} + 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; - sal_Int32 nTextAreaWidth = GetPageWidth() - GetLeftMargin() - GetRightMargin(); uno::Reference<text::XTextAppendAndConvert> xBodyText( rDM_Impl.GetBodyText(), uno::UNO_QUERY ); for (size_t i = 0; i < rPendingFloatingTables.size(); ++i) { FloatingTableInfo& rInfo = rPendingFloatingTables[i]; - // Count the layout width of the table. - sal_Int32 nTableWidth = rInfo.m_nTableWidth; - sal_Int32 nLeftMargin = 0; - if (rInfo.getPropertyValue("LeftMargin") >>= nLeftMargin) - nTableWidth += nLeftMargin; - sal_Int32 nRightMargin = 0; - if (rInfo.getPropertyValue("RightMargin") >>= nRightMargin) - nTableWidth += nRightMargin; - - // If the table is wider than the text area, then don't create a fly - // for the table: no wrapping will be performed anyway, but multi-page - // tables will be broken. - // If the position is relative to the edge of the page, then we always - // create the fly. - // If there are columns, always create the fly, otherwise the columns would - // restrict geometry of the table. - if ( ( rInfo.getPropertyValue("HoriOrientRelation") == text::RelOrientation::PAGE_FRAME ) || - nTableWidth < nTextAreaWidth || ColumnCount() + 1 >= 2 ) + if (FloatingTableConversion(rInfo)) xBodyText->convertToTextFrame(rInfo.m_xStart, rInfo.m_xEnd, rInfo.m_aFrameProperties); } rPendingFloatingTables.clear(); diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 64cda4d184b2..1be5794b039b 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -56,6 +56,7 @@ namespace com{namespace sun{namespace star{ namespace writerfilter { namespace dmapper{ class DomainMapper_Impl; +struct FloatingTableInfo; enum BorderPosition { @@ -256,6 +257,8 @@ class SectionPropertyMap : public PropertyMap sal_Int32 nDistance, sal_Int32 nOffsetFrom, sal_uInt32 nLineWidth); + /// Determintes if conversion of a given floating table is wanted or not. + bool FloatingTableConversion(FloatingTableInfo& rInfo); public: explicit SectionPropertyMap(bool bIsFirstSection); |