summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorTibor Nagy <nagy.tibor2@nisz.hu>2022-03-10 08:42:12 +0100
committerLászló Németh <nemeth@numbertext.org>2022-03-29 16:12:45 +0200
commitcbf66ec3e60d07efb7c3cceed9b4f0fb4f0510c8 (patch)
treec7e02c1e50525e42d7b15d000398631be3c7c697 /oox
parentbc601af632861896bdfaa14c96daf1a7ffdfcf71 (diff)
tdf#89449 PPTX import: fix line connectors
Line connectors were imported as plain shapes, losing their functionality during editing, i.e. keeping connections of boxes and other shapes. Change-Id: I0f1562be2dbcce0e45eb209c6ca4e035731039e1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131303 Tested-by: László Németh <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'oox')
-rw-r--r--oox/inc/drawingml/customshapeproperties.hxx1
-rw-r--r--oox/source/drawingml/chart/chartdrawingfragment.cxx3
-rw-r--r--oox/source/drawingml/connectorshapecontext.cxx84
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx36
-rw-r--r--oox/source/drawingml/shape.cxx37
-rw-r--r--oox/source/drawingml/shapegroupcontext.cxx3
-rw-r--r--oox/source/drawingml/shapepropertiescontext.cxx8
-rw-r--r--oox/source/export/shapes.cxx3
-rw-r--r--oox/source/ppt/pptshapegroupcontext.cxx6
-rw-r--r--oox/source/ppt/slidepersist.cxx70
-rw-r--r--oox/source/shape/LockedCanvasContext.cxx7
11 files changed, 194 insertions, 64 deletions
diff --git a/oox/inc/drawingml/customshapeproperties.hxx b/oox/inc/drawingml/customshapeproperties.hxx
index 779003412fbb..ea9b9e9d53af 100644
--- a/oox/inc/drawingml/customshapeproperties.hxx
+++ b/oox/inc/drawingml/customshapeproperties.hxx
@@ -98,7 +98,6 @@ public:
CustomShapeProperties();
void pushToPropSet( const css::uno::Reference < css::beans::XPropertySet > & xPropSet,
- const css::uno::Reference < css::drawing::XShape > & xShape,
const css::awt::Size &aSize );
sal_Int32 getShapePresetType() const { return mnShapePresetType; }
diff --git a/oox/source/drawingml/chart/chartdrawingfragment.cxx b/oox/source/drawingml/chart/chartdrawingfragment.cxx
index c41e2db49821..9509ad4ea01e 100644
--- a/oox/source/drawingml/chart/chartdrawingfragment.cxx
+++ b/oox/source/drawingml/chart/chartdrawingfragment.cxx
@@ -157,7 +157,8 @@ ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, con
return new ShapeContext( *this, ShapePtr(), mxShape );
case CDR_TOKEN( cxnSp ):
mxShape = std::make_shared<Shape>( "com.sun.star.drawing.ConnectorShape" );
- return new ConnectorShapeContext( *this, ShapePtr(), mxShape );
+ return new ConnectorShapeContext(*this, ShapePtr(), mxShape,
+ mxShape->getConnectorShapeProperties());
case CDR_TOKEN( pic ):
mxShape = std::make_shared<Shape>( "com.sun.star.drawing.GraphicObjectShape" );
return new GraphicShapeContext( *this, ShapePtr(), mxShape );
diff --git a/oox/source/drawingml/connectorshapecontext.cxx b/oox/source/drawingml/connectorshapecontext.cxx
index e815d56994d9..b1ea90c357af 100644
--- a/oox/source/drawingml/connectorshapecontext.cxx
+++ b/oox/source/drawingml/connectorshapecontext.cxx
@@ -22,6 +22,7 @@
#include <oox/drawingml/connectorshapecontext.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
+#include <oox/drawingml/shape.hxx>
#include <oox/helper/attributelist.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
@@ -35,30 +36,93 @@ using namespace ::com::sun::star::xml::sax;
namespace oox::drawingml {
-ConnectorShapeContext::ConnectorShapeContext( ContextHandler2Helper const & rParent,
- const ShapePtr& pMasterShapePtr, const ShapePtr& pGroupShapePtr )
-: ShapeContext( rParent, pMasterShapePtr, pGroupShapePtr )
+namespace
{
+class ConnectorShapePropertiesContext : public ::oox::core::ContextHandler2
+{
+ std::vector<ConnectorShapeProperties>& mrConnectorShapePropertiesList;
+ ShapePtr mpConnectorShapePtr;
+
+public:
+ ConnectorShapePropertiesContext(
+ ::oox::core::ContextHandler2Helper const& rParent, ShapePtr& pShapePtr,
+ std::vector<ConnectorShapeProperties>& rConnectorShapePropertiesList);
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 aElementToken,
+ const AttributeList& rAttribs) override;
+};
}
-ConnectorShapeContext::~ConnectorShapeContext()
+ConnectorShapePropertiesContext::ConnectorShapePropertiesContext(
+ ContextHandler2Helper const& rParent, ShapePtr& pShapePtr,
+ std::vector<ConnectorShapeProperties>& rConnectorShapePropertiesList)
+ : ContextHandler2(rParent)
+ , mrConnectorShapePropertiesList(rConnectorShapePropertiesList)
+ , mpConnectorShapePtr(pShapePtr)
{
+ mpConnectorShapePtr->setConnectorShape(true);
}
-ContextHandlerRef ConnectorShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+::oox::core::ContextHandlerRef
+ConnectorShapePropertiesContext::onCreateContext(sal_Int32 aElementToken,
+ const AttributeList& rAttribs)
{
- switch( getBaseToken( aElementToken ) )
+ switch (getBaseToken(aElementToken))
{
- case XML_nvCxnSpPr :
- break;
-
+ case XML_cNvPr:
+ mpConnectorShapePtr->setId(rAttribs.getString(XML_id).get());
+ mpConnectorShapePtr->setName(rAttribs.getString(XML_name).get());
+ break;
+ case XML_stCxn:
+ {
+ ConnectorShapeProperties aConnectorShapeProps;
+ aConnectorShapeProps.mbStartShape = true;
+ aConnectorShapeProps.maDestShapeId = rAttribs.getString(XML_id).get();
+ aConnectorShapeProps.mnDestGlueId = rAttribs.getInteger(XML_idx).get();
+ mrConnectorShapePropertiesList.push_back(aConnectorShapeProps);
+ break;
+ }
+ case XML_endCxn:
+ {
+ ConnectorShapeProperties aConnectorShapeProps;
+ aConnectorShapeProps.mbStartShape = false;
+ aConnectorShapeProps.maDestShapeId = rAttribs.getString(XML_id).get();
+ aConnectorShapeProps.mnDestGlueId = rAttribs.getInteger(XML_idx).get();
+ mrConnectorShapePropertiesList.push_back(aConnectorShapeProps);
+ break;
+ }
default:
- return ShapeContext::onCreateContext( aElementToken, rAttribs );
+ break;
}
return this;
}
+ConnectorShapeContext::ConnectorShapeContext(
+ ContextHandler2Helper const& rParent, const ShapePtr& pMasterShapePtr,
+ const ShapePtr& pGroupShapePtr,
+ std::vector<ConnectorShapeProperties>& rConnectorShapePropertiesList)
+ : ShapeContext(rParent, pMasterShapePtr, pGroupShapePtr)
+ , mrConnectorShapePropertiesList(rConnectorShapePropertiesList)
+ , mpConnectorShapePtr(pGroupShapePtr)
+{
+}
+
+ConnectorShapeContext::~ConnectorShapeContext() {}
+
+ContextHandlerRef ConnectorShapeContext::onCreateContext(sal_Int32 aElementToken,
+ const AttributeList& rAttribs)
+{
+ switch (getBaseToken(aElementToken))
+ {
+ case XML_nvCxnSpPr:
+ return new ConnectorShapePropertiesContext(*this, mpConnectorShapePtr,
+ mrConnectorShapePropertiesList);
+ }
+
+ return ShapeContext::onCreateContext(aElementToken, rAttribs);
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx
index efe7c0ad03af..b748deb48702 100644
--- a/oox/source/drawingml/customshapeproperties.cxx
+++ b/oox/source/drawingml/customshapeproperties.cxx
@@ -97,25 +97,8 @@ bool CustomShapeProperties::representsDefaultShape() const
CustomShapeProperties::PresetDataMap CustomShapeProperties::maPresetDataMap;
-static OUString GetConnectorShapeType( sal_Int32 nType )
-{
- SAL_INFO(
- "oox.drawingml", "preset: " << nType << " " << XML_straightConnector1);
-
- OUString sType;
- switch( nType )
- {
- case XML_straightConnector1:
- sType = "mso-spt32";
- break;
- default:
- break;
- }
- return sType;
-}
-
void CustomShapeProperties::pushToPropSet(
- const Reference < XPropertySet >& xPropSet, const Reference < XShape > & xShape, const awt::Size &aSize )
+ const Reference < XPropertySet >& xPropSet, const awt::Size &aSize )
{
if ( mnShapePresetType >= 0 )
{
@@ -127,22 +110,7 @@ void CustomShapeProperties::pushToPropSet(
PropertyMap aPropertyMap;
PropertySet aPropSet( xPropSet );
- OUString sConnectorShapeType = GetConnectorShapeType( mnShapePresetType );
-
- if (sConnectorShapeType.getLength() > 0)
- {
- SAL_INFO(
- "oox.drawingml",
- "connector shape: " << sConnectorShapeType << " ("
- << mnShapePresetType << ")");
- //const uno::Reference < drawing::XShape > xShape( xPropSet, UNO_QUERY );
- Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY );
- if( xDefaulter.is() ) {
- xDefaulter->createCustomShapeDefaults( sConnectorShapeType );
- aPropertyMap.setProperty( PROP_Type, sConnectorShapeType );
- }
- }
- else if (maPresetDataMap.find(mnShapePresetType) != maPresetDataMap.end())
+ if (maPresetDataMap.find(mnShapePresetType) != maPresetDataMap.end())
{
SAL_INFO(
"oox.drawingml",
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index cc988699292e..2ef801c5ee08 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -78,6 +78,7 @@
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
@@ -867,10 +868,8 @@ Reference< XShape > const & Shape::createAndInsert(
bool bIsCroppedGraphic = (aServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
!mpCustomShapePropertiesPtr->representsDefaultShape());
- // ToDo: Why is ConnectorShape here treated as custom shape, but below with start and end point?
- bool bIsCustomShape = ( aServiceName == "com.sun.star.drawing.CustomShape" ||
- aServiceName == "com.sun.star.drawing.ConnectorShape" ||
- bIsCroppedGraphic);
+ bool bIsCustomShape = (aServiceName == "com.sun.star.drawing.CustomShape" || bIsCroppedGraphic);
+ bool bIsConnectorShape = (aServiceName == "com.sun.star.drawing.ConnectorShape");
if(bIsCroppedGraphic)
{
aServiceName = "com.sun.star.drawing.CustomShape";
@@ -1653,6 +1652,34 @@ Reference< XShape > const & Shape::createAndInsert(
if (mbWps && aServiceName == "com.sun.star.drawing.LineShape" && !pParentGroupShape)
mxShape->setPosition(maPosition);
+ if (bIsConnectorShape)
+ {
+ ConnectorType aConnectorType;
+ sal_Int32 nType = mpCustomShapePropertiesPtr->getShapePresetType();
+ switch (nType)
+ {
+ case XML_line:
+ case XML_straightConnector1:
+ aConnectorType = ConnectorType_LINE;
+ break;
+ case XML_bentConnector2:
+ case XML_bentConnector3:
+ case XML_bentConnector4:
+ case XML_bentConnector5:
+ aConnectorType = ConnectorType_STANDARD;
+ break;
+ case XML_curvedConnector2:
+ case XML_curvedConnector3:
+ case XML_curvedConnector4:
+ case XML_curvedConnector5:
+ aConnectorType = ConnectorType_CURVE;
+ break;
+ default:
+ break;
+ }
+ xSet->setPropertyValue("EdgeKind", Any(aConnectorType));
+ }
+
if( bIsCustomShape )
{
if ( mbFlipH )
@@ -1701,7 +1728,7 @@ Reference< XShape > const & Shape::createAndInsert(
// for these ==cscode== and ==csdata== markers, so don't "clean up" these SAL_INFOs
SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
- mpCustomShapePropertiesPtr->pushToPropSet( xSet, mxShape, maSize );
+ mpCustomShapePropertiesPtr->pushToPropSet(xSet, maSize);
if (mpTextBody)
{
diff --git a/oox/source/drawingml/shapegroupcontext.cxx b/oox/source/drawingml/shapegroupcontext.cxx
index 61aadb45d862..1a9cb4113871 100644
--- a/oox/source/drawingml/shapegroupcontext.cxx
+++ b/oox/source/drawingml/shapegroupcontext.cxx
@@ -85,7 +85,8 @@ ContextHandlerRef ShapeGroupContext::onCreateContext( sal_Int32 aElementToken, c
{
ShapePtr pShape = std::make_shared<Shape>("com.sun.star.drawing.ConnectorShape");
pShape->setLockedCanvas(mpGroupShapePtr->getLockedCanvas());
- return new ConnectorShapeContext( *this, mpGroupShapePtr, pShape );
+ return new ConnectorShapeContext(*this, mpGroupShapePtr, pShape,
+ pShape->getConnectorShapeProperties());
}
case XML_grpSp: // group shape
return new ShapeGroupContext( *this, mpGroupShapePtr, std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" ) );
diff --git a/oox/source/drawingml/shapepropertiescontext.cxx b/oox/source/drawingml/shapepropertiescontext.cxx
index e0fc3274c731..935cc4970c7c 100644
--- a/oox/source/drawingml/shapepropertiescontext.cxx
+++ b/oox/source/drawingml/shapepropertiescontext.cxx
@@ -62,16 +62,10 @@ ContextHandlerRef ShapePropertiesContext::onCreateContext( sal_Int32 aElementTok
{
sal_Int32 nToken = rAttribs.getToken( XML_prst, 0 );
// TODO: Move the following checks to a separate place or as a separate function
- if ( nToken == XML_line )
+ if (nToken == XML_line && !mrShape.isConnectorShape())
{
mrShape.getServiceName() = "com.sun.star.drawing.LineShape";
}
- if( ( nToken >= XML_bentConnector2 && nToken <= XML_bentConnector5 ) ||
- ( nToken >= XML_curvedConnector2 && nToken <= XML_curvedConnector5 ) ||
- nToken == XML_straightConnector1 )
- {
- mrShape.getServiceName() = "com.sun.star.drawing.CustomShape";
- }
// We got a preset geometry, forget the geometry inherited from the placeholder shape.
mrShape.getCustomShapeProperties() = std::make_shared<CustomShapeProperties>();
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index ea0e21f457d8..0405c975db0a 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -1496,7 +1496,8 @@ ShapeExport& ShapeExport::WriteConnectorShape( const Reference< XShape >& xShape
pFS->startElementNS(mnXmlNamespace, XML_cNvCxnSpPr);
WriteConnectorConnections(aConnectorEntry, GetShapeID(rXShapeA), GetShapeID(rXShapeB));
pFS->endElementNS(mnXmlNamespace, XML_cNvCxnSpPr);
- pFS->singleElementNS(mnXmlNamespace, XML_nvPr);
+ if (GetDocumentType() == DOCUMENT_PPTX)
+ pFS->singleElementNS(mnXmlNamespace, XML_nvPr);
pFS->endElementNS(mnXmlNamespace, XML_nvCxnSpPr);
}
diff --git a/oox/source/ppt/pptshapegroupcontext.cxx b/oox/source/ppt/pptshapegroupcontext.cxx
index 4355f951bc8b..4ca58a383af8 100644
--- a/oox/source/ppt/pptshapegroupcontext.cxx
+++ b/oox/source/ppt/pptshapegroupcontext.cxx
@@ -90,7 +90,11 @@ ContextHandlerRef PPTShapeGroupContext::onCreateContext( sal_Int32 aElementToken
return new ShapeStyleContext( getParser() );
*/
case PPT_TOKEN( cxnSp ): // connector shape
- return new oox::drawingml::ConnectorShapeContext( *this, mpGroupShapePtr, std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.ConnectorShape" ) );
+ {
+ auto pShape = std::make_shared<PPTShape>(meShapeLocation, "com.sun.star.drawing.ConnectorShape");
+ return new oox::drawingml::ConnectorShapeContext(*this, mpGroupShapePtr, pShape,
+ pShape->getConnectorShapeProperties());
+ }
case PPT_TOKEN( grpSp ): // group shape
return new PPTShapeGroupContext( *this, mpSlidePersistPtr, meShapeLocation, mpGroupShapePtr, std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.GroupShape" ) );
case PPT_TOKEN( sp ): // Shape
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
index ae9f0f567a7c..061dda725551 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -41,6 +41,9 @@
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/container/XIdentifierContainer.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
using namespace ::com::sun::star;
using namespace ::oox::core;
@@ -143,12 +146,19 @@ void SlidePersist::createXShapes( XmlFilterBase& rFilterBase )
PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
basegfx::B2DHomMatrix aTransformation;
if ( pPPTShape )
+ {
pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, aTransformation, &getShapeMap() );
+ if (pPPTShape->isConnectorShape())
+ maConnectorShapeId.push_back(pPPTShape->getId());
+ }
else
child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() );
}
}
+ if (!maConnectorShapeId.empty())
+ createConnectorShapeConnection();
+
Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY);
if( !xNodeSupplier.is() )
return;
@@ -330,6 +340,66 @@ Reference<XAnimationNode> SlidePersist::getAnimationNode(const OUString& sId) co
return aResult;
}
+// create connection between two shape with a connector shape.
+void SlidePersist::createConnectorShapeConnection()
+{
+ sal_Int32 nConnectorShapeCount = maConnectorShapeId.size();
+ for (sal_Int32 i = 0; i < nConnectorShapeCount; i++)
+ {
+ const auto& pIt = maShapeMap.find(maConnectorShapeId[i]);
+ oox::drawingml::ConnectorShapePropertiesList aConnectorShapeProperties
+ = pIt->second->getConnectorShapeProperties();
+ uno::Reference<drawing::XShape> xConnector(pIt->second->getXShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xConnector, uno::UNO_QUERY);
+
+ if (xConnector.is())
+ {
+ sal_Int32 nCount = aConnectorShapeProperties.size();
+ for (sal_Int32 j = 0; j < nCount; j++)
+ {
+ OUString aDestShapeId = aConnectorShapeProperties[j].maDestShapeId;
+ const auto& pShape = maShapeMap.find(aDestShapeId);
+ uno::Reference<drawing::XShape> xShape(pShape->second->getXShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSet(xShape, uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ uno::Reference<drawing::XGluePointsSupplier> xSupplier(xShape, uno::UNO_QUERY);
+ css::uno::Reference<css::container::XIdentifierContainer> xGluePoints(
+ xSupplier->getGluePoints(), uno::UNO_QUERY);
+
+ sal_Int32 nCountGluePoints = xGluePoints->getIdentifiers().getLength();
+ sal_Int32 nGlueId = aConnectorShapeProperties[j].mnDestGlueId;
+
+ // The first 4 glue points belong to the bounding box.
+ if (nCountGluePoints > 4)
+ nGlueId += 4;
+ else
+ {
+ // change id of the left and right glue points of the bounding box (1 <-> 3)
+ if (nGlueId == 1)
+ nGlueId = 3; // Right
+ else if (nGlueId == 3)
+ nGlueId = 1; // Left
+ }
+
+ bool bStart = aConnectorShapeProperties[j].mbStartShape;
+ if (bStart)
+ {
+ xPropertySet->setPropertyValue("StartShape", uno::Any(xShape));
+ xPropertySet->setPropertyValue("StartGluePointIndex", uno::Any(nGlueId));
+ }
+ else
+ {
+ xPropertySet->setPropertyValue("EndShape", uno::Any(xShape));
+ xPropertySet->setPropertyValue("EndGluePointIndex", uno::Any(nGlueId));
+ }
+ }
+ }
+ }
+ }
+ maConnectorShapeId.clear();
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/LockedCanvasContext.cxx b/oox/source/shape/LockedCanvasContext.cxx
index 5eac3b5ceff7..19267954cf06 100644
--- a/oox/source/shape/LockedCanvasContext.cxx
+++ b/oox/source/shape/LockedCanvasContext.cxx
@@ -51,9 +51,10 @@ LockedCanvasContext::onCreateContext(sal_Int32 nElementToken, const ::oox::Attri
}
case XML_cxnSp: // CT_GvmlConnector
{
- return new oox::drawingml::ConnectorShapeContext(
- *this, mpShapePtr,
- std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.ConnectorShape"));
+ oox::drawingml::ShapePtr pShape
+ = std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.ConnectorShape");
+ return new oox::drawingml::ConnectorShapeContext(*this, mpShapePtr, pShape,
+ pShape->getConnectorShapeProperties());
}
case XML_pic: // CT_GvmlPicture
{