include/oox/drawingml/diagram/diagram.hxx               |    3 
 include/sal/log-areas.dox                               |    1 
 include/svx/diagram/datamodel.hxx                       |   71 +++++++++++
 oox/source/drawingml/diagram/datamodel.cxx              |   87 -------------
 oox/source/drawingml/diagram/datamodel.hxx              |   71 ++---------
 oox/source/drawingml/diagram/datamodelcontext.cxx       |   12 -
 oox/source/drawingml/diagram/datamodelcontext.hxx       |    4 
 oox/source/drawingml/diagram/diagram.cxx                |    2 
 oox/source/drawingml/diagram/diagram.hxx                |   18 +-
 oox/source/drawingml/diagram/diagramfragmenthandler.cxx |    2 
 oox/source/drawingml/diagram/diagramfragmenthandler.hxx |    4 
 svx/source/diagram/datamodel.cxx                        |  101 +++++++++++++++-
 12 files changed, 212 insertions(+), 164 deletions(-)

New commits:
commit ca6d879f765dad8471d42ec736b1f4235e5b8da4
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Wed Mar 30 11:48:08 2022 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Thu Mar 31 15:29:28 2022 +0200

    Advanced Diagram support: Move class DiagramData to svx AFAP
    
    Splitted and moved parts of DiagramData class to svx as peparation
    to access from there. Done as pure virtual class so that no
    incarnations will be possible, also made the constructor protected.
    The derived class in oox hosts all functionality/data which
    involves usage/modification of oox::Shape class. That way we get
    closer to get the Diagram DataModel isloated/seperated.
    Not-yet moved is the String/Text holding data, it's still in oox.
    Moving that one will be next, that will allow to migrate quite
    some more functionalty to svx.
    
    Change-Id: I389dbf3ebf6171b8175cf30be7bbc8c20d9a38e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132303
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/include/oox/drawingml/diagram/diagram.hxx 
b/include/oox/drawingml/diagram/diagram.hxx
index fa200dd1662a..b3e79d46197c 100644
--- a/include/oox/drawingml/diagram/diagram.hxx
+++ b/include/oox/drawingml/diagram/diagram.hxx
@@ -30,9 +30,6 @@
 
 namespace oox::drawingml {
 
-class DiagramData;
-typedef std::shared_ptr<DiagramData> DiagramDataPtr;
-
 /** load diagram data, and put resulting graphic into shape
 
     This method loads the diagram data fragments from the given paths,
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index b4f90e7e50d3..b00d1c1c8236 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -391,6 +391,7 @@ certain functionality.
 
 @li @c svx
 @li @c svx.chaining
+@li @c svx.diagram - Diagram ModelData
 @li @c svx.dialog
 @li @c svx.fmcomp
 @li @c svx.form
diff --git a/include/svx/diagram/datamodel.hxx 
b/include/svx/diagram/datamodel.hxx
index 9f47e30f8ef9..d76b5c25b163 100644
--- a/include/svx/diagram/datamodel.hxx
+++ b/include/svx/diagram/datamodel.hxx
@@ -22,13 +22,15 @@
 
 #include <vector>
 #include <optional>
+#include <map>
 
 #include <svx/svxdllapi.h>
 #include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
 
 namespace svx::diagram {
 
-enum TypeConstant {
+enum SVXCORE_DLLPUBLIC TypeConstant {
     XML_none = 0,
     XML_type = 395,
     XML_asst = 680,
@@ -114,6 +116,73 @@ struct SVXCORE_DLLPUBLIC Point
 
 typedef std::vector< Point >        Points;
 
+/** The collected Diagram ModelData
+ */
+class SVXCORE_DLLPUBLIC DiagramData
+{
+public:
+    typedef std::map< OUString, Point* > PointNameMap;
+    typedef std::map< OUString, std::vector< Point* > > PointsNameMap;
+    typedef std::map< OUString, const Connection* > ConnectionNameMap;
+
+    struct SourceIdAndDepth
+    {
+        OUString msSourceId;
+        sal_Int32 mnDepth = 0;
+    };
+
+    /// Tracks connections: destination id -> {destination order, details} map.
+    typedef std::map< OUString, std::map<sal_Int32, SourceIdAndDepth > > 
StringMap;
+
+protected:
+    // Make constructor protected to signal that this anyways pure virual class
+    // shall not be incarnated - target to use is oox::drawingml::DiagramData
+    DiagramData();
+
+public:
+    virtual ~DiagramData();
+
+    // creates temporary processing data from model data
+    virtual void build(bool bClearOoxShapes) = 0;
+
+    Connections& getConnections() { return maConnections; }
+    Points& getPoints() { return maPoints; }
+    StringMap& getPresOfNameMap() { return maPresOfNameMap; }
+    PointNameMap& getPointNameMap() { return maPointNameMap; }
+    PointsNameMap& getPointsPresNameMap() { return maPointsPresNameMap; }
+    ::std::vector<OUString>& getExtDrawings() { return maExtDrawings; }
+    const Point* getRootPoint() const;
+
+    virtual void dump() const = 0;
+
+    OUString getString() const;
+    virtual std::vector<std::pair<OUString, OUString>> getChildren(const 
OUString& rParentId) const = 0;
+    virtual OUString addNode(const OUString& rText) = 0;
+    bool removeNode(const OUString& rNodeId);
+
+protected:
+    virtual void getChildrenString(OUStringBuffer& rBuf, const Point* pPoint, 
sal_Int32 nLevel) const = 0;
+    void addConnection(TypeConstant nType, const OUString& sSourceId, const 
OUString& sDestId);
+
+    // evtl. existing alternative imported visualization identifier
+    ::std::vector<OUString>  maExtDrawings;
+
+    // The model definition, the parts available in svx.
+    // See evtl. parts in oox::drawingml::DiagramData that may need t obe 
accessed
+    // - logic connections/associations
+    // - data point entries
+    Connections maConnections;
+    Points maPoints;
+
+    // temporary processing data, deleted when using build()
+    PointNameMap      maPointNameMap;
+    PointsNameMap     maPointsPresNameMap;
+    ConnectionNameMap maConnectionNameMap;
+    StringMap         maPresOfNameMap;
+};
+
+typedef std::shared_ptr< DiagramData > DiagramDataPtr;
+
 }
 
 #endif
diff --git a/oox/source/drawingml/diagram/datamodel.cxx 
b/oox/source/drawingml/diagram/datamodel.cxx
index 2e10c23e6d2e..9bd8318c8fe1 100644
--- a/oox/source/drawingml/diagram/datamodel.cxx
+++ b/oox/source/drawingml/diagram/datamodel.cxx
@@ -93,19 +93,14 @@ void 
DiagramData::secureDataFromShapeToModelAfterDiagramImport()
     // more easily.
 }
 
-DiagramData::DiagramData() :
-    mpFillProperties( std::make_shared<FillProperties>() )
+DiagramData::DiagramData()
+: svx::diagram::DiagramData()
+, mpFillProperties( std::make_shared<FillProperties>() )
 {
 }
 
-const svx::diagram::Point* DiagramData::getRootPoint() const
+DiagramData::~DiagramData()
 {
-    for (const auto & aCurrPoint : maPoints)
-        if (aCurrPoint.mnXMLType == svx::diagram::TypeConstant::XML_doc)
-            return &aCurrPoint;
-
-    SAL_WARN("oox.drawingml", "No root point");
-    return nullptr;
 }
 
 static void Connection_dump(const svx::diagram::Connection& rConnection)
@@ -175,14 +170,6 @@ void DiagramData::getChildrenString(
         getChildrenString(rBuf, pChild, nLevel + 1);
 }
 
-OUString DiagramData::getString() const
-{
-    OUStringBuffer aBuf;
-    const svx::diagram::Point* pPoint = getRootPoint();
-    getChildrenString(aBuf, pPoint, 0);
-    return aBuf.makeStringAndClear();
-}
-
 std::vector<std::pair<OUString, OUString>> DiagramData::getChildren(const 
OUString& rParentId) const
 {
     const OUString sModelId = rParentId.isEmpty() ? getRootPoint()->msModelId 
: rParentId;
@@ -210,20 +197,6 @@ std::vector<std::pair<OUString, OUString>> 
DiagramData::getChildren(const OUStri
     return aChildren;
 }
 
-void DiagramData::addConnection(svx::diagram::TypeConstant nType, const 
OUString& sSourceId, const OUString& sDestId)
-{
-    sal_Int32 nMaxOrd = -1;
-    for (const auto& aCxn : maConnections)
-        if (aCxn.mnXMLType == nType && aCxn.msSourceId == sSourceId)
-            nMaxOrd = std::max(nMaxOrd, aCxn.mnSourceOrder);
-
-    svx::diagram::Connection& rCxn = maConnections.emplace_back();
-    rCxn.mnXMLType = nType;
-    rCxn.msSourceId = sSourceId;
-    rCxn.msDestId = sDestId;
-    rCxn.mnSourceOrder = nMaxOrd + 1;
-}
-
 OUString DiagramData::addNode(const OUString& rText)
 {
     const svx::diagram::Point& rDataRoot = *getRootPoint();
@@ -287,58 +260,6 @@ OUString DiagramData::addNode(const OUString& rText)
     return sNewNodeId;
 }
 
-bool DiagramData::removeNode(const OUString& rNodeId)
-{
-    // check if it doesn't have children
-    for (const auto& aCxn : maConnections)
-        if (aCxn.mnXMLType == svx::diagram::TypeConstant::XML_parOf && 
aCxn.msSourceId == rNodeId)
-        {
-            SAL_WARN("oox.drawingml", "Node has children - can't be removed");
-            return false;
-        }
-
-    svx::diagram::Connection aParCxn;
-    for (const auto& aCxn : maConnections)
-        if (aCxn.mnXMLType == svx::diagram::TypeConstant::XML_parOf && 
aCxn.msDestId == rNodeId)
-            aParCxn = aCxn;
-
-    std::unordered_set<OUString> aIdsToRemove;
-    aIdsToRemove.insert(rNodeId);
-    if (!aParCxn.msParTransId.isEmpty())
-        aIdsToRemove.insert(aParCxn.msParTransId);
-    if (!aParCxn.msSibTransId.isEmpty())
-        aIdsToRemove.insert(aParCxn.msSibTransId);
-
-    for (const svx::diagram::Point& rPoint : maPoints)
-        if (aIdsToRemove.count(rPoint.msPresentationAssociationId))
-            aIdsToRemove.insert(rPoint.msModelId);
-
-    // insert also transition nodes
-    for (const auto& aCxn : maConnections)
-        if (aIdsToRemove.count(aCxn.msSourceId) || 
aIdsToRemove.count(aCxn.msDestId))
-            if (!aCxn.msPresId.isEmpty())
-                aIdsToRemove.insert(aCxn.msPresId);
-
-    // remove connections
-    maConnections.erase(std::remove_if(maConnections.begin(), 
maConnections.end(),
-                                       [aIdsToRemove](const 
svx::diagram::Connection& rCxn) {
-                                           return 
aIdsToRemove.count(rCxn.msSourceId) || aIdsToRemove.count(rCxn.msDestId);
-                                       }),
-                        maConnections.end());
-
-    // remove data and presentation nodes
-    maPoints.erase(std::remove_if(maPoints.begin(), maPoints.end(),
-                                  [aIdsToRemove](const svx::diagram::Point& 
rPoint) {
-                                      return 
aIdsToRemove.count(rPoint.msModelId);
-                                  }),
-                   maPoints.end());
-
-    // TODO: fix source/dest order
-
-    build(true);
-    return true;
-}
-
 #ifdef DEBUG_OOX_DIAGRAM
 OString normalizeDotName( const OUString& rStr )
 {
diff --git a/oox/source/drawingml/diagram/datamodel.hxx 
b/oox/source/drawingml/diagram/datamodel.hxx
index ab7625fa8772..eef345edb630 100644
--- a/oox/source/drawingml/diagram/datamodel.hxx
+++ b/oox/source/drawingml/diagram/datamodel.hxx
@@ -33,51 +33,23 @@
 
 namespace oox::drawingml {
 
-class DiagramData
+class DiagramData : public svx::diagram::DiagramData
 {
 public:
     typedef std::map< OUString, ShapePtr > PointShapeMap;
     typedef std::map< OUString, TextBodyPtr > PointTextMap;
-    typedef std::map< OUString, svx::diagram::Point* > PointNameMap;
-    typedef std::map< OUString, std::vector< svx::diagram::Point* > > 
PointsNameMap;
-    typedef std::map< OUString, const svx::diagram::Connection* > 
ConnectionNameMap;
-
-    struct SourceIdAndDepth
-    {
-        OUString msSourceId;
-        sal_Int32 mnDepth = 0;
-    };
-
-    /// Tracks connections: destination id -> {destination order, details} map.
-    typedef std::map< OUString, std::map<sal_Int32, SourceIdAndDepth > > 
StringMap;
 
     DiagramData();
-    virtual ~DiagramData() {}
+    virtual ~DiagramData();
 
     // creates temporary processing data from model data
-    void build(bool bClearOoxShapes);
-
-    FillPropertiesPtr & getFillProperties()
-        { return mpFillProperties; }
-    svx::diagram::Connections & getConnections()
-        { return maConnections; }
-    svx::diagram::Points & getPoints()
-        { return maPoints; }
-    StringMap & getPresOfNameMap()
-        { return maPresOfNameMap; }
-    PointNameMap & getPointNameMap()
-        { return maPointNameMap; }
-    PointsNameMap & getPointsPresNameMap()
-        { return maPointsPresNameMap; }
-    ::std::vector<OUString> &getExtDrawings()
-        { return maExtDrawings; }
-    const svx::diagram::Point* getRootPoint() const;
-    void dump() const;
-
-    OUString getString() const;
-    std::vector<std::pair<OUString, OUString>> getChildren(const OUString& 
rParentId) const;
-    OUString addNode(const OUString& rText);
-    bool removeNode(const OUString& rNodeId);
+    virtual void build(bool bClearOoxShapes);
+
+    FillPropertiesPtr& getFillProperties() { return mpFillProperties; }
+    virtual void dump() const;
+
+    virtual std::vector<std::pair<OUString, OUString>> getChildren(const 
OUString& rParentId) const;
+    virtual OUString addNode(const OUString& rText);
 
     Shape* getOrCreateAssociatedShape(const svx::diagram::Point& rPoint, bool 
bCreateOnDemand = false) const;
 
@@ -85,32 +57,23 @@ public:
     void secureDataFromShapeToModelAfterDiagramImport();
     void restoreDataFromModelToShapeAfterReCreation(const svx::diagram::Point& 
rPoint, Shape& rNewShape) const;
 
-private:
-    void getChildrenString(OUStringBuffer& rBuf, const svx::diagram::Point* 
pPoint, sal_Int32 nLevel) const;
-    void addConnection(svx::diagram::TypeConstant nType, const OUString& 
sSourceId, const OUString& sDestId);
-
-    // evtl. existing alternative imported visualization identifier
-    ::std::vector<OUString>  maExtDrawings;
+protected:
+    virtual void getChildrenString(OUStringBuffer& rBuf, const 
svx::diagram::Point* pPoint, sal_Int32 nLevel) const;
 
-    // the model definition,
+    // The model definition, the parts *only* available in oox. Also look for 
already
+    // defined ModelData in svx::diagram::DiagramData
     // - FillStyle
     // - Texts for oox::drawingml::Points/svx::diagram::Points, associated by 
ModelId
-    // - logic connections/associations
-    // - data point entries
     FillPropertiesPtr mpFillProperties;
     PointTextMap      maPointTextMap;
-    svx::diagram::Connections  maConnections;
-    svx::diagram::Points       maPoints;
 
-    // temporary processing data
+    // temporary processing data, deleted when using build()
     PointShapeMap     maPointShapeMap;
-    PointNameMap      maPointNameMap;
-    PointsNameMap     maPointsPresNameMap;
-    ConnectionNameMap maConnectionNameMap;
-    StringMap         maPresOfNameMap;
 };
 
-typedef std::shared_ptr< DiagramData > DiagramDataPtr;
+// Oox-lcal definiitkion of DiagramData. Doing and using this onm Oox
+// allows to do much less static_cast(s) - if at all  from 
svx::diagram::DiagramData
+typedef std::shared_ptr< DiagramData > OoxDiagramDataPtr;
 
 }
 
diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx 
b/oox/source/drawingml/diagram/datamodelcontext.cxx
index 35b9b213c550..5715e7d11995 100644
--- a/oox/source/drawingml/diagram/datamodelcontext.cxx
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -206,9 +206,9 @@ class PtContext
     : public ContextHandler2
 {
 public:
-    PtContext( ContextHandler2Helper const & rParent,
+    PtContext( ContextHandler2Helper const& rParent,
                const AttributeList& rAttribs,
-               svx::diagram::Point & rPoint,
+               svx::diagram::Point& rPoint,
                DiagramData& rDiagramData):
         ContextHandler2( rParent ),
         mrPoint( rPoint ),
@@ -296,7 +296,7 @@ class BackgroundFormattingContext
     : public ContextHandler2
 {
 public:
-    BackgroundFormattingContext( ContextHandler2Helper const & rParent, 
DiagramDataPtr const & pModel )
+    BackgroundFormattingContext( ContextHandler2Helper const & rParent, 
OoxDiagramDataPtr const& pModel )
         : ContextHandler2( rParent )
         , mpDataModel( pModel )
         {
@@ -329,13 +329,13 @@ public:
             return this;
         }
 private:
-    DiagramDataPtr mpDataModel;
+    OoxDiagramDataPtr mpDataModel;
 };
 
 }
 
-DataModelContext::DataModelContext( ContextHandler2Helper const & rParent,
-                                    const DiagramDataPtr & pDataModel )
+DataModelContext::DataModelContext( ContextHandler2Helper const& rParent,
+                                    const OoxDiagramDataPtr& pDataModel )
     : ContextHandler2( rParent )
     , mpDataModel( pDataModel )
 {
diff --git a/oox/source/drawingml/diagram/datamodelcontext.hxx 
b/oox/source/drawingml/diagram/datamodelcontext.hxx
index 4148a01721a4..9a5c323de875 100644
--- a/oox/source/drawingml/diagram/datamodelcontext.hxx
+++ b/oox/source/drawingml/diagram/datamodelcontext.hxx
@@ -29,13 +29,13 @@ namespace oox::drawingml {
 class DataModelContext final : public ::oox::core::ContextHandler2
 {
 public:
-    DataModelContext( ::oox::core::ContextHandler2Helper const & rParent, 
const DiagramDataPtr & pDataModelPtr );
+    DataModelContext( ::oox::core::ContextHandler2Helper const& rParent, const 
OoxDiagramDataPtr& pDataModelPtr );
     virtual ~DataModelContext() override;
 
     virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 
Element, const ::oox::AttributeList& rAttribs ) override;
 
 private:
-    DiagramDataPtr mpDataModel;
+    OoxDiagramDataPtr mpDataModel;
 };
 
 }
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index 7c83204ea6a7..070b365eea14 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -298,7 +298,7 @@ void loadDiagram( ShapePtr const & pShape,
 {
     DiagramPtr pDiagram = std::make_shared<Diagram>();
 
-    DiagramDataPtr pData = std::make_shared<DiagramData>();
+    OoxDiagramDataPtr pData = std::make_shared<DiagramData>();
     pDiagram->setData( pData );
 
     DiagramLayoutPtr pLayout = std::make_shared<DiagramLayout>(*pDiagram);
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index 0f62224812ad..f58c762f6a1a 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -66,13 +66,13 @@ public:
         { return mpNode; }
     const LayoutNodePtr & getNode() const
         { return mpNode; }
-    DiagramDataPtr & getSampData()
+    OoxDiagramDataPtr& getSampData()
         { return mpSampData; }
-    const DiagramDataPtr & getSampData() const
+    const OoxDiagramDataPtr& getSampData() const
         { return mpSampData; }
-    DiagramDataPtr & getStyleData()
+    OoxDiagramDataPtr& getStyleData()
         { return mpStyleData; }
-    const DiagramDataPtr & getStyleData() const
+    const OoxDiagramDataPtr& getStyleData() const
         { return mpStyleData; }
     LayoutAtomMap & getLayoutAtomMap()
         { return maLayoutAtomMap; }
@@ -88,8 +88,8 @@ private:
     OUString msTitle;
     OUString msDesc;
     LayoutNodePtr  mpNode;
-    DiagramDataPtr mpSampData;
-    DiagramDataPtr mpStyleData;
+    OoxDiagramDataPtr mpSampData;
+    OoxDiagramDataPtr mpStyleData;
     // TODO
     // catLst
     // clrData
@@ -129,9 +129,9 @@ class Diagram
 {
 public:
     explicit Diagram();
-    void setData( const DiagramDataPtr & pData )
+    void setData( OoxDiagramDataPtr& pData )
         { mpData = pData; }
-    const DiagramDataPtr& getData() const
+    const OoxDiagramDataPtr& getData() const
         { return mpData; }
     void setLayout( const DiagramLayoutPtr & pLayout )
         { mpLayout = pLayout; }
@@ -154,7 +154,7 @@ private:
     // This contains groups of shapes: automatic font size is the same in each 
group.
     oox::core::NamedShapePairs maDiagramFontHeights;
 
-    DiagramDataPtr                 mpData;
+    OoxDiagramDataPtr              mpData;
     DiagramLayoutPtr               mpLayout;
     DiagramQStyleMap               maStyles;
     DiagramColorMap                maColors;
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx 
b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
index 16c8de50d6f5..8ff4af7f0bfb 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -33,7 +33,7 @@ namespace oox::drawingml {
 
 DiagramDataFragmentHandler::DiagramDataFragmentHandler( XmlFilterBase& rFilter,
                                                         const OUString& 
rFragmentPath,
-                                                        const DiagramDataPtr& 
rDataPtr )
+                                                        const 
OoxDiagramDataPtr& rDataPtr )
     : FragmentHandler2( rFilter, rFragmentPath )
     , mpDataPtr( rDataPtr )
 {
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx 
b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
index f7024f4c440d..eb51d6407448 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
@@ -29,7 +29,7 @@ namespace oox::drawingml {
 class DiagramDataFragmentHandler : public ::oox::core::FragmentHandler2
 {
 public:
-    DiagramDataFragmentHandler(oox::core::XmlFilterBase& rFilter, const 
OUString& rFragmentPath, const DiagramDataPtr& rDataPtr);
+    DiagramDataFragmentHandler(oox::core::XmlFilterBase& rFilter, const 
OUString& rFragmentPath, const OoxDiagramDataPtr& rDataPtr);
     virtual ~DiagramDataFragmentHandler() noexcept override;
 
     virtual void SAL_CALL endDocument() override;
@@ -37,7 +37,7 @@ public:
 
 private:
 
-    DiagramDataPtr  mpDataPtr;
+    OoxDiagramDataPtr mpDataPtr;
 };
 
 class DiagramLayoutFragmentHandler : public ::oox::core::FragmentHandler2
diff --git a/svx/source/diagram/datamodel.cxx b/svx/source/diagram/datamodel.cxx
index 4396ef90ba1f..11b71240b6ec 100644
--- a/svx/source/diagram/datamodel.cxx
+++ b/svx/source/diagram/datamodel.cxx
@@ -17,6 +17,9 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <unordered_set>
+#include <algorithm>
+
 #include <svx/diagram/datamodel.hxx>
 #include <sal/log.hxx>
 
@@ -26,7 +29,8 @@ Connection::Connection()
 : mnXMLType( XML_none )
 , mnSourceOrder( 0 )
 , mnDestOrder( 0 )
-{}
+{
+}
 
 Point::Point()
 : mnXMLType(XML_none)
@@ -54,7 +58,100 @@ Point::Point()
 , mbCustomVerticalFlip(false)
 , mbCustomText(false)
 , mbIsPlaceholder(false)
-{}
+{
+}
+
+DiagramData::DiagramData()
+{
+}
+
+DiagramData::~DiagramData()
+{
+}
+
+const Point* DiagramData::getRootPoint() const
+{
+    for (const auto & aCurrPoint : maPoints)
+        if (aCurrPoint.mnXMLType == TypeConstant::XML_doc)
+            return &aCurrPoint;
+
+    SAL_WARN("svx.diagram", "No root point");
+    return nullptr;
+}
+
+OUString DiagramData::getString() const
+{
+    OUStringBuffer aBuf;
+    const Point* pPoint = getRootPoint();
+    getChildrenString(aBuf, pPoint, 0);
+    return aBuf.makeStringAndClear();
+}
+
+bool DiagramData::removeNode(const OUString& rNodeId)
+{
+    // check if it doesn't have children
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnXMLType == TypeConstant::XML_parOf && aCxn.msSourceId == 
rNodeId)
+        {
+            SAL_WARN("svx.diagram", "Node has children - can't be removed");
+            return false;
+        }
+
+    Connection aParCxn;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnXMLType == TypeConstant::XML_parOf && aCxn.msDestId == 
rNodeId)
+            aParCxn = aCxn;
+
+    std::unordered_set<OUString> aIdsToRemove;
+    aIdsToRemove.insert(rNodeId);
+    if (!aParCxn.msParTransId.isEmpty())
+        aIdsToRemove.insert(aParCxn.msParTransId);
+    if (!aParCxn.msSibTransId.isEmpty())
+        aIdsToRemove.insert(aParCxn.msSibTransId);
+
+    for (const Point& rPoint : maPoints)
+        if (aIdsToRemove.count(rPoint.msPresentationAssociationId))
+            aIdsToRemove.insert(rPoint.msModelId);
+
+    // insert also transition nodes
+    for (const auto& aCxn : maConnections)
+        if (aIdsToRemove.count(aCxn.msSourceId) || 
aIdsToRemove.count(aCxn.msDestId))
+            if (!aCxn.msPresId.isEmpty())
+                aIdsToRemove.insert(aCxn.msPresId);
+
+    // remove connections
+    maConnections.erase(std::remove_if(maConnections.begin(), 
maConnections.end(),
+                                       [aIdsToRemove](const Connection& rCxn) {
+                                           return 
aIdsToRemove.count(rCxn.msSourceId) || aIdsToRemove.count(rCxn.msDestId);
+                                       }),
+                        maConnections.end());
+
+    // remove data and presentation nodes
+    maPoints.erase(std::remove_if(maPoints.begin(), maPoints.end(),
+                                  [aIdsToRemove](const Point& rPoint) {
+                                      return 
aIdsToRemove.count(rPoint.msModelId);
+                                  }),
+                   maPoints.end());
+
+    // TODO: fix source/dest order
+
+    build(true);
+    return true;
+}
+
+void DiagramData::addConnection(svx::diagram::TypeConstant nType, const 
OUString& sSourceId, const OUString& sDestId)
+{
+    sal_Int32 nMaxOrd = -1;
+    for (const auto& aCxn : maConnections)
+        if (aCxn.mnXMLType == nType && aCxn.msSourceId == sSourceId)
+            nMaxOrd = std::max(nMaxOrd, aCxn.mnSourceOrder);
+
+    svx::diagram::Connection& rCxn = maConnections.emplace_back();
+    rCxn.mnXMLType = nType;
+    rCxn.msSourceId = sSourceId;
+    rCxn.msDestId = sDestId;
+    rCxn.mnSourceOrder = nMaxOrd + 1;
+}
 
 }
 

Reply via email to