include/oox/drawingml/shape.hxx      |    4 ++
 oox/source/drawingml/shape.cxx       |    7 +++
 oox/source/ppt/slidepersist.cxx      |   69 +++++++++++++++++++++++++++++++++++
 sd/qa/unit/data/pptx/connectors.pptx |binary
 sd/qa/unit/import-tests.cxx          |   18 +++++++++
 5 files changed, 98 insertions(+)

New commits:
commit 66806942e246b5aa72677807e1a290e4bbf6bcea
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Mon Oct 24 09:36:54 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Nov 2 11:14:00 2022 +0100

    tdf#148926 tdf#151678 PPTX import: position of standard connector - part1
    
    Connectors are typically connected to connection dots,
    which exist on shapes. If both or one of the two shapes
    are missing, it will be drawn the default type of a
    standard connector in LO. In this case, there is an
    adjustment point which is used to modify positions and
    shapes of the connectors. This patch fixes the position of
    the connector by calculating and setting the adjustment
    value.
    
    Change-Id: Iee384d2a92a22ff95d7b17ba0b4f09698176bc84
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141723
    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/+/142159
    Tested-by: Jenkins

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 5f4173c9de87..5c4f788cde2e 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -136,6 +136,7 @@ public:
 
     CustomShapePropertiesPtr&       getCustomShapeProperties(){ return 
mpCustomShapePropertiesPtr; }
 
+    OUString&                       getConnectorName() { return 
msConnectorName; }
     ConnectorShapePropertiesList&   getConnectorShapeProperties() { return 
maConnectorShapePropertiesList; }
     void                            setConnectorShape(bool bConnector) { 
mbConnector = bConnector; }
     bool                            isConnectorShape() const { return 
mbConnector; }
@@ -163,6 +164,8 @@ public:
     sal_Int32                       getRotation() const { return mnRotation; }
     void                            setDiagramRotation( sal_Int32 nRotation ) 
{ mnDiagramRotation = nRotation; }
     void                            setFlip( bool bFlipH, bool bFlipV ) { 
mbFlipH = bFlipH; mbFlipV = bFlipV; }
+    bool                            getFlipH() const { return mbFlipH; }
+    bool                            getFlipV() const { return mbFlipV; }
     void                            addChild( const ShapePtr& rChildPtr ) { 
maChildren.push_back( rChildPtr ); }
     std::vector< ShapePtr >&        getChildren() { return maChildren; }
 
@@ -347,6 +350,7 @@ protected:
     css::uno::Reference< css::drawing::XShape > mxShape;
     ConnectorShapePropertiesList maConnectorShapePropertiesList;
 
+    OUString                    msConnectorName;
     OUString                    msServiceName;
     OUString                    msName;
     OUString                    msInternalName; // used by diagram; not 
displayed in UI
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 12b3303054e4..1dd4eb319c26 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1678,6 +1678,13 @@ Reference< XShape > const & Shape::createAndInsert(
 
         if (bIsConnectorShape)
         {
+            OUString sConnectorShapePresetTypeName(
+                reinterpret_cast<const char*>(
+                    
mpCustomShapePropertiesPtr->getShapePresetTypeName().getConstArray()),
+                
mpCustomShapePropertiesPtr->getShapePresetTypeName().getLength(),
+                RTL_TEXTENCODING_UTF8);
+            msConnectorName = sConnectorShapePresetTypeName;
+
             sal_Int32 nType = mpCustomShapePropertiesPtr->getShapePresetType();
             switch (nType)
             {
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
index 8d45bcdb7947..137a9c437a4b 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -44,6 +44,7 @@
 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
 #include <com/sun/star/container/XIdentifierContainer.hpp>
 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
 
 using namespace ::com::sun::star;
 using namespace ::oox::core;
@@ -350,6 +351,70 @@ Reference<XAnimationNode> 
SlidePersist::getAnimationNode(const OUString& sId) co
     return aResult;
 }
 
+static void lcl_SetEdgeLineValue(uno::Reference<drawing::XShape>& rXConnector,
+                                 oox::drawingml::ShapePtr& rShapePtr)
+{
+    sal_Int32 nEdge = 0;
+    awt::Point aStartPt, aEndPt;
+    uno::Reference<drawing::XShape> xStartSp, xEndSp;
+    uno::Reference<beans::XPropertySet> xPropSet(rXConnector, uno::UNO_QUERY);
+    xPropSet->getPropertyValue("EdgeStartPoint") >>= aStartPt;
+    xPropSet->getPropertyValue("EdgeEndPoint") >>= aEndPt;
+    xPropSet->getPropertyValue("StartShape") >>= xStartSp;
+    xPropSet->getPropertyValue("EndShape") >>= xEndSp;
+    xPropSet->setPropertyValue("EdgeNode1HorzDist", Any(sal_Int32(0)));
+    xPropSet->setPropertyValue("EdgeNode1VertDist", Any(sal_Int32(0)));
+    xPropSet->setPropertyValue("EdgeNode2HorzDist", Any(sal_Int32(0)));
+    xPropSet->setPropertyValue("EdgeNode2VertDist", Any(sal_Int32(0)));
+
+    const OUString sConnectorName = rShapePtr->getConnectorName();
+    if (sConnectorName == "bentConnector2")
+    {
+        awt::Size aConnSize = rXConnector->getSize();
+        if (xStartSp.is() || xEndSp.is())
+        {
+            if (aConnSize.Height < aConnSize.Width)
+            {
+                if (xStartSp.is())
+                    nEdge = (aStartPt.Y > aEndPt.Y) ? -aConnSize.Height : 
aConnSize.Height;
+                else
+                    nEdge = (aStartPt.Y > aEndPt.Y) ? aConnSize.Height : 
-aConnSize.Height;
+            }
+            else
+            {
+                if (xStartSp.is())
+                    nEdge = (aStartPt.X > aEndPt.X) ? -aConnSize.Width : 
aConnSize.Width;
+                else
+                    nEdge = (aStartPt.X > aEndPt.X) ? aConnSize.Width : 
-aConnSize.Width;
+            }
+        }
+        else
+        {
+            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 == 180 && bFlipV) || (nConnectorAngle 
== 270 && bFlipH))
+                    nEdge -= aConnSize.Width;
+                else
+                    nEdge += aConnSize.Width;
+            }
+            else
+            {
+                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));
+    }
+}
+
 // create connection between two shape with a connector shape.
 void SlidePersist::createConnectorShapeConnection()
 {
@@ -408,6 +473,10 @@ void SlidePersist::createConnectorShapeConnection()
                     }
                 }
             }
+            ConnectorType aConnectorType;
+            xPropertySet->getPropertyValue("EdgeKind") >>= aConnectorType;
+            if (aConnectorType == ConnectorType_STANDARD)
+                lcl_SetEdgeLineValue(xConnector, pIt->second);
         }
     }
     maConnectorShapeId.clear();
diff --git a/sd/qa/unit/data/pptx/connectors.pptx 
b/sd/qa/unit/data/pptx/connectors.pptx
new file mode 100644
index 000000000000..fa03ef0f6046
Binary files /dev/null and b/sd/qa/unit/data/pptx/connectors.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 68161536da93..87d282a8a8f9 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -61,6 +61,7 @@
 #include <comphelper/lok.hxx>
 #include <svx/svdograf.hxx>
 #include <vcl/filter/PDFiumLibrary.hxx>
+#include <filter/msfilter/escherex.hxx>
 
 using namespace ::com::sun::star;
 
@@ -83,6 +84,7 @@ public:
     virtual void setUp() override;
 
     void testDocumentLayout();
+    void testConnectors();
     void testTdf149314();
     void testTdf149124();
     void testTdf148965();
@@ -154,6 +156,7 @@ public:
     CPPUNIT_TEST_SUITE(SdImportTest);
 
     CPPUNIT_TEST(testDocumentLayout);
+    CPPUNIT_TEST(testConnectors);
     CPPUNIT_TEST(testTdf149314);
     CPPUNIT_TEST(testTdf149124);
     CPPUNIT_TEST(testTdf148965);
@@ -303,6 +306,21 @@ void SdImportTest::testDocumentLayout()
     }
 }
 
+void SdImportTest::testConnectors()
+{
+    ::sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/connectors.pptx"), 
PPTX);
+
+    sal_Int32 aEdgeValue[] = { -1167, -1167, -1591, 1476, 1357, -1357, 1604, 
-1540 };
+    for (size_t i = 1; i < 9; i++)
+    {
+        uno::Reference<beans::XPropertySet> xConnector(getShapeFromPage(i, 0, 
xDocShRef));
+        sal_Int32 nEdgeLine = 
xConnector->getPropertyValue("EdgeLine1Delta").get<sal_Int32>();
+        CPPUNIT_ASSERT_EQUAL(aEdgeValue[i-1], nEdgeLine);
+    }
+    xDocShRef->DoClose();
+}
+
 void SdImportTest::testTdf149314()
 {
     sd::DrawDocShellRef xDocShRef

Reply via email to