[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - sw/qa writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Apr 14 08:11:06 UTC 2016


 sw/qa/extras/ooxmlimport/data/tdf99140.docx              |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                 |   15 ++
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx |   13 +-
 writerfilter/source/dmapper/PropertyMap.cxx              |   78 +++++++++++----
 writerfilter/source/dmapper/PropertyMap.hxx              |    3 
 5 files changed, 84 insertions(+), 25 deletions(-)

New commits:
commit 168e55d3d05224c790824ec71677ff787371ad48
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Apr 7 16:47:23 2016 +0200

    tdf#99140 DOCX import: fix table at the bottom of the page to span over ...
    
    ... multiple pages.
    
    In short, one more blacklist entry when conversion should not be
    performed.
    
    Conflicts:
    	sw/qa/extras/ooxmlimport/ooxmlimport.cxx
    
    Also (because otherwise the first commit would introduce a regression):
    
    tdf#99140 DOCX import: fix table horizontal aligment to be 'from left' ...
    
    ... when it was 'manual'.
    
    Regression from commit c1e563f6efd09cd3463f1b92a3022ae288c92087
    (fdo#76741 [DOCX] Table Alignment and width type, 2014-04-04), DOCX
    import code had to deal with two kinds of horizontal alignment when it
    came to floating tables: the alignment of the table itself, and the
    alignment of the float parameters. The problem is, in general it's
    wanted that the table is aligned according to the floating parameters,
    but in Writer the "from left" UI setting is described differently for
    tables and fly frames: tables use LEFT_AND_WIDTH for that, while fly
    frames use NONE.
    
    Fix the problem by touching the default only in case the floating
    parameters have something that's different from NONE.
    
    With this, the width of tables is no longer lost when they are described
    to be floating ones in the DOCX markup, but FloatingTableConversion()
    decides to ignore that.
    
    (cherry picked from commits d56deaeb2a1e8007e50fc2334f416fddd4e3cde3,
    c07f04ab422eadba0f2c3c128a0e3ff78e90cdf2, and
    fd61dee6457a44687f1142dd55bfee6b64fda2ef)
    
    Change-Id: I764f02cc58ae1b7af802b81e570e4feaf73ee2c1
    Reviewed-on: https://gerrit.libreoffice.org/23986
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sw/qa/extras/ooxmlimport/data/tdf99140.docx b/sw/qa/extras/ooxmlimport/data/tdf99140.docx
new file mode 100644
index 0000000..42fa73d
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf99140.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index a634825..d1c5b08 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -3087,6 +3087,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"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index ac566f7..d21f5f7 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -287,20 +287,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 3d712ba..e15c259 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>
@@ -997,34 +999,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 649ad1bd..79fc213 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -57,6 +57,7 @@ namespace com{namespace sun{namespace star{
 namespace writerfilter {
 namespace dmapper{
 class DomainMapper_Impl;
+struct FloatingTableInfo;
 
 enum BorderPosition
 {
@@ -251,6 +252,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);


More information about the Libreoffice-commits mailing list