include/oox/drawingml/shape.hxx              |    3 
 include/svx/svdmodel.hxx                     |    4 
 oox/source/drawingml/shape.cxx               |    4 
 oox/source/ppt/slidepersist.cxx              |  232 +++++++++++++++++++++------
 sd/qa/unit/data/pptx/standardConnectors.pptx |binary
 sd/qa/unit/import-tests.cxx                  |   34 +++
 sd/source/ui/docshell/docshel4.cxx           |    8 
 svx/source/svdraw/svdmodel.cxx               |   21 ++
 svx/source/svdraw/svdoedge.cxx               |   10 -
 sw/qa/extras/rtfexport/data/tdf153681.odt    |binary
 sw/qa/extras/rtfexport/rtfexport5.cxx        |   16 +
 sw/source/filter/ww8/rtfattributeoutput.cxx  |    4 
 12 files changed, 281 insertions(+), 55 deletions(-)

New commits:
commit 2860a771f93e43b95250beee78351a58bffba1ff
Author:     Czeber László Ádám <czeber.laszloa...@nisz.hu>
AuthorDate: Mon Feb 27 13:31:33 2023 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Mar 8 19:17:22 2023 +0000

    tdf#153681 RTF export: fix extra cell regression at nested tables
    
    Table rows exported with an extra empty cell, if there was a
    nested table in them (and not in the last cell).
    
    Partial revert of commit 1f77a5e8d5bf8a7f1b7bd7206996d2b2efc59462
    "n#203704 fix RTF export table output for subtables".
    
    Note: the partially reverted code was for the old table format
    (used before OOo 2.3). This old format is partially converted to the
    new table format since commit e366c928819c44b5c253c45dca6dae40b71c9808
    "sw: ODF import: convert the simplest sub-tables to rowspan tables".
    
    Change-Id: I63ebefbb99e1a95cd60ce8d8dc34c307573d4b58
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147887
    Reviewed-by: László Németh <nem...@numbertext.org>
    Tested-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 6ddffa9841a20b7fddd3f742c88dba7d51cf9114)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147984
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/rtfexport/data/tdf153681.odt 
b/sw/qa/extras/rtfexport/data/tdf153681.odt
new file mode 100644
index 000000000000..2e2e71740de0
Binary files /dev/null and b/sw/qa/extras/rtfexport/data/tdf153681.odt differ
diff --git a/sw/qa/extras/rtfexport/rtfexport5.cxx 
b/sw/qa/extras/rtfexport/rtfexport5.cxx
index 1104b9e4683b..1b925713cc96 100644
--- a/sw/qa/extras/rtfexport/rtfexport5.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport5.cxx
@@ -1395,6 +1395,22 @@ DECLARE_RTFEXPORT_TEST(testTdf104390, "tdf104390.rtf")
     CPPUNIT_ASSERT_MESSAGE("Extra elements in paragraph", 
!xRunEnum->hasMoreElements());
 }
 
+DECLARE_RTFEXPORT_TEST(testTdf153681, "tdf153681.odt")
+{
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY_THROW);
+    uno::Reference<container::XIndexAccess> 
xTables(xTablesSupplier->getTextTables(),
+                                                    uno::UNO_QUERY_THROW);
+
+    // This is outside table
+    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(1), 
uno::UNO_QUERY_THROW);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 3
+    // Generates extra cell
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getColumns()->getCount());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c1221069936b..f2362a53d5b2 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1077,10 +1077,6 @@ void RtfAttributeOutput::EndTableRow()
 {
     SAL_INFO("sw.rtf", __func__ << ", (depth is " << m_nTableDepth << ")");
 
-    // Trying to end the row without writing the required number of cells? 
Fill with empty ones.
-    for (sal_uInt32 i = 0; i < m_aCells[m_nTableDepth]; i++)
-        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
-
     if (m_nTableDepth > 1)
     {
         m_aAfterRuns.append(
commit 5308d68a7cc0a4b38216438150adba2ac62e2bbe
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Thu Jan 26 09:17:56 2023 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Mar 8 19:17:11 2023 +0000

    tdf#149756 tdf#152545 PPTX import: position of standard connector - part2
    
    and add new compatibility option "ConnectorUseSnapRect".
    
    Standard connectors (bentConnector3, bentConnector4, bentConnector5)
    are improved. MSO calculates the edge track differently, so have
    to add "ConnectorUseSnapRect" compatibility option:
    
    - For PPTX file format, it is set to true and use the snap rectangle
    
    - For ODP format, it is set to false by default and use the bounding
      rectangle.
    
    Follow-up to commit eec48130271188cab63665acedbabf1ff5e850a2
    "tdf#148926 tdf#151678 PPTX import: position of standard
    connector - part1" (bentConnector2)
    
    Change-Id: Icca84708d6e10d44ebf7262415d055ce9cfc157d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146162
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148480
    Tested-by: Jenkins

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 36017132e83d..72ce51ef6476 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -137,6 +137,7 @@ public:
     CustomShapePropertiesPtr&       getCustomShapeProperties(){ return 
mpCustomShapePropertiesPtr; }
 
     OUString&                       getConnectorName() { return 
msConnectorName; }
+    std::vector<OUString>&          getConnectorAdjustments() { return 
maConnectorAdjustmentList; };
     ConnectorShapePropertiesList&   getConnectorShapeProperties() { return 
maConnectorShapePropertiesList; }
     void                            setConnectorShape(bool bConnector) { 
mbConnector = bConnector; }
     bool                            isConnectorShape() const { return 
mbConnector; }
@@ -330,6 +331,8 @@ protected:
     css::awt::Size   maChSize;                 // only used for group shapes
     css::awt::Point  maChPosition;             // only used for group shapes
 
+    std::vector<OUString>       maConnectorAdjustmentList; // only used for 
connector shapes
+
     TextBodyPtr                 mpTextBody;
     LinePropertiesPtr           mpLinePropertiesPtr;
     LinePropertiesPtr           mpShapeRefLinePropPtr;
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index b5d93fa53eb7..853f76570c1c 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -579,6 +579,10 @@ public:
     void SetLegacySingleLineFontwork(bool bEnabled);
     bool IsLegacySingleLineFontwork() const;
 
+    // tdf#149756 compatibility flag
+    void SetConnectorUseSnapRect(bool bEnabled);
+    bool IsConnectorUseSnapRect() const;
+
     void ReformatAllTextObjects();
 
     std::unique_ptr<SdrOutliner> createOutliner( OutlinerMode nOutlinerMode );
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 059785edf6e5..fad591a93d04 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1835,6 +1835,10 @@ Reference< XShape > const & Shape::createAndInsert(
                 RTL_TEXTENCODING_UTF8);
             msConnectorName = sConnectorShapePresetTypeName;
 
+            auto aAdjustmentList = 
mpCustomShapePropertiesPtr->getAdjustmentGuideList();
+            for (size_t i = 0; i < aAdjustmentList.size(); i++)
+                
maConnectorAdjustmentList.push_back(aAdjustmentList[i].maFormula);
+
             sal_Int32 nType = mpCustomShapePropertiesPtr->getShapePresetType();
             switch (nType)
             {
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
index ca296561a52f..7298eea1247c 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -386,7 +386,7 @@ static void 
lcl_SetEdgeLineValue(uno::Reference<drawing::XShape>& rXConnector,
 {
     sal_Int32 nEdge = 0;
     awt::Point aStartPt, aEndPt;
-    tools::Rectangle aStartRect, aEndRect;
+    tools::Rectangle aS, aE; // Start, End rectangle
     uno::Reference<drawing::XShape> xStartSp, xEndSp;
     uno::Reference<beans::XPropertySet> xPropSet(rXConnector, uno::UNO_QUERY);
     xPropSet->getPropertyValue("EdgeStartPoint") >>= aStartPt;
@@ -401,80 +401,218 @@ static void 
lcl_SetEdgeLineValue(uno::Reference<drawing::XShape>& rXConnector,
     SdrObject* pStartObj = xStartSp.is() ? 
SdrObject::getSdrObjectFromXShape(xStartSp) : nullptr;
     SdrObject* pEndObj = xEndSp.is() ? 
SdrObject::getSdrObjectFromXShape(xEndSp) : nullptr;
 
-    sal_Int32 nStartSpLineW = 0;
     sal_Int32 nStartA = -1;
     sal_Int32 nEndA = -1;
     if (pStartObj)
     {
-        aStartRect = pStartObj->GetSnapRect();
-        uno::Reference<beans::XPropertySet> xPropxStartSp(xStartSp, 
uno::UNO_QUERY);
-        xPropxStartSp->getPropertyValue("LineWidth") >>= nStartSpLineW;
-        if (nStartSpLineW)
-            nStartSpLineW = nStartSpLineW / 2;
+        aS = pStartObj->GetSnapRect();
         nStartA = lcl_GetAngle(xStartSp, aStartPt);
     }
-    sal_Int32 nEndSpLineW = 0;
     if (pEndObj)
     {
-        aEndRect = pEndObj->GetSnapRect();
-        uno::Reference<beans::XPropertySet> xPropxEndSp(xEndSp, 
uno::UNO_QUERY);
-        xPropxEndSp->getPropertyValue("LineWidth") >>= nEndSpLineW;
-        if (nEndSpLineW)
-            nEndSpLineW = nEndSpLineW / 2;
+        aE = pEndObj->GetSnapRect();
         nEndA = lcl_GetAngle(xEndSp, aEndPt);
     }
 
-    const OUString sConnectorName = rShapePtr->getConnectorName();
-    if (sConnectorName == "bentConnector2")
+    // bentConnector3, bentConnector4, bentConnector5
+    if (!rShapePtr->getConnectorAdjustments().empty())
     {
-        awt::Size aConnSize = rXConnector->getSize();
-        if (xStartSp.is() || xEndSp.is())
+        sal_Int32 nAdjustValue = 0;
+        for (size_t i = 0; i < rShapePtr->getConnectorAdjustments().size(); 
i++)
         {
-            if (nStartA >= 0)
+            bool bVertical = false;
+            if (xStartSp.is() || xEndSp.is())
+                bVertical = xStartSp.is() ? ((nStartA == 90 || nStartA == 270) 
? true : false)
+                                          : ((nEndA == 90 || nEndA == 270) ? 
true : false);
+            else
+            {
+                sal_Int32 nAng = rShapePtr->getRotation() / 60000;
+                bVertical = (nAng == 90 || nAng == 270) ? true : false;
+            }
+
+            if (i % 2 == 1)
+                bVertical = !bVertical;
+
+            nAdjustValue = rShapePtr->getConnectorAdjustments()[i].toInt32();
+            if (bVertical)
+            {
+                sal_Int32 nY = aStartPt.Y + ((nAdjustValue * (aEndPt.Y - 
aStartPt.Y)) / 100000);
+                if (xStartSp.is() && xEndSp.is())
+                {
+                    if (aS.Top() <= aE.Top())
+                    {
+                        if (nStartA == 270 && i != 2)
+                            nEdge = nY - aS.Top();
+                        else
+                        {
+                            if (aS.Bottom() < aE.Top() && nEndA != 90)
+                            {
+                                nEdge = nY - (aS.Bottom() + ((aE.Top() - 
aS.Bottom()) / 2));
+                            }
+                            else
+                                nEdge = nY - aE.Bottom();
+                        }
+                    }
+                    else
+                    {
+                        if (nStartA == 90 && i != 2)
+                            nEdge = nY - aS.Bottom();
+                        else
+                        {
+                            if (aE.Bottom() < aS.Top() && nEndA != 270)
+                                nEdge = nY - (aS.Top() + ((aE.Bottom() - 
aS.Top()) / 2));
+                            else
+                                nEdge = nY - aE.Top();
+                        }
+                    }
+                }
+                else if ((xStartSp.is() && !xEndSp.is()) || (!xStartSp.is() && 
xEndSp.is()))
+                {
+                    if (aStartPt.Y < aEndPt.Y)
+                    {
+                        if (xStartSp.is())
+                            nEdge = (nStartA == 90)
+                                        ? nY - (aEndPt.Y - ((aEndPt.Y - 
aS.Bottom()) / 2))
+                                        : nY - aS.Top();
+                        else
+                            nEdge = (nEndA == 90)
+                                        ? nY - aE.Bottom()
+                                        : nY - (aStartPt.Y + ((aE.Top() - 
aStartPt.Y) / 2));
+                    }
+                    else
+                    {
+                        if (xStartSp.is())
+                            nEdge = (nStartA == 90) ? nY - aS.Bottom()
+                                                    : nY - (aEndPt.Y + 
((aS.Top() - aEndPt.Y) / 2));
+                        else
+                            nEdge = (nEndA == 90)
+                                        ? nY - (aStartPt.Y - ((aStartPt.Y - 
aE.Bottom()) / 2))
+                                        : nY - aE.Top();
+                    }
+                }
+                else
+                {
+                    nEdge = (aStartPt.Y < aEndPt.Y)
+                                ? nY - (aStartPt.Y + 
(rXConnector->getSize().Height / 2))
+                                : nY - (aStartPt.Y - 
(rXConnector->getSize().Height / 2));
+                }
+            }
+            else // Horizontal
             {
-                switch (nStartA)
+                sal_Int32 nX = aStartPt.X + ((nAdjustValue * (aEndPt.X - 
aStartPt.X)) / 100000);
+                if (xStartSp.is() && xEndSp.is())
+                {
+                    if (aS.Left() <= aE.Left())
+                    {
+                        if (nStartA == 180 && i != 2)
+                            nEdge = nX - aS.Left();
+                        else
+                        {
+                            if (aS.Right() < aE.Left() && nEndA != 0)
+                                nEdge = nX - (aS.Right() + ((aE.Left() - 
aS.Right()) / 2));
+                            else
+                                nEdge = nX - aE.Right();
+                        }
+                    }
+                    else
+                    {
+                        if (nStartA == 0 && i != 2)
+                            nEdge = nX - aS.Right();
+                        else
+                        {
+                            if (aE.Right() < aS.Left() && nEndA != 180)
+                                nEdge = nX - (aS.Left() + ((aE.Right() - 
aS.Left()) / 2));
+                            else
+                                nEdge = nX - aE.Left();
+                        }
+                    }
+                }
+                else if ((xStartSp.is() && !xEndSp.is()) || (!xStartSp.is() && 
xEndSp.is()))
                 {
-                    case 0:     nEdge = aEndPt.X - aStartRect.Right();  break;
-                    case 180:   nEdge = aEndPt.X - aStartRect.Left();   break;
-                    case 90:    nEdge = aEndPt.Y - aStartRect.Bottom(); break;
-                    case 270:   nEdge = aEndPt.Y - aStartRect.Top();    break;
+                    if (aStartPt.X < aEndPt.X)
+                    {
+                        if (xStartSp.is())
+                            nEdge = (nStartA == 0)
+                                        ? nX - (aS.Right() + ((aEndPt.X - 
aS.Right()) / 2))
+                                        : nX - aS.Left();
+                        else
+                            nEdge = (nEndA == 0)
+                                        ? nX - aE.Right()
+                                        : nX - (aStartPt.X + ((aE.Left() - 
aStartPt.X) / 2));
+                    }
+                    else
+                    {
+                        if (xStartSp.is())
+                            nEdge = (nStartA == 0) ? nX - aS.Right()
+                                                   : nX - (aEndPt.X + 
((aS.Left() - aEndPt.X) / 2));
+                        else
+                            nEdge = (nEndA == 0)
+                                        ? nX - (aE.Right() + ((aStartPt.X - 
aE.Right()) / 2))
+                                        : nX - aE.Left();
+                    }
                 }
-                nEdge += nStartSpLineW * (nStartA >= 180 ? +1 : -1);
-            } else {
-                switch (nEndA)
+                else
                 {
-                    case 0:     nEdge = aStartPt.X - aEndRect.Right();  break;
-                    case 180:   nEdge = aStartPt.X - aEndRect.Left();   break;
-                    case 90:    nEdge = aStartPt.Y - aEndRect.Bottom(); break;
-                    case 270:   nEdge = aStartPt.Y - aEndRect.Top();    break;
+                    nEdge = (aStartPt.X < aEndPt.X)
+                                ? nX - (aStartPt.X + 
(rXConnector->getSize().Width / 2))
+                                : nX - (aStartPt.X - 
(rXConnector->getSize().Width / 2));
                 }
-                nEdge += nEndSpLineW * (nEndA >= 180 ? +1 : -1);
             }
+            xPropSet->setPropertyValue("EdgeLine" + OUString::number(i + 1) + 
"Delta", Any(nEdge));
         }
-        else
+    }
+    else
+    {
+        const OUString sConnectorName = rShapePtr->getConnectorName();
+        if (sConnectorName == "bentConnector2")
         {
-            bool bFlipH = rShapePtr->getFlipH();
-            bool bFlipV = rShapePtr->getFlipV();
-            sal_Int32 nConnectorAngle = rShapePtr->getRotation() / 60000;
-            if (aConnSize.Height < aConnSize.Width)
+            awt::Size aConnSize = rXConnector->getSize();
+            if (xStartSp.is() || xEndSp.is())
             {
-                if ((nConnectorAngle == 90 && bFlipH && bFlipV) || 
(nConnectorAngle == 180)
-                    || (nConnectorAngle == 270 && bFlipH))
-                    nEdge -= aConnSize.Width;
-                else
-                    nEdge += aConnSize.Width;
+                if (nStartA >= 0)
+                {
+                    switch (nStartA)
+                    {
+                    case 0:     nEdge = aEndPt.X - aS.Right();  break;
+                    case 180:   nEdge = aEndPt.X - aS.Left();   break;
+                    case 90:    nEdge = aEndPt.Y - aS.Bottom(); break;
+                    case 270:   nEdge = aEndPt.Y - aS.Top();    break;
+                    }
+                } else {
+                    switch (nEndA)
+                    {
+                    case 0:     nEdge = aStartPt.X - aE.Right();  break;
+                    case 180:   nEdge = aStartPt.X - aE.Left();   break;
+                    case 90:    nEdge = aStartPt.Y - aE.Bottom(); break;
+                    case 270:   nEdge = aStartPt.Y - aE.Top();    break;
+                    }
+                }
             }
             else
             {
-                if ((nConnectorAngle == 180 && bFlipV) || (nConnectorAngle == 
270 && bFlipV)
-                    || (nConnectorAngle == 90 && bFlipH && bFlipV)
-                    || (nConnectorAngle == 0 && !bFlipV))
-                    nEdge -= aConnSize.Height;
+                bool bFlipH = rShapePtr->getFlipH();
+                bool bFlipV = rShapePtr->getFlipV();
+                sal_Int32 nConnectorAngle = rShapePtr->getRotation() / 60000;
+                if (aConnSize.Height < aConnSize.Width)
+                {
+                    if ((nConnectorAngle == 90 && bFlipH && bFlipV) || 
(nConnectorAngle == 180)
+                        || (nConnectorAngle == 270 && bFlipH))
+                        nEdge -= aConnSize.Width;
+                    else
+                        nEdge += aConnSize.Width;
+                }
                 else
-                    nEdge += aConnSize.Height;
+                {
+                    if ((nConnectorAngle == 180 && bFlipV) || (nConnectorAngle 
== 270 && bFlipV)
+                        || (nConnectorAngle == 90 && bFlipH && bFlipV)
+                        || (nConnectorAngle == 0 && !bFlipV))
+                        nEdge -= aConnSize.Height;
+                    else
+                        nEdge += aConnSize.Height;
+                }
             }
+            xPropSet->setPropertyValue("EdgeLine1Delta", Any(nEdge / 2));
         }
-        xPropSet->setPropertyValue("EdgeLine1Delta", Any(nEdge / 2));
     }
 }
 
diff --git a/sd/qa/unit/data/pptx/standardConnectors.pptx 
b/sd/qa/unit/data/pptx/standardConnectors.pptx
new file mode 100644
index 000000000000..46bb0735f40f
Binary files /dev/null and b/sd/qa/unit/data/pptx/standardConnectors.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 07c105fc1b0a..3ab567c43877 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -84,6 +84,7 @@ public:
 
     void testDocumentLayout();
     void testTdf152434();
+    void testStandardConnectors();
     void testConnectors();
     void testTdf153036_resizedConnectorL();
     void testTdf150719();
@@ -161,6 +162,7 @@ public:
 
     CPPUNIT_TEST(testDocumentLayout);
     CPPUNIT_TEST(testTdf152434);
+    CPPUNIT_TEST(testStandardConnectors);
     CPPUNIT_TEST(testConnectors);
     CPPUNIT_TEST(testTdf153036_resizedConnectorL);
     CPPUNIT_TEST(testTdf150719);
@@ -355,12 +357,40 @@ void SdImportTest::testTdf152434()
     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
 }
 
+void SdImportTest::testStandardConnectors()
+{
+    createSdImpressDoc("pptx/standardConnectors.pptx");
+
+    sal_Int32 aEdgeValue[] = { -1352, -2457, 3977, -2900, -1261, 4611, -1431, 
-2643, 3830, 3438 };
+
+    sal_Int32 nCount = 0;
+    sal_Int32 nEdgeLine = 0;
+    for (size_t i = 0; i < 10; i++)
+    {
+        uno::Reference<beans::XPropertySet> xConnector(getShapeFromPage(i, 0));
+        bool bConnector = 
xConnector->getPropertySetInfo()->hasPropertyByName("EdgeKind");
+        if (bConnector)
+        {
+            nEdgeLine = 
xConnector->getPropertyValue("EdgeLine1Delta").get<sal_Int32>();
+            CPPUNIT_ASSERT_EQUAL(aEdgeValue[nCount], nEdgeLine);
+            nCount++;
+
+            nEdgeLine = 
xConnector->getPropertyValue("EdgeLine2Delta").get<sal_Int32>();
+            if (nEdgeLine != 0)
+            {
+                CPPUNIT_ASSERT_EQUAL(aEdgeValue[nCount], nEdgeLine);
+                nCount++;
+            }
+        }
+    }
+}
+
 void SdImportTest::testConnectors()
 {
     createSdImpressDoc("pptx/connectors.pptx");
 
-    sal_Int32 aEdgeValue[] = { -1123, -1123, -1547, 1432,  1356, -1357, 1604,  
-1540,
-                               599,   1288,  -1629, -1052, -513, 1569,  -1283, 
333 };
+    sal_Int32 aEdgeValue[] = { -1167, -1167, -1591, 1476,  1356, -1357, 1604,  
-1540,
+                               607,   1296,  -1638, -1060, -522, 1578,  -1291, 
333 };
 
     sal_Int32 nCount = 0;
     for (size_t i = 0; i < 18; i++)
diff --git a/sd/source/ui/docshell/docshel4.cxx 
b/sd/source/ui/docshell/docshel4.cxx
index 0bdfef02b7db..afe322d7a959 100644
--- a/sd/source/ui/docshell/docshel4.cxx
+++ b/sd/source/ui/docshell/docshel4.cxx
@@ -402,6 +402,14 @@ bool DrawDocShell::ImportFrom(SfxMedium &rMedium,
         mpDoc->SetSummationOfParagraphs();
     }
 
+    if (aFilterName == "Impress MS PowerPoint 2007 XML")
+    {
+        // This is a "MS Compact" mode for connectors.
+        // The Libreoffice uses bounding rectangle of connected shapes but
+        // MSO uses snap rectangle when calculate the edge track.
+        mpDoc->SetConnectorUseSnapRect(true);
+    }
+
     if (aFilterName == "Impress MS PowerPoint 2007 XML" ||
         aFilterName == "Impress MS PowerPoint 2007 XML AutoPlay" ||
         aFilterName == "Impress MS PowerPoint 2007 XML VBA" ||
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index bc86671c9437..5a79b8c16f6e 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -84,6 +84,7 @@ struct SdrModelImpl
     SdrUndoFactory* mpUndoFactory;
     bool mbAnchoredTextOverflowLegacy; // tdf#99729 compatibility flag
     bool mbLegacySingleLineFontwork;   // tdf#148000 compatibility flag
+    bool mbConnectorUseSnapRect;       // tdf#149756 compatibility flag
     std::unique_ptr<svx::Theme> mpTheme;
 
     SdrModelImpl()
@@ -91,6 +92,7 @@ struct SdrModelImpl
         , mpUndoFactory(nullptr)
         , mbAnchoredTextOverflowLegacy(false)
         , mbLegacySingleLineFontwork(false)
+        , mbConnectorUseSnapRect(false)
     {}
 };
 
@@ -1733,6 +1735,16 @@ bool SdrModel::IsLegacySingleLineFontwork() const
     return mpImpl->mbLegacySingleLineFontwork;
 }
 
+void SdrModel::SetConnectorUseSnapRect(bool bEnabled)
+{
+    mpImpl->mbConnectorUseSnapRect = bEnabled;
+}
+
+bool SdrModel::IsConnectorUseSnapRect() const
+{
+    return mpImpl->mbConnectorUseSnapRect;
+}
+
 void SdrModel::ReformatAllTextObjects()
 {
     ImpReformatAllTextObjects();
@@ -1776,6 +1788,14 @@ void SdrModel::ReadUserDataSequenceValue(const 
beans::PropertyValue* pValue)
             mpImpl->mbAnchoredTextOverflowLegacy = bBool;
         }
     }
+    else if (pValue->Name == "ConnectorUseSnapRect")
+    {
+        bool bBool = false;
+        if (pValue->Value >>= bBool)
+        {
+            mpImpl->mbConnectorUseSnapRect = bBool;
+        }
+    }
     else if (pValue->Name == "LegacySingleLineFontwork")
     {
         bool bBool = false;
@@ -1815,6 +1835,7 @@ void SdrModel::WriteUserDataSequence(uno::Sequence 
<beans::PropertyValue>& rValu
     std::vector< std::pair< OUString, uno::Any > > aUserData;
     addPair(aUserData, "AnchoredTextOverflowLegacy", 
IsAnchoredTextOverflowLegacy());
     addPair(aUserData, "LegacySingleLineFontwork", 
IsLegacySingleLineFontwork());
+    addPair(aUserData, "ConnectorUseSnapRect", IsConnectorUseSnapRect());
 
     const sal_Int32 nOldLength = rValues.getLength();
     rValues.realloc(nOldLength + aUserData.size());
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index f84ee128a6e0..15d507679789 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -753,7 +753,10 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& 
rTrack0, SdrObjConnection&
         }
         else
         {
-            aBoundRect1 = rCon1.pObj->GetCurrentBoundRect();
+            if (getSdrModelFromSdrObject().IsConnectorUseSnapRect())
+                aBoundRect1 = rCon1.pObj->GetSnapRect();
+            else
+                aBoundRect1 = rCon1.pObj->GetCurrentBoundRect();
         }
 
         aBoundRect1.Move(rCon1.aObjOfs.X(),rCon1.aObjOfs.Y());
@@ -780,7 +783,10 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& 
rTrack0, SdrObjConnection&
         }
         else
         {
-            aBoundRect2 = rCon2.pObj->GetCurrentBoundRect();
+            if (getSdrModelFromSdrObject().IsConnectorUseSnapRect())
+                aBoundRect2 = rCon2.pObj->GetSnapRect();
+            else
+                aBoundRect2 = rCon2.pObj->GetCurrentBoundRect();
         }
 
         aBoundRect2.Move(rCon2.aObjOfs.X(),rCon2.aObjOfs.Y());

Reply via email to