include/oox/drawingml/diagram/diagramhelper_oox.hxx | 19 +-- include/oox/drawingml/shape.hxx | 4 include/svx/diagram/DiagramHelper_svx.hxx | 9 + include/svx/diagram/DomMapFlag.hxx | 3 include/svx/diagram/datamodel_svx.hxx | 92 +++++++++-------- include/svx/svdobj.hxx | 7 - oox/source/drawingml/diagram/datamodel_oox.cxx | 52 +++++++-- oox/source/drawingml/diagram/datamodel_oox.hxx | 3 oox/source/drawingml/diagram/datamodelcontext.cxx | 2 oox/source/drawingml/diagram/diagram.cxx | 44 +++++--- oox/source/drawingml/diagram/diagram.hxx | 15 +- oox/source/drawingml/diagram/diagramhelper_oox.cxx | 40 +++++-- oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 6 - oox/source/drawingml/diagram/layoutatomvisitorbase.hxx | 6 - oox/source/drawingml/diagram/layoutatomvisitors.hxx | 6 - oox/source/drawingml/graphicshapecontext.cxx | 4 oox/source/drawingml/shape.cxx | 7 - oox/source/export/drawingml.cxx | 53 +++++---- svx/source/diagram/DiagramHelper_svx.cxx | 7 + svx/source/diagram/datamodel_svx.cxx | 64 ++++++++--- svx/source/svdraw/svdobj.cxx | 16 ++ svx/source/svdraw/svdogrp.cxx | 10 + 22 files changed, 310 insertions(+), 159 deletions(-)
New commits: commit 8353e8c98547c72ae943a219e4ff5046611869c8 Author: Armin Le Grand (collabora) <[email protected]> AuthorDate: Thu Feb 12 16:16:34 2026 +0100 Commit: Armin Le Grand <[email protected]> CommitDate: Fri Feb 13 10:59:15 2026 +0100 SmartArt: Add basic Copy/Paste functionality Next thing we need copy/paste. That creates internally a new doc with the cloned selected object. Two cases: (a) If copy/paste is inside same instance, that gets cloned again to the target, done. (b) If target is other app (2nd office instance, ...) new doc is saved using ODF (or other), re-loaded by target LO instance and then cloned like (a) For (a) we need cloning functionality in LO core. For (b) we need support in ODF format. Thus (a) is less complext than (b) and a precondition for (b), too. This change mainly enables (a). It also contains deep check of correctness for DomTrees for Data and Drawing stuff, especially for Pint and Connection data. Also as a 1st step for (b) I moved the DiagramDataModelID to use the SdrObjectTitle - those Objects are encapsulated inside the hosting GroupObject anyways and we have that part of ODF im/export solved that way. NOTE: I first used SdrObjectName, but that gets *changed* when SdrObject is cloned to ensure unified ObjNames inside a Document. This is secured by ACTIVATE_ADVANCED_DIAGRAM_FEATURES as last commits for SmartArt since notg complete. Change-Id: Iff51ca56e559111cc8d205fc501d96b0a1d7c616 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199287 Reviewed-by: Armin Le Grand <[email protected]> Tested-by: Jenkins diff --git a/include/oox/drawingml/diagram/diagramhelper_oox.hxx b/include/oox/drawingml/diagram/diagramhelper_oox.hxx index 046e4e885ede..30367e0b2930 100644 --- a/include/oox/drawingml/diagram/diagramhelper_oox.hxx +++ b/include/oox/drawingml/diagram/diagramhelper_oox.hxx @@ -27,7 +27,7 @@ namespace oox::drawingml { -class Diagram; +class SmartArtDiagram; class DrawingML; // Advanced DiagramHelper @@ -45,19 +45,16 @@ class DrawingML; // - im/export Diagram model to other representations class DiagramHelper_oox final : public svx::diagram::DiagramHelper_svx { - const std::shared_ptr< Diagram > mpDiagramPtr; - std::shared_ptr<::oox::drawingml::Theme> mpThemePtr; + const std::shared_ptr< SmartArtDiagram > mpDiagramPtr; + std::shared_ptr<::oox::drawingml::Theme> mpDiagramThemePtr; - css::awt::Size maImportSize; + css::awt::Size maDiagramImportSize; // data values set by addDiagramNode to be used by next reLayout call // when a new ode gets added OUString msNewNodeId; OUString msNewNodeText; - // flag to remember if initial import had a DrawingDom at all - bool mbInitiallyNoDrawingDom; - bool hasDiagramData() const; static void moveDiagramModelDataFromOldToNewXShape( @@ -70,9 +67,10 @@ protected: public: DiagramHelper_oox( - std::shared_ptr< Diagram > xDiagramPtr, + std::shared_ptr< SmartArtDiagram > xDiagramPtr, std::shared_ptr<::oox::drawingml::Theme> xTheme, css::awt::Size aImportSize); + explicit DiagramHelper_oox(DiagramHelper_oox const& rSource); virtual ~DiagramHelper_oox(); // re-create XShapes @@ -110,9 +108,8 @@ public: void writeDiagramOOXData(DrawingML& rOriginalDrawingML, css::uno::Reference<css::io::XOutputStream>& xOutputStream, std::u16string_view rDrawingRelId) const; void writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, css::uno::Reference<css::io::XOutputStream>& xOutputStream) const; - // flag to remember if initial import had a DrawingDom at all - void setInitiallyNoDrawingDom(bool bNew) { mbInitiallyNoDrawingDom = bNew; } - bool getInitiallyNoDrawingDom() const { return mbInitiallyNoDrawingDom; } + // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor + virtual DiagramHelper_oox* clone() const override; }; } diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx index a0f7af687d63..59f5e2a9e33d 100644 --- a/include/oox/drawingml/shape.hxx +++ b/include/oox/drawingml/shape.hxx @@ -98,7 +98,7 @@ struct LinkedTxbxAttr LinkedTxbxAttr(): id(0),seq(0){}; }; -class Diagram; +class SmartArtDiagram; class OOX_DLLPUBLIC Shape : public std::enable_shared_from_this< Shape > @@ -277,7 +277,7 @@ public: // Allows preparation of a local Diagram helper && propagate an eventually // existing one to the data holder object later SAL_DLLPRIVATE void prepareDiagramHelper( - const std::shared_ptr< Diagram >& rDiagramPtr, + const std::shared_ptr< SmartArtDiagram >& rDiagramPtr, const std::shared_ptr<::oox::drawingml::Theme>& rTheme); SAL_DLLPRIVATE void propagateDiagramHelper(); diff --git a/include/svx/diagram/DiagramHelper_svx.hxx b/include/svx/diagram/DiagramHelper_svx.hxx index 583964d7ac40..60bd7c37754b 100644 --- a/include/svx/diagram/DiagramHelper_svx.hxx +++ b/include/svx/diagram/DiagramHelper_svx.hxx @@ -84,8 +84,12 @@ protected: // access associated SdrObjGroup/XShape/RootShape virtual css::uno::Reference< css::drawing::XShape >& accessRootShape() = 0; -public: + // Make constructor protected to signal that this anyway pure virtual class + // shall not be incarnated - target to use is oox::drawingml::DiagramHelper_oox DiagramHelper_svx(); + explicit DiagramHelper_svx(DiagramHelper_svx const& rSource); + +public: virtual ~DiagramHelper_svx(); // re-create XShapes @@ -127,6 +131,9 @@ public: // access to RootShape - the GroupObject used to host this Diagram css::uno::Reference< css::drawing::XShape >& getRootShape() { return accessRootShape(); } + + // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor + virtual DiagramHelper_svx* clone() const = 0; }; }} // end of namespace diff --git a/include/svx/diagram/DomMapFlag.hxx b/include/svx/diagram/DomMapFlag.hxx index 0ceb4186f7f3..e9673e1d990d 100644 --- a/include/svx/diagram/DomMapFlag.hxx +++ b/include/svx/diagram/DomMapFlag.hxx @@ -34,7 +34,8 @@ enum class SVXCORE_DLLPUBLIC DomMapFlag : sal_uInt16 OOXStyle = 4, OOXColor = 5, OOXDrawing = 6, - OOXDrawingRels = 7 + OOXDrawingImageRels = 7, + OOXDrawingHlinkRels = 8 }; typedef std::vector<DomMapFlag> DomMapFlags; diff --git a/include/svx/diagram/datamodel_svx.hxx b/include/svx/diagram/datamodel_svx.hxx index 357c63245894..352eae2104d0 100644 --- a/include/svx/diagram/datamodel_svx.hxx +++ b/include/svx/diagram/datamodel_svx.hxx @@ -60,7 +60,7 @@ struct SVXCORE_DLLPUBLIC Connection { Connection(); - TypeConstant mnXMLType; + TypeConstant mnXMLType; // default is XML_parOf OUString msModelId; OUString msSourceId; OUString msDestId; @@ -81,51 +81,56 @@ struct SVXCORE_DLLPUBLIC Point { Point(); - OUString msCnxId; - OUString msModelId; - OUString msColorTransformCategoryId; - OUString msColorTransformTypeId; - OUString msLayoutCategoryId; - OUString msLayoutTypeId; - OUString msPlaceholderText; - OUString msPresentationAssociationId; - OUString msPresentationLayoutName; - OUString msPresentationLayoutStyleLabel; - OUString msQuickStyleCategoryId; - OUString msQuickStyleTypeId; - OUString msResizeHandles; - - TypeConstant mnXMLType; - sal_Int32 mnMaxChildren; - sal_Int32 mnPreferredChildren; - sal_Int32 mnDirection; - std::optional<sal_Int32> moHierarchyBranch; - sal_Int32 mnCustomAngle; - sal_Int32 mnPercentageNeighbourWidth; - sal_Int32 mnPercentageNeighbourHeight; - sal_Int32 mnPercentageOwnWidth; - sal_Int32 mnPercentageOwnHeight; - sal_Int32 mnIncludeAngleScale; - sal_Int32 mnRadiusScale; - sal_Int32 mnWidthScale; - sal_Int32 mnHeightScale; - sal_Int32 mnWidthOverride; - sal_Int32 mnHeightOverride; - sal_Int32 mnLayoutStyleCount; - sal_Int32 mnLayoutStyleIndex; - - bool mbOrgChartEnabled; - bool mbBulletEnabled; - bool mbCoherent3DOffset; - bool mbCustomHorizontalFlip; - bool mbCustomVerticalFlip; - bool mbCustomText; - bool mbIsPlaceholder; + // PT: dgm:pt + // PRS: dgm:prSet + // PLV: dgm:presLayoutVars + + /* PT */ OUString msCnxId; + /* PT */ OUString msModelId; + /* PRS */ OUString msColorTransformCategoryId; + /* PRS */ OUString msColorTransformTypeId; + /* PRS */ OUString msLayoutCategoryId; + /* PRS */ OUString msLayoutTypeId; + /* PRS */ OUString msPlaceholderText; + /* PRS */ OUString msPresentationAssociationId; + /* PRS */ OUString msPresentationLayoutName; + /* PRS */ OUString msPresentationLayoutStyleLabel; + /* PRS */ OUString msQuickStyleCategoryId; + /* PRS */ OUString msQuickStyleTypeId; + /* PLV */ OUString msResizeHandles; + + /* PT */ TypeConstant mnXMLType; // default is XML_node + /* PLV */ sal_Int32 mnMaxChildren; + /* PLV */ sal_Int32 mnPreferredChildren; + /* PLV */ sal_Int32 mnDirection; + /* PLV */ std::optional<sal_Int32> moHierarchyBranch; + + /* PRS */ sal_Int32 mnCustomAngle; + /* PRS */ sal_Int32 mnPercentageNeighbourWidth; + /* PRS */ sal_Int32 mnPercentageNeighbourHeight; + /* PRS */ sal_Int32 mnPercentageOwnWidth; + /* PRS */ sal_Int32 mnPercentageOwnHeight; + /* PRS */ sal_Int32 mnIncludeAngleScale; + /* PRS */ sal_Int32 mnRadiusScale; + /* PRS */ sal_Int32 mnWidthScale; + /* PRS */ sal_Int32 mnHeightScale; + /* PRS */ sal_Int32 mnWidthOverride; + /* PRS */ sal_Int32 mnHeightOverride; + /* PRS */ sal_Int32 mnLayoutStyleCount; + /* PRS */ sal_Int32 mnLayoutStyleIndex; + + /* PLV */ bool mbOrgChartEnabled : 1; + /* PLV */ bool mbBulletEnabled : 1; + /* PRS */ bool mbCoherent3DOffset : 1; + /* PRS */ bool mbCustomHorizontalFlip : 1; + /* PRS */ bool mbCustomVerticalFlip : 1; + /* PRS */ bool mbCustomText : 1; + /* PRS */ bool mbIsPlaceholder : 1; void writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget); }; -void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList); +void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint); typedef std::vector< Point > Points; /** Snippet of Diagram ModelData for Diagram-defining data undo/redo @@ -166,6 +171,7 @@ protected: // Make constructor protected to signal that this anyway pure virtual class // shall not be incarnated - target to use is oox::drawingml::DiagramData_oox DiagramData_svx(); + explicit DiagramData_svx(DiagramData_svx const& rSource); public: // access associated SdrObjGroup/XShape/RootShape @@ -178,7 +184,9 @@ public: virtual void buildDiagramDataModel(bool bClearOoxShapes); // dump to readable format +#ifdef DBG_UTIL virtual void dump() const = 0; + #endif // read accesses Connections& getConnections() { return maConnections; } diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx index af040b18d14c..4fd5a4773499 100644 --- a/include/svx/svdobj.hxx +++ b/include/svx/svdobj.hxx @@ -230,8 +230,8 @@ public: virtual bool isDiagram() const; virtual const std::shared_ptr< svx::diagram::DiagramHelper_svx >& getDiagramHelper() const; const std::shared_ptr< svx::diagram::DiagramHelper_svx >& getDiagramHelperFromDiagramOrMember() const; - void setDiagramDataModelID(const OUString& rID) { msDiagramDataModelID = rID; } - const OUString& getDiagramDataModelID() const { return msDiagramDataModelID; } + void setDiagramDataModelID(const OUString& rID); + const OUString& getDiagramDataModelID() const; private: friend class SdrObjListIter; @@ -993,9 +993,6 @@ private: // Hyperlink for the whole shape OUString msHyperlink; - // if this object is a representation of Diagram Sub-Data, hold the DataModelID - OUString msDiagramDataModelID; - // only for internal use! SvxShape* getSvxShape(); diff --git a/oox/source/drawingml/diagram/datamodel_oox.cxx b/oox/source/drawingml/diagram/datamodel_oox.cxx index 349656c71c34..9c9f4b085e12 100644 --- a/oox/source/drawingml/diagram/datamodel_oox.cxx +++ b/oox/source/drawingml/diagram/datamodel_oox.cxx @@ -129,7 +129,7 @@ void DiagramData_oox::writeDiagramData(DrawingML& rOriginalDrawingML, sax_fastpa rtl::Reference<sax_fastparser::FastAttributeList> pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList()); pAttributeList->add(XML_modelId, rPoint.msModelId); - addTypeConstantToFastAttributeList(rPoint.mnXMLType, pAttributeList); + addTypeConstantToFastAttributeList(rPoint.mnXMLType, pAttributeList, true); if (!rPoint.msCnxId.isEmpty()) pAttributeList->add(XML_cxnId, rPoint.msCnxId); rTarget->startElementNS(XML_dgm, XML_pt, pAttributeList); @@ -212,9 +212,13 @@ void DiagramData_oox::writeDiagramData(DrawingML& rOriginalDrawingML, sax_fastpa if (bWriteFill) { + rTarget->startElementNS(XML_dgm, XML_spPr); + DrawingML aTempML(rTarget, pOriginalFB); aTempML.setDiagaramExport(true); aTempML.WriteFill( xProps, xAssociatedShape->getSize()); + + rTarget->endElementNS(XML_dgm, XML_spPr); } else { @@ -274,7 +278,7 @@ void DiagramData_oox::writeDiagramData(DrawingML& rOriginalDrawingML, sax_fastpa { aDspLine += u"relId=\""_ustr + rDrawingRelId + u"\" "_ustr; } - aDspLine += u"minVer=\""_ustr + aNsDml + u"\"/>"_ustr; + aDspLine += u"minVer=\""_ustr + aNsDmlDiagram + u"\"/>"_ustr; rTarget->write(aDspLine); rTarget->endElementNS(XML_a, XML_ext); rTarget->endElementNS(XML_dgm, XML_extLst); @@ -289,38 +293,64 @@ DiagramData_oox::DiagramData_oox() { } +DiagramData_oox::DiagramData_oox(DiagramData_oox const& rSource) +: svx::diagram::DiagramData_svx(rSource) +, mpBackgroundShapeFillProperties() +, maPointShapeMap() +{ +} + DiagramData_oox::~DiagramData_oox() { } +#ifdef DBG_UTIL static void Connection_dump(const svx::diagram::Connection& rConnection) { SAL_INFO( "oox.drawingml", - "cnx modelId " << rConnection.msModelId << ", srcId " << rConnection.msSourceId << ", dstId " + " CNX: modelId " << rConnection.msModelId << ", srcId " << rConnection.msSourceId << ", dstId " << rConnection.msDestId << ", parTransId " << rConnection.msParTransId << ", presId " << rConnection.msPresId << ", sibTransId " << rConnection.msSibTransId << ", srcOrd " << rConnection.mnSourceOrder << ", dstOrd " << rConnection.mnDestOrder); } -static void Point_dump(const svx::diagram::Point& rPoint, const Shape* pShape) +static void Point_dump(const svx::diagram::Point& rPoint, const uno::Reference<drawing::XShape>& rXShape) { - SAL_INFO( - "oox.drawingml", - "pt text " << pShape << ", cnxId " << rPoint.msCnxId << ", modelId " - << rPoint.msModelId << ", type " << rPoint.mnXMLType); + SAL_INFO("oox.drawingml", "PT: " << rXShape.is() << ", cnxId " << rPoint.msCnxId << ", modelId " << rPoint.msModelId << ", type " << rPoint.mnXMLType); + + SAL_INFO("oox.drawingml", " PRS_0: " << rPoint.msColorTransformCategoryId << "," << rPoint.msColorTransformTypeId << "," << rPoint.msLayoutCategoryId << "," << rPoint.msLayoutTypeId << "," << rPoint.msPlaceholderText); + SAL_INFO("oox.drawingml", " PRS_1: " << rPoint.msPresentationAssociationId << "," << rPoint.msPresentationLayoutName << "," << rPoint.msPresentationLayoutStyleLabel << "," << rPoint.msQuickStyleCategoryId << "," << rPoint.msQuickStyleTypeId); + SAL_INFO("oox.drawingml", " PRS_2: " << rPoint.mnCustomAngle << "," << rPoint.mnPercentageNeighbourWidth << "," << rPoint.mnPercentageNeighbourHeight << "," << rPoint.mnPercentageOwnWidth << "," << rPoint.mnPercentageOwnHeight); + SAL_INFO("oox.drawingml", " PRS_3: " << rPoint.mnIncludeAngleScale<< rPoint.mnRadiusScale << "," << rPoint.mnWidthScale << "," << rPoint.mnHeightScale << "," << rPoint.mnWidthOverride << "," << rPoint.mnHeightOverride << "," << rPoint.mnLayoutStyleCount << "," << rPoint.mnLayoutStyleIndex); + SAL_INFO("oox.drawingml", " PRS_4: " << rPoint.mbCoherent3DOffset << "," << rPoint.mbCustomHorizontalFlip << "," << rPoint.mbCustomVerticalFlip << "," << rPoint.mbCustomText << "," << rPoint.mbIsPlaceholder); + + SAL_INFO("oox.drawingml", " PLV_0: " << rPoint.msResizeHandles << "," << rPoint.mnMaxChildren << "," << rPoint.mnPreferredChildren << "," << rPoint.mnDirection << "," << rPoint.mbOrgChartEnabled << "," << rPoint.mbBulletEnabled); + SAL_INFO("oox.drawingml", " PLV_1: " << (rPoint.moHierarchyBranch.has_value() ? rPoint.moHierarchyBranch.value() : 0)); + } void DiagramData_oox::dump() const { - SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of cnx: " << maConnections.size() ); + size_t a = maConnections.size(); + SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of cnx: " << a ); + a = 0; for (const auto& rConnection : maConnections) + { + SAL_INFO("oox.drawingml", "cnx #" << a++ << ":"); Connection_dump(rConnection); + } - SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of pt: " << maPoints.size() ); + a = maPoints.size(); + SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of pt: " << a ); + a = 0; for (const auto& rPoint : maPoints) - Point_dump(rPoint, getOrCreateAssociatedShape(rPoint)); + { + SAL_INFO("oox.drawingml", "pt #" << a++ << ":"); + Point_dump(rPoint, getXShapeByModelID(rPoint.msModelId)); + } } +#endif void DiagramData_oox::buildDiagramDataModel(bool bClearOoxShapes) { diff --git a/oox/source/drawingml/diagram/datamodel_oox.hxx b/oox/source/drawingml/diagram/datamodel_oox.hxx index 75579681d2e0..9cede1263d90 100644 --- a/oox/source/drawingml/diagram/datamodel_oox.hxx +++ b/oox/source/drawingml/diagram/datamodel_oox.hxx @@ -42,13 +42,16 @@ public: typedef std::map< OUString, ShapePtr > PointShapeMap; DiagramData_oox(); + explicit DiagramData_oox(DiagramData_oox const& rSource); virtual ~DiagramData_oox(); // creates temporary processing data from model data virtual void buildDiagramDataModel(bool bClearOoxShapes); FillPropertiesPtr& getBackgroundShapeFillProperties() { return mpBackgroundShapeFillProperties; } +#ifdef DBG_UTIL virtual void dump() const; +#endif Shape* getOrCreateAssociatedShape(const svx::diagram::Point& rPoint, bool bCreateOnDemand = false) const; diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx b/oox/source/drawingml/diagram/datamodelcontext.cxx index 336c870a5659..34307b9d6d93 100644 --- a/oox/source/drawingml/diagram/datamodelcontext.cxx +++ b/oox/source/drawingml/diagram/datamodelcontext.cxx @@ -343,7 +343,9 @@ DataModelContext::DataModelContext( ContextHandler2Helper const& rParent, DataModelContext::~DataModelContext() { // some debug +#ifdef DBG_UTIL mpDataModel->dump(); +#endif } ContextHandlerRef diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index 5e4089a9d8e2..dc78b6d46511 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -118,10 +118,10 @@ static void removeUnneededGroupShapes(const ShapePtr& pShape) } -void Diagram::createShapeHierarchyFromModel( const ShapePtr & pParentShape, bool bCreate ) +void SmartArtDiagram::createShapeHierarchyFromModel( const ShapePtr & pParentShape, bool bCreate ) { if (pParentShape->getSize().Width == 0 || pParentShape->getSize().Height == 0) - SAL_WARN("oox.drawingml", "Diagram cannot be correctly laid out. Size: " + SAL_WARN("oox.drawingml", "SmartArtDiagram cannot be correctly laid out. Size: " << pParentShape->getSize().Width << "x" << pParentShape->getSize().Height); pParentShape->setChildSize(pParentShape->getSize()); @@ -157,12 +157,27 @@ void Diagram::createShapeHierarchyFromModel( const ShapePtr & pParentShape, bool aChildren.insert(aChildren.begin(), pBackground); } -Diagram::Diagram() +SmartArtDiagram::SmartArtDiagram() : maDiagramFontHeights() +, mpData() +, mpLayout() +, maStyles() +, maColors() +, maDiagramPRDomMap() { } -uno::Any Diagram::getOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag) const +SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource) +: maDiagramFontHeights() +, mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr) +, mpLayout(rSource.mpLayout) +, maStyles(rSource.maStyles) +, maColors(rSource.maColors) +, maDiagramPRDomMap(rSource.maDiagramPRDomMap) +{ +} + +uno::Any SmartArtDiagram::getOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag) const { const DiagramPRDomMap::const_iterator aHit = maDiagramPRDomMap.find(aDomMapFlag); @@ -172,12 +187,12 @@ uno::Any Diagram::getOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag) const return uno::Any(); } -void Diagram::setOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag, const uno::Any& rValue) +void SmartArtDiagram::setOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag, const uno::Any& rValue) { maDiagramPRDomMap[aDomMapFlag] = rValue; } -void Diagram::resetOOXDomValues(svx::diagram::DomMapFlags aDomMapFlags) +void SmartArtDiagram::resetOOXDomValues(svx::diagram::DomMapFlags aDomMapFlags) { for (const auto& rEntry : aDomMapFlags) { @@ -188,12 +203,12 @@ void Diagram::resetOOXDomValues(svx::diagram::DomMapFlags aDomMapFlags) } } -bool Diagram::checkMinimalDataDoms() const +bool SmartArtDiagram::checkMinimalDataDoms() const { // check if re-creation is activated - static bool bReCreateDiagramDataDoms(nullptr != std::getenv("ACTIVATE_RECREATE_DIAGRAM_DATADOMS")); + static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES")); - if (!bReCreateDiagramDataDoms && maDiagramPRDomMap.end() == maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXData)) + if (!bActivateAdvancedDiagramFeatures && maDiagramPRDomMap.end() == maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXData)) return false; if (maDiagramPRDomMap.end() == maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXLayout)) @@ -208,7 +223,7 @@ bool Diagram::checkMinimalDataDoms() const return true; } -void Diagram::writeDiagramOOXData(DrawingML& rOriginalDrawingML, uno::Reference<io::XOutputStream>& xOutputStream, std::u16string_view rDrawingRelId) const +void SmartArtDiagram::writeDiagramOOXData(DrawingML& rOriginalDrawingML, uno::Reference<io::XOutputStream>& xOutputStream, std::u16string_view rDrawingRelId) const { if (!xOutputStream) return; @@ -247,7 +262,7 @@ void Diagram::writeDiagramOOXData(DrawingML& rOriginalDrawingML, uno::Reference< #endif } -void Diagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, uno::Reference<io::XOutputStream>& xOutputStream) const +void SmartArtDiagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, uno::Reference<io::XOutputStream>& xOutputStream) const { if (!xOutputStream) return; @@ -290,7 +305,7 @@ void Diagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, uno::Referen using ShapePairs = std::map<std::shared_ptr<drawingml::Shape>, uno::Reference<drawing::XShape>>; -void Diagram::syncDiagramFontHeights() +void SmartArtDiagram::syncDiagramFontHeights() { // Each name represents a group of shapes, for which the font height should have the same // scaling. @@ -421,7 +436,7 @@ void loadDiagram( ShapePtr const & pShape, const OUString& rColorStylePath, const oox::core::Relations& rRelations ) { - DiagramPtr pDiagram = std::make_shared<Diagram>(); + DiagramPtr pDiagram = std::make_shared<SmartArtDiagram>(); OoxDiagramDataPtr pData = std::make_shared<DiagramData_oox>(); pDiagram->setData( pData ); @@ -540,6 +555,9 @@ void loadDiagram( ShapePtr const & pShape, // collect data, init maps // for Diagram import, do - for now - NOT clear all oox::drawingml::Shape pData->buildDiagramDataModel(false); +#ifdef DBG_UTIL + pData->dump(); +#endif // diagram loaded. now lump together & attach to shape // create own geometry if extLst is not present (no geometric diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx index 4d2008dd9a33..c63e806866c8 100644 --- a/oox/source/drawingml/diagram/diagram.hxx +++ b/oox/source/drawingml/diagram/diagram.hxx @@ -35,7 +35,7 @@ namespace com::sun::star { namespace oox::drawingml { -class Diagram; +class SmartArtDiagram; class LayoutNode; typedef std::shared_ptr< LayoutNode > LayoutNodePtr; class LayoutAtom; @@ -46,7 +46,7 @@ typedef std::map< const svx::diagram::Point*, ShapePtr > PresPointShapeMap; class DiagramLayout { public: - DiagramLayout(Diagram& rDgm) + DiagramLayout(SmartArtDiagram& rDgm) : mrDgm(rDgm) { } @@ -60,7 +60,7 @@ public: { msTitle = sTitle; } void setDesc( const OUString & sDesc ) { msDesc = sDesc; } - Diagram& getDiagram() { return mrDgm; } + SmartArtDiagram& getDiagram() { return mrDgm; } LayoutNodePtr & getNode() { return mpNode; } const LayoutNodePtr & getNode() const @@ -79,7 +79,7 @@ public: { return maPresPointShapeMap; } private: - Diagram& mrDgm; + SmartArtDiagram& mrDgm; OUString msDefStyle; OUString msMinVer; OUString msUniqueId; @@ -125,10 +125,11 @@ struct DiagramColor typedef std::map<OUString,DiagramColor> DiagramColorMap; typedef std::map<svx::diagram::DomMapFlag,css::uno::Any> DiagramPRDomMap; -class Diagram +class SmartArtDiagram { public: - explicit Diagram(); + explicit SmartArtDiagram(); + explicit SmartArtDiagram(SmartArtDiagram const& rSource); void setData( const OoxDiagramDataPtr& pData ) { mpData = pData; } const OoxDiagramDataPtr& getData() const @@ -169,7 +170,7 @@ private: DiagramPRDomMap maDiagramPRDomMap; }; -typedef std::shared_ptr< Diagram > DiagramPtr; +typedef std::shared_ptr< SmartArtDiagram > DiagramPtr; } diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx b/oox/source/drawingml/diagram/diagramhelper_oox.cxx index c77e2a0a73a5..4f3ad43d84fe 100644 --- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx +++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx @@ -42,15 +42,24 @@ namespace oox::drawingml { bool DiagramHelper_oox::hasDiagramData() const { return mpDiagramPtr && mpDiagramPtr->getData(); } -DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr<Diagram> xDiagramPtr, +DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr<SmartArtDiagram> xDiagramPtr, std::shared_ptr<::oox::drawingml::Theme> xTheme, awt::Size aImportSize) : mpDiagramPtr(std::move(xDiagramPtr)) - , mpThemePtr(std::move(xTheme)) - , maImportSize(aImportSize) + , mpDiagramThemePtr(std::move(xTheme)) + , maDiagramImportSize(aImportSize) + , msNewNodeId() + , msNewNodeText() +{ +} + +DiagramHelper_oox::DiagramHelper_oox(DiagramHelper_oox const& rSource) + : DiagramHelper_svx(rSource) + , mpDiagramPtr(rSource.mpDiagramPtr ? new SmartArtDiagram(*rSource.mpDiagramPtr) : nullptr) + , mpDiagramThemePtr(rSource.mpDiagramThemePtr) + , maDiagramImportSize(rSource.maDiagramImportSize) , msNewNodeId() , msNewNodeText() - , mbInitiallyNoDrawingDom(false) { } @@ -100,7 +109,7 @@ void DiagramHelper_oox::reLayout() // to get the same layout(s) oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>("com.sun.star.drawing.GroupShape"); pShapePtr->setDiagramType(); - pShapePtr->setSize(maImportSize); + pShapePtr->setSize(maDiagramImportSize); // remember existing DrawingLayerModelData. Do this before createShapeHierarchyFromModel // below, that will create a new BackgroundShapeModelID and the BGShape would @@ -374,7 +383,8 @@ void DiagramHelper_oox::TextInformationChange() aFlags.push_back(DomMapFlag::OOXDrawing); aFlags.push_back(DomMapFlag::OOXDataImageRels); aFlags.push_back(DomMapFlag::OOXDataHlinkRels); - aFlags.push_back(DomMapFlag::OOXDrawingRels); + aFlags.push_back(DomMapFlag::OOXDrawingImageRels); + aFlags.push_back(DomMapFlag::OOXDrawingHlinkRels); mpDiagramPtr->resetOOXDomValues(std::move(aFlags)); // still reset GrabBag at Associated SdrObjGroup object. There are no "OOX.*" @@ -424,7 +434,7 @@ const std::shared_ptr<::oox::drawingml::Theme>& DiagramHelper_oox::getOrCreateTh { // (Re-)Use already existing Theme if existing/imported if possible. // If not, re-import Theme if data is available and thus possible - if (hasDiagramData() && (ForceThemePtrRecreation() || !mpThemePtr)) + if (hasDiagramData() && (ForceThemePtrRecreation() || !mpDiagramThemePtr)) { // get the originally imported dom::XDocument const uno::Reference<xml::dom::XDocument>& xThemeDocument( @@ -434,20 +444,20 @@ const std::shared_ptr<::oox::drawingml::Theme>& DiagramHelper_oox::getOrCreateTh { // reset local Theme ModelData *always* to get rid of former data that would // else be added additionally - const_cast<DiagramHelper_oox*>(this)->mpThemePtr + const_cast<DiagramHelper_oox*>(this)->mpDiagramThemePtr = std::make_shared<oox::drawingml::Theme>(); auto pTheme = std::make_shared<model::Theme>(); - mpThemePtr->setTheme(pTheme); + mpDiagramThemePtr->setTheme(pTheme); // import Theme ModelData rxFilter->importFragment( - new ThemeFragmentHandler(*rxFilter, OUString(), *mpThemePtr, *pTheme), + new ThemeFragmentHandler(*rxFilter, OUString(), *mpDiagramThemePtr, *pTheme), uno::Reference<xml::sax::XFastSAXSerializable>(xThemeDocument, uno::UNO_QUERY_THROW)); } } - return mpThemePtr; + return mpDiagramThemePtr; } void DiagramHelper_oox::setOOXDomValue(DomMapFlag aDomMapFlag, const uno::Any& rValue) @@ -490,6 +500,14 @@ void DiagramHelper_oox::writeDiagramOOXDrawing( mpDiagramPtr->writeDiagramOOXDrawing(rOriginalDrawingML, xOutputStream); } + +DiagramHelper_oox* DiagramHelper_oox::clone() const +{ + if (!mpDiagramPtr) + return nullptr; + + return new DiagramHelper_oox(*this); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index f9ed4c46cc5c..da20dff4cf98 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -306,13 +306,13 @@ class LayoutNode public: typedef std::map<sal_Int32, OUString> VarMap; - LayoutNode(Diagram& rDgm) + LayoutNode(SmartArtDiagram& rDgm) : LayoutAtom(*this) , mrDgm(rDgm) , mnChildOrder(0) { } - Diagram& getDiagram() { return mrDgm; } + SmartArtDiagram& getDiagram() { return mrDgm; } virtual void accept( LayoutAtomVisitor& ) override; VarMap & variables() { return mVariables; } @@ -339,7 +339,7 @@ public: const LayoutNode* getParentLayoutNode() const; private: - Diagram& mrDgm; + SmartArtDiagram& mrDgm; VarMap mVariables; OUString msMoveWith; OUString msStyleLabel; diff --git a/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx b/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx index 49c83f67455d..c202ff17ebdf 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx +++ b/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx @@ -43,7 +43,7 @@ struct LayoutAtomVisitor class LayoutAtomVisitorBase : public LayoutAtomVisitor { public: - LayoutAtomVisitorBase(const Diagram& rDgm, const svx::diagram::Point* pRootPoint) : + LayoutAtomVisitorBase(const SmartArtDiagram& rDgm, const svx::diagram::Point* pRootPoint) : mrDgm(rDgm), mpCurrentNode(pRootPoint), mnCurrIdx(0), @@ -61,7 +61,7 @@ public: virtual void visit(LayoutNode& rAtom) override; protected: - const Diagram& mrDgm; + const SmartArtDiagram& mrDgm; const svx::diagram::Point* mpCurrentNode; sal_Int32 mnCurrIdx; sal_Int32 mnCurrStep; @@ -72,7 +72,7 @@ protected: class ShallowPresNameVisitor : public LayoutAtomVisitorBase { public: - explicit ShallowPresNameVisitor(const Diagram& rDgm, const svx::diagram::Point* pRootPoint) : + explicit ShallowPresNameVisitor(const SmartArtDiagram& rDgm, const svx::diagram::Point* pRootPoint) : LayoutAtomVisitorBase(rDgm, pRootPoint), mnCnt(0) {} diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx index 7c10fc436d8c..e5911192c29a 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx @@ -31,7 +31,7 @@ namespace oox::drawingml { class ShapeCreationVisitor : public LayoutAtomVisitorBase { public: - ShapeCreationVisitor(const Diagram& rDgm, + ShapeCreationVisitor(const SmartArtDiagram& rDgm, const svx::diagram::Point* pRootPoint, ShapePtr xParentShape) : LayoutAtomVisitorBase(rDgm, pRootPoint), @@ -52,7 +52,7 @@ private: class ShapeTemplateVisitor : public LayoutAtomVisitorBase { public: - ShapeTemplateVisitor(const Diagram& rDgm, const svx::diagram::Point* pRootPoint) + ShapeTemplateVisitor(const SmartArtDiagram& rDgm, const svx::diagram::Point* pRootPoint) : LayoutAtomVisitorBase(rDgm, pRootPoint) {} @@ -74,7 +74,7 @@ private: class ShapeLayoutingVisitor : public LayoutAtomVisitorBase { public: - ShapeLayoutingVisitor(const Diagram& rDgm, const svx::diagram::Point* pRootPoint) : + ShapeLayoutingVisitor(const SmartArtDiagram& rDgm, const svx::diagram::Point* pRootPoint) : LayoutAtomVisitorBase(rDgm, pRootPoint) {} diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx index e647d9db7855..3e82b9c956f0 100644 --- a/oox/source/drawingml/graphicshapecontext.cxx +++ b/oox/source/drawingml/graphicshapecontext.cxx @@ -40,7 +40,6 @@ #include <oox/ppt/pptshapegroupcontext.hxx> #include <oox/token/namespaces.hxx> #include <oox/token/tokens.hxx> -#include <oox/drawingml/diagram/diagramhelper_oox.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::io; @@ -316,9 +315,6 @@ ContextHandlerRef DiagramGraphicDataContext::onCreateContext( ::sal_Int32 aEleme if (mpShapePtr->getExtDrawings().empty()) { getFilter().setMissingExtDrawing(); - DiagramHelper_oox* pHelper(mpShapePtr->getDiagramHelper()); - if (nullptr != pHelper) - pHelper->setInitiallyNoDrawingDom(true); } else { diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 1c9384f8f622..26d3a903aa1c 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -254,7 +254,7 @@ Shape::~Shape() } void Shape::prepareDiagramHelper( - const std::shared_ptr< Diagram >& rDiagramPtr, + const std::shared_ptr< SmartArtDiagram >& rDiagramPtr, const std::shared_ptr<::oox::drawingml::Theme>& rTheme) { // Prepare Diagram data collecting for this Shape @@ -2417,8 +2417,11 @@ void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& rFrag svx::diagram::DomMapFlag::OOXDrawing, uno::Any(rFilterBase.importFragment(rFragmentPath))); pAdvancedDiagramHelper->setOOXDomValue( - svx::diagram::DomMapFlag::OOXDrawingRels, + svx::diagram::DomMapFlag::OOXDrawingImageRels, uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, rFragmentPath, u"image"))); + pAdvancedDiagramHelper->setOOXDomValue( + svx::diagram::DomMapFlag::OOXDrawingHlinkRels, + uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, rFragmentPath, u"hlink"))); } void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase) diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 8b0c8989f766..837043b948d8 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -6848,10 +6848,8 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX // from original import. it needs a drawingRelId that is referenced inside dataDom uno::Reference<xml::dom::XDocument> drawingDom; rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawing) >>= drawingDom; - const OUString drawingFileName("diagrams/drawing" + OUString::number(nDiagramId) + ".xml"); - const OUString sRelationCompPrefix(GetRelationCompPrefix()); - const OUString sDir(GetComponentDir()); static bool bForceAlwaysReCreate(nullptr != std::getenv("FORCE_RECREATE_DIAGRAM_DATADOMS")); + static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES")); // check if re-creation is forced (for test purposes) if (drawingDom && bForceAlwaysReCreate) @@ -6865,10 +6863,13 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX // that do not originally have a drawingDom at all. The test mentions // that this file was created in ms word 2007. In those cases we might // try in the future to 'repair' stuff by writing a DrawingDom, but for - // now just do as version before did - write no DrawingSDom at all - const bool bWriteNoDrawingDomAtAll(pAdvancedDiagramHelper->getInitiallyNoDrawingDom()); + // now just do as version before did - write no DrawingDom at all if new + // features are not activated + const OUString drawingFileName("diagrams/drawing" + OUString::number(nDiagramId) + ".xml"); + const OUString sRelationCompPrefix(GetRelationCompPrefix()); + const OUString sDir(GetComponentDir()); - if (!bWriteNoDrawingDomAtAll) + if (bActivateAdvancedDiagramFeatures || drawingDom.is()) { // only add Relation if we write a DrawingDom drawingRelId = mpFB->addRelation( @@ -6876,7 +6877,7 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX Concat2View(sRelationCompPrefix + drawingFileName)); } - if (!drawingDom && !bWriteNoDrawingDomAtAll) + if (!drawingDom && bActivateAdvancedDiagramFeatures) { // no drawingDom exists, so it was either not originally imported or the // Diagram was changed, so it got deleted. write drawingDom directly as @@ -6897,11 +6898,17 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX if (dataDom && bForceAlwaysReCreate) dataDom.clear(); + // add data relation + const OUString dataFileName = "diagrams/data" + OUString::number(nDiagramId) + ".xml"; + const OUString dataRelId = + mpFB->addRelation(mpFS->getOutputStream(), oox::getRelationship(Relationship::DIAGRAMDATA), + Concat2View(sRelationCompPrefix + dataFileName)); + if (!dataDom) { // no dataDom exists, so the Diagram was changed, so it got deleted. // write dataDom directly as sub-content - OUString dataFileName = u"diagrams/data"_ustr + OUString::number(nDiagramId) + u".xml"_ustr; + // OUString dataFileName = u"diagrams/data"_ustr + OUString::number(nDiagramId) + u".xml"_ustr; uno::Reference<io::XOutputStream> xOutputStream = mpFB->openFragmentStream( sDir + u"/"_ustr + dataFileName, u"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml"_ustr); @@ -6971,12 +6978,6 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX mpFS->startElementNS(XML_a, XML_graphicData, XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/diagram"); - // add data relation - OUString dataFileName = "diagrams/data" + OUString::number(nDiagramId) + ".xml"; - OUString dataRelId = - mpFB->addRelation(mpFS->getOutputStream(), oox::getRelationship(Relationship::DIAGRAMDATA), - Concat2View(sRelationCompPrefix + dataFileName)); - // add layout relation OUString layoutFileName = "diagrams/layout" + OUString::number(nDiagramId) + ".xml"; OUString layoutRelId = mpFB->addRelation(mpFS->getOutputStream(), @@ -7012,8 +7013,8 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX { if (!drawingRelId.isEmpty()) { - // NOTE: drawingRelId may be empty if bWriteNoDrawingDomAtAll is set, see - // comments above + // NOTE: drawingRelId may be empty if bActivateAdvancedDiagramFeatures is + // set, see comments above // the original and unchanged dataDom contains a reference to the drawing // relation. We need to update it with the new generated relation value // before writing the dom to the file @@ -7092,11 +7093,19 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW), uno::Sequence<beans::StringPair>()); - // write the associated Images and rels for drawing file - uno::Sequence<uno::Sequence<uno::Any>> xDrawingRelSeq; - rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingRels) >>= xDrawingRelSeq; - writeDiagramImageRels(xDrawingRelSeq, xDrawingOutputStream, u"OOXDiagramDrawingRels", - nDiagramId); + // get originally imported OOXDrawingImageRels + uno::Sequence<uno::Sequence<uno::Any>> xDrawingImageRelSeq; + rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingImageRels) + >>= xDrawingImageRelSeq; + + // get originally imported OOXDataHlinkRels + uno::Sequence<uno::Sequence<uno::Any>> xDrawingHlinkRelSeq; + rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingHlinkRels) + >>= xDrawingHlinkRelSeq; + + // write the associated Images and rels for data file + writeDiagramImageRels(xDrawingImageRelSeq, xDrawingOutputStream, u"OOXDiagramDrawingRels", nDiagramId); + writeDiagramHlinkRels(xDrawingHlinkRelSeq, xDrawingOutputStream); } } @@ -7104,7 +7113,7 @@ void DrawingML::writeDiagramImageRels(const uno::Sequence<uno::Sequence<uno::Any const uno::Reference<io::XOutputStream>& xOutStream, std::u16string_view sGrabBagProperyName, int nDiagramId) { - // add image relationships of OOXData, OOXDiagram + // add image relationships of OOXData, SmartArtDiagram OUString sType(oox::getRelationship(Relationship::IMAGE)); uno::Reference<xml::sax::XWriter> xWriter = xml::sax::Writer::create(comphelper::getProcessComponentContext()); diff --git a/svx/source/diagram/DiagramHelper_svx.cxx b/svx/source/diagram/DiagramHelper_svx.cxx index e4ca89d73d4c..66fce4a71f13 100644 --- a/svx/source/diagram/DiagramHelper_svx.cxx +++ b/svx/source/diagram/DiagramHelper_svx.cxx @@ -412,6 +412,13 @@ DiagramHelper_svx::DiagramHelper_svx() { } +DiagramHelper_svx::DiagramHelper_svx(DiagramHelper_svx const& rSource) +: mbUseDiagramThemeData(rSource.mbUseDiagramThemeData) +, mbUseDiagramModelData(rSource.mbUseDiagramModelData) +, mbForceThemePtrRecreation(rSource.mbForceThemePtrRecreation) +{ +} + DiagramHelper_svx::~DiagramHelper_svx() {} void DiagramHelper_svx::disconnectFromSdrObjGroup() diff --git a/svx/source/diagram/datamodel_svx.cxx b/svx/source/diagram/datamodel_svx.cxx index b20188452d4b..a4fba56d989a 100644 --- a/svx/source/diagram/datamodel_svx.cxx +++ b/svx/source/diagram/datamodel_svx.cxx @@ -35,7 +35,7 @@ using namespace ::com::sun::star; namespace svx::diagram { -void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList) +void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint) { if (TypeConstant::XML_none != aTypeConstant) { @@ -46,9 +46,9 @@ void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Referen case TypeConstant::XML_type: rAttributeList->add(::XML_type, "Type"); break; case TypeConstant::XML_asst: rAttributeList->add(::XML_type, "asst"); break; case TypeConstant::XML_doc: rAttributeList->add(::XML_type, "doc"); break; - case TypeConstant::XML_node: /* XML_node is default, no need to write */ break; + case TypeConstant::XML_node: if(!bPoint) rAttributeList->add(::XML_type, "node"); break; case TypeConstant::XML_norm: rAttributeList->add(::XML_type, "norm"); break; - case TypeConstant::XML_parOf: rAttributeList->add(::XML_type, "parOf"); break; + case TypeConstant::XML_parOf: if(bPoint) rAttributeList->add(::XML_type, "parOf"); break; case TypeConstant::XML_parTrans: rAttributeList->add(::XML_type, "parTrans"); break; case TypeConstant::XML_pres: rAttributeList->add(::XML_type, "pres"); break; case TypeConstant::XML_presOf: rAttributeList->add(::XML_type, "presOf"); break; @@ -61,7 +61,7 @@ void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Referen } Connection::Connection() -: mnXMLType( XML_none ) +: mnXMLType( XML_parOf ) , mnSourceOrder( 0 ) , mnDestOrder( 0 ) { @@ -74,21 +74,27 @@ void Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget) rtl::Reference<sax_fastparser::FastAttributeList> pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList()); - addTypeConstantToFastAttributeList(mnXMLType, pAttributeList); - if (!msModelId.isEmpty()) pAttributeList->add(XML_modelId, msModelId); - if (!msSourceId.isEmpty()) pAttributeList->add(XML_srcId, msSourceId); - if (!msDestId.isEmpty()) pAttributeList->add(XML_destId, msDestId); - if (!msPresId.isEmpty()) pAttributeList->add(XML_presId, msPresId); - if (!msSibTransId.isEmpty()) pAttributeList->add(XML_sibTransId, msSibTransId); - if (!msParTransId.isEmpty()) pAttributeList->add(XML_parTransId, msParTransId); - if (0 != mnSourceOrder) pAttributeList->add(XML_srcOrd, OUString::number(mnSourceOrder)); - if (0 != mnDestOrder) pAttributeList->add(XML_destOrd, OUString::number(mnDestOrder)); + if (!msModelId.isEmpty()) + pAttributeList->add(XML_modelId, msModelId); + addTypeConstantToFastAttributeList(mnXMLType, pAttributeList, false); + if (!msSourceId.isEmpty()) + pAttributeList->add(XML_srcId, msSourceId); + if (!msDestId.isEmpty()) + pAttributeList->add(XML_destId, msDestId); + pAttributeList->add(XML_srcOrd, OUString::number(mnSourceOrder)); + pAttributeList->add(XML_destOrd, OUString::number(mnDestOrder)); + if (!msPresId.isEmpty()) + pAttributeList->add(XML_presId, msPresId); + if (!msParTransId.isEmpty()) + pAttributeList->add(XML_parTransId, msParTransId); + if (!msSibTransId.isEmpty()) + pAttributeList->add(XML_sibTransId, msSibTransId); rTarget->singleElementNS(XML_dgm, XML_cxn, pAttributeList); } Point::Point() -: mnXMLType(XML_none) +: mnXMLType(XML_node) , mnMaxChildren(-1) , mnPreferredChildren(-1) , mnDirection(XML_norm) @@ -193,6 +199,30 @@ void Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget) } DiagramData_svx::DiagramData_svx() +: mxRootShape() +, maExtDrawings() +, maConnections() +, maPoints() +, mxThemeDocument() +, maPointNameMap() +, maPointsPresNameMap() +, maConnectionNameMap() +, maPresOfNameMap() +, msBackgroundShapeModelID() +{ +} + +DiagramData_svx::DiagramData_svx(DiagramData_svx const& rSource) +: mxRootShape() +, maExtDrawings() +, maConnections(rSource.maConnections) +, maPoints(rSource.maPoints) +, mxThemeDocument() +, maPointNameMap() +, maPointsPresNameMap() +, maConnectionNameMap() +, maPresOfNameMap() +, msBackgroundShapeModelID() { } @@ -271,7 +301,8 @@ DomMapFlags DiagramData_svx::removeDiagramNode(const OUString& rNodeId) aRetval.push_back(DomMapFlag::OOXDrawing); aRetval.push_back(DomMapFlag::OOXDataImageRels); aRetval.push_back(DomMapFlag::OOXDataHlinkRels); - aRetval.push_back(DomMapFlag::OOXDrawingRels); + aRetval.push_back(DomMapFlag::OOXDrawingImageRels); + aRetval.push_back(DomMapFlag::OOXDrawingHlinkRels); return aRetval; } @@ -468,7 +499,8 @@ std::pair<OUString, DomMapFlags> DiagramData_svx::addDiagramNode() aRetval.push_back(DomMapFlag::OOXDrawing); aRetval.push_back(DomMapFlag::OOXDataImageRels); aRetval.push_back(DomMapFlag::OOXDataHlinkRels); - aRetval.push_back(DomMapFlag::OOXDrawingRels); + aRetval.push_back(DomMapFlag::OOXDrawingImageRels); + aRetval.push_back(DomMapFlag::OOXDrawingHlinkRels); return std::make_pair(sNewNodeId, aRetval); } diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index b8e0b1fb7212..625af3a3a664 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -202,6 +202,20 @@ struct SdrObject::Impl meRelativeHeightRelation(text::RelOrientation::PAGE_FRAME) {} }; +void SdrObject::setDiagramDataModelID(const OUString& rID) +{ + if (!m_pPlusData) + ImpForcePlusData(); + m_pPlusData->aObjTitle = rID; +} + +const OUString& SdrObject::getDiagramDataModelID() const +{ + if(m_pPlusData) + return m_pPlusData->aObjTitle; + return EMPTY_OUSTRING; +} + bool SdrObject::isDiagram() const { return false; @@ -367,7 +381,6 @@ SdrObject::SdrObject(SdrModel& rSdrModel) , mpSvxShape( nullptr ) , mbDoNotInsertIntoPageAutomatically(false) , msHyperlink() - , msDiagramDataModelID() { m_bVirtObj =false; m_bSnapRectDirty =true; @@ -405,7 +418,6 @@ SdrObject::SdrObject(SdrModel& rSdrModel, SdrObject const & rSource) , mpSvxShape( nullptr ) , mbDoNotInsertIntoPageAutomatically(false) , msHyperlink() - , msDiagramDataModelID() { m_bVirtObj =false; m_bSnapRectDirty =true; diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx index 3f0f85534fb6..47518a5d1d76 100644 --- a/svx/source/svdraw/svdogrp.cxx +++ b/svx/source/svdraw/svdogrp.cxx @@ -89,6 +89,16 @@ SdrObjGroup::SdrObjGroup(SdrModel& rSdrModel, SdrObjGroup const & rSource) // copy local parameters maRefPoint = rSource.maRefPoint; + + static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES")); + if (bActivateAdvancedDiagramFeatures && rSource.getDiagramHelper()) + { + // create complete clone of current DiagramData + mp_DiagramHelper.reset(rSource.getDiagramHelper()->clone()); + + // need to set new RootShape to newly created associated XShape + mp_DiagramHelper->getRootShape() = getUnoShape(); + } } void SdrObjGroup::AddToHdlList(SdrHdlList& rHdlList) const
