diff options
author | Tibor Nagy <nagy.tibor2@nisz.hu> | 2023-01-26 09:17:56 +0100 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-03-08 19:17:11 +0000 |
commit | 5308d68a7cc0a4b38216438150adba2ac62e2bbe (patch) | |
tree | d19fa457f17fbb0ecb792c2b7557dc161178e450 | |
parent | 1c7b700179afda772af0f004e7ba497ba42fd8fc (diff) |
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 <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148480
Tested-by: Jenkins
-rw-r--r-- | include/oox/drawingml/shape.hxx | 3 | ||||
-rw-r--r-- | include/svx/svdmodel.hxx | 4 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 4 | ||||
-rw-r--r-- | oox/source/ppt/slidepersist.cxx | 232 | ||||
-rw-r--r-- | sd/qa/unit/data/pptx/standardConnectors.pptx | bin | 0 -> 36923 bytes | |||
-rw-r--r-- | sd/qa/unit/import-tests.cxx | 34 | ||||
-rw-r--r-- | sd/source/ui/docshell/docshel4.cxx | 8 | ||||
-rw-r--r-- | svx/source/svdraw/svdmodel.cxx | 21 | ||||
-rw-r--r-- | svx/source/svdraw/svdoedge.cxx | 10 |
9 files changed, 265 insertions, 51 deletions
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 Binary files differnew file mode 100644 index 000000000000..46bb0735f40f --- /dev/null +++ b/sd/qa/unit/data/pptx/standardConnectors.pptx 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()); |