include/svx/svdotable.hxx                       |    7 ++++++
 oox/source/drawingml/shape.cxx                  |   25 ++++++++++++++++++++++++
 sd/qa/unit/data/pptx/tdf144092-tableHeight.pptx |binary
 sd/qa/unit/export-tests-ooxml2.cxx              |    2 -
 sd/qa/unit/import-tests2.cxx                    |   17 ++++++++++++++++
 svx/source/table/svdotable.cxx                  |   12 +++++++++++
 svx/source/table/tablelayouter.hxx              |    6 ++---
 7 files changed, 65 insertions(+), 4 deletions(-)

New commits:
commit d29f1ffc03ac0ea2c5eb77ef6272259fe25e05c4
Author:     Sarper Akdemir <[email protected]>
AuthorDate: Wed Aug 17 16:23:29 2022 +0300
Commit:     Sarper Akdemir <[email protected]>
CommitDate: Mon Sep 5 14:22:11 2022 +0200

    tdf#144092 pptx import: correct table height during import
    
    It appears PowerPoint can export rows of a table with row heights that
    is less than the minimum height (for that row). And also export the
    total table height wrong with it.
    
    If PowerPoint imports such a table, those rows are individually
    expanded to the minimum height. (Also increasing the table's total
    height)
    
    In Impress import we calculate table height by adding up individual
    row heights. Table layouting code depends on the table height being
    correct. This is why rows with less than minimum height lead to
    layouting problems.
    
    To compensate for this, while importing tables, layouting is skipped
    until the table height is updated with the corrected height.
    
    The correct height is calculated by layouting the table without
    fitting to an area (i.e with bFit = false).
    
    Change-Id: I79187882470a4e285b45bca1eabb469a084067f5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138652
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <[email protected]>
    (cherry picked from commit a5126a21351c87138ff86a6636326eb6cd6a0f8c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139218
    Reviewed-by: Sarper Akdemir <[email protected]>

diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx
index 18497bcc2494..030bb643b75c 100644
--- a/include/svx/svdotable.hxx
+++ b/include/svx/svdotable.hxx
@@ -256,6 +256,13 @@ public:
     /// Next time layouting would be done, skip it (to layout at the end of 
multiple actions).
     void SetSkipChangeLayout(bool bSkipChangeLayout);
 
+    /** Tries to get table height if rows with sizes less then the minimum 
size were expanded
+
+        (i.e. Table height layouted without fitting to an area)
+        Helper for OOXML import
+     */
+    sal_Int32 getHeightWithoutFitting();
+
     virtual void onEditOutlinerStatusEvent( EditStatus* pEditStatus ) override;
 
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index de0c17bd9dc7..50bc2f8bc9c4 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -94,6 +94,7 @@
 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
 #include <com/sun/star/text/GraphicCrop.hpp>
 #include <svx/svdobj.hxx>
+#include <svx/svdotable.hxx>
 #include <svx/svdtrans.hxx>
 #include <tools/stream.hxx>
 #include <unotools/streamwrap.hxx>
@@ -834,6 +835,8 @@ Reference< XShape > const & Shape::createAndInsert(
         maSize.Height = 0;
         for (auto const& elem : mpTablePropertiesPtr->getTableRows())
         {
+            // WARN: When less then minimum sized rows exist, calculated 
height here
+            // is corrected before layouting takes place
             maSize.Height = o3tl::saturating_add(maSize.Height, 
elem.getHeight());
         }
     }
@@ -1256,7 +1259,14 @@ Reference< XShape > const & Shape::createAndInsert(
             mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, 
rGraphicHelper, mbFlipH, mbFlipV );
         }
         if ( mpTablePropertiesPtr && aServiceName == 
"com.sun.star.drawing.TableShape" )
+        {
             mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, 
mpMasterTextListStyle );
+            if ( auto* pTableShape = 
dynamic_cast<sdr::table::SdrTableObj*>(SdrObject::getSdrObjectFromXShape(mxShape))
 )
+            {
+                // Disable layouting until an attempt at correcting faulty 
table height is made
+                pTableShape->SetSkipChangeLayout(true);
+            }
+        }
 
         FillProperties aFillProperties = getActualFillProperties(pTheme, 
&rShapeOrParentShapeFillProps);
         if (getFillProperties().moFillType.has() && 
getFillProperties().moFillType.get() == XML_grpFill)
@@ -1487,6 +1497,21 @@ Reference< XShape > const & Shape::createAndInsert(
             }
 
             PropertySet( xSet ).setProperties( aShapeProps );
+
+            if (mpTablePropertiesPtr && aServiceName == 
"com.sun.star.drawing.TableShape")
+            {
+                // Powerpoint sometimes export row heights less than the 
minimum size,
+                // which during import expanded to the minimum
+                if (auto* pTableShape = 
dynamic_cast<sdr::table::SdrTableObj*>(SdrObject::getSdrObjectFromXShape(mxShape)))
+                {
+                    sal_Int32 nCorrectedHeight = 
pTableShape->getHeightWithoutFitting();
+                    const auto& aShapeSize = mxShape->getSize();
+                    if( nCorrectedHeight > aShapeSize.Height )
+                        mxShape->setSize( {aShapeSize.Width, nCorrectedHeight} 
);
+                    pTableShape->SetSkipChangeLayout(false);
+                }
+            }
+
             if (mbLockedCanvas)
             {
                 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
diff --git a/sd/qa/unit/data/pptx/tdf144092-tableHeight.pptx 
b/sd/qa/unit/data/pptx/tdf144092-tableHeight.pptx
new file mode 100644
index 000000000000..c597abf9a620
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf144092-tableHeight.pptx 
differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index c74f5e41d925..fb57a721149e 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -442,7 +442,7 @@ void SdOOXMLExportTest2::testTdf119015()
     sdr::table::SdrTableObj* pTableObj = 
dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
     CPPUNIT_ASSERT(pTableObj);
     // The position was previously not properly initialized: (0, 0, 100, 100)
-    CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(6991, 6902), Size(14099, 
1999)),
+    CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(6991, 6902), Size(14099, 
2000)),
                          pTableObj->GetLogicRect());
     uno::Reference<table::XTable> xTable(pTableObj->getTable());
 
diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx
index 33bbcca615b7..6a98d409b725 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -136,6 +136,7 @@ public:
     void testTdf128596();
     void testDefaultTabStop();
     void testCropToZero();
+    void testTdf144092TableHeight();
 
     CPPUNIT_TEST_SUITE(SdImportTest2);
 
@@ -206,6 +207,7 @@ public:
     CPPUNIT_TEST(testTdf128596);
     CPPUNIT_TEST(testDefaultTabStop);
     CPPUNIT_TEST(testCropToZero);
+    CPPUNIT_TEST(testTdf144092TableHeight);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -2060,6 +2062,21 @@ void SdImportTest2::testCropToZero()
     
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/croppedTo0.pptx"), 
PPTX);
 }
 
+void SdImportTest2::testTdf144092TableHeight()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(
+        
m_directories.getURLFromSrc(u"sd/qa/unit/data/pptx/tdf144092-tableHeight.pptx"),
 PPTX);
+
+    uno::Reference<drawing::XShape> xTableShape(getShapeFromPage(0, 0, 
xDocShRef), uno::UNO_QUERY);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 7208
+    // - Actual  : 4595
+    // i.e. the table height wasn't corrected by expanding less than minimum 
sized rows.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(7208), xTableShape->getSize().Height);
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 1b1d643d26d9..8b46feb29309 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -2393,6 +2393,18 @@ void SdrTableObj::CropTableModelToSelection(const 
CellPos& rStart, const CellPos
     mpImpl->CropTableModelToSelection(rStart, rEnd);
 }
 
+sal_Int32 SdrTableObj::getHeightWithoutFitting()
+{
+    tools::Rectangle aRect{};
+    if( mpImpl.is() && mpImpl->mpLayouter)
+    {
+        mpImpl->mpLayouter->LayoutTableHeight(aRect, /*bFit=*/false);
+        return aRect.GetHeight();
+    }
+    else
+        return 0;
+}
+
 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 
nLastColumn, const bool bOptimize, const bool bMinimize )
 {
     if( mpImpl.is() && mpImpl->mpLayouter )
diff --git a/svx/source/table/tablelayouter.hxx 
b/svx/source/table/tablelayouter.hxx
index 309269bcce52..2ff69598e4e1 100644
--- a/svx/source/table/tablelayouter.hxx
+++ b/svx/source/table/tablelayouter.hxx
@@ -123,13 +123,13 @@ public:
                          const bool bMinimize );
     void dumpAsXml(xmlTextWriterPtr pWriter) const;
 
+    void LayoutTableWidth(::tools::Rectangle& rArea, bool bFit);
+    void LayoutTableHeight(::tools::Rectangle& rArea, bool bFit);
+
 private:
     CellRef getCell( const CellPos& rPos ) const;
     basegfx::B2ITuple getCellSize( const CellRef& xCell, const CellPos& rPos ) 
const;
 
-    void LayoutTableWidth( ::tools::Rectangle& rArea, bool bFit );
-    void LayoutTableHeight( ::tools::Rectangle& rArea, bool bFit );
-
     bool isValidColumn( sal_Int32 nColumn ) const { return (nColumn >= 0) && 
(o3tl::make_unsigned(nColumn) < maColumns.size()); }
     bool isValidRow( sal_Int32 nRow ) const { return (nRow >= 0) && 
(o3tl::make_unsigned(nRow) < maRows.size()); }
     bool isValid( const CellPos& rPos ) const { return isValidColumn( 
rPos.mnCol ) && isValidRow( rPos.mnRow ); }

Reply via email to