include/oox/drawingml/shape.hxx                     |    6 
 include/svx/diagram/datamodel.hxx                   |   46 ++-
 include/svx/svdogrp.hxx                             |   30 ++
 oox/source/drawingml/diagram/datamodel.cxx          |  278 +++++++++++++++++++-
 oox/source/drawingml/diagram/datamodel.hxx          |   10 
 oox/source/drawingml/diagram/datamodelcontext.cxx   |    2 
 oox/source/drawingml/diagram/diagram.cxx            |   41 --
 oox/source/drawingml/diagram/diagram.hxx            |    4 
 oox/source/drawingml/diagram/diagramhelper.cxx      |   17 -
 oox/source/drawingml/diagram/diagramhelper.hxx      |    2 
 oox/source/drawingml/diagram/layoutatomvisitors.cxx |    4 
 oox/source/drawingml/shape.cxx                      |    3 
 svx/source/diagram/datamodel.cxx                    |  179 ------------
 svx/source/svdraw/svdogrp.cxx                       |    8 
 14 files changed, 383 insertions(+), 247 deletions(-)

New commits:
commit d9b3374b13108cf6b847f6eb92fb666194a68770
Author:     Armin Le Grand (Allotropia) <[email protected]>
AuthorDate: Tue Apr 19 11:37:57 2022 +0200
Commit:     Armin Le Grand <[email protected]>
CommitDate: Wed Apr 20 09:32:52 2022 +0200

    Advanced Diagram support: Use better association Model<->XShape
    
    To have a more direct and more reliable association between the
    XShape/oox::Shape and the model data svx::diagram::Point I added
    optional usage of the Model-UUID for that at the oox::Shape.
    Also added a 'fake' UUID to work with the BackgroundShape's
    attributes. Changed all preserve/rescue code to work based on that.
    
    Also cleanups/comments and preparations of some flags in the
    Diagram ModelData to steer behaviour on re-ceration.
    
    Change-Id: Ie30effdff34dcdbbc79a766de09157b2a3bd97d3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133168
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <[email protected]>

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index a16e65a71ef1..3d0ee6ebaec8 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -118,6 +118,9 @@ public:
     OUString&                  getServiceName(){ return msServiceName; }
     void                            setServiceName( const char* pServiceName );
 
+    const OUString& getDiagramDataModelID() const { return 
msDiagramDataModelID; }
+    void setDiagramDataModelID( const OUString& rDiagramDataModelID ) { 
msDiagramDataModelID = rDiagramDataModelID; }
+
     PropertyMap&                    getShapeProperties(){ return 
maShapeProperties; }
 
     LineProperties&          getLineProperties() { return 
*mpLinePropertiesPtr; }
@@ -408,6 +411,9 @@ private:
     // temporary space for DiagramHelper in preparation for collecting data
     // Note: I tried to use a unique_ptr here, but existing constructor func 
does not allow that
     IDiagramHelper* mpDiagramHelper;
+
+    // association-ID to identify the Diagram ModelData
+    OUString msDiagramDataModelID;
 };
 
 }
diff --git a/include/svx/diagram/datamodel.hxx 
b/include/svx/diagram/datamodel.hxx
index 686835ee378f..7a080f8703ee 100644
--- a/include/svx/diagram/datamodel.hxx
+++ b/include/svx/diagram/datamodel.hxx
@@ -28,7 +28,6 @@
 #include <rtl/ustring.hxx>
 #include <rtl/ustrbuf.hxx>
 
-#include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/xml/dom/XDocument.hpp>
 #include <com/sun/star/drawing/XShape.hpp>
 
@@ -73,9 +72,7 @@ typedef std::vector< Connection > Connections;
 /** Text and properties for a point
  * For proof of concept to make TextData available in svx level this
  * is in a first run pretty simple, but may need to be extended accordingly
- * up to similar data as in oox::drawingml::TextBody. Pls have a look at
- * secureDataFromShapeToModelAfterDiagramImport() resp.
- * restoreDataFromModelToShapeAfterReCreation() on it's usage/purpose
+ * up to similar data as in oox::drawingml::TextBody.
  */
 struct SVXCORE_DLLPUBLIC TextBody
 {
@@ -104,7 +101,13 @@ struct SVXCORE_DLLPUBLIC Point
 {
     Point();
 
+    // The minimal text data from the imported Diagram
+    // in source format
     TextBodyPtr msTextBody;
+
+    // The property sequence of pairs<OUString, css::uno::Any>,
+    // interpreted & assigned by the ::addShape(s) creators in the
+    // import filter that created a XShape associated/based on this entry
     PointStylePtr msPointStylePtr;
 
     OUString msCnxId;
@@ -147,9 +150,6 @@ struct SVXCORE_DLLPUBLIC Point
     bool          mbCustomVerticalFlip;
     bool          mbCustomText;
     bool          mbIsPlaceholder;
-
-    void securePropertiesFromXShape(const css::uno::Reference< 
css::drawing::XShape >& rXShape);
-    void restorePropertiesToXShape(const css::uno::Reference< 
css::drawing::XShape >& rXShape) const;
 };
 
 typedef std::vector< Point >        Points;
@@ -183,6 +183,10 @@ public:
     // creates temporary processing data from model data
     virtual void buildDiagramDataModel(bool bClearOoxShapes);
 
+    // dump to readable format
+    virtual void dump() const = 0;
+
+    // read accesses
     Connections& getConnections() { return maConnections; }
     Points& getPoints() { return maPoints; }
     StringMap& getPresOfNameMap() { return maPresOfNameMap; }
@@ -190,18 +194,21 @@ public:
     PointsNameMap& getPointsPresNameMap() { return maPointsPresNameMap; }
     ::std::vector<OUString>& getExtDrawings() { return maExtDrawings; }
     const Point* getRootPoint() const;
-
-    virtual void dump() const = 0;
-
     OUString getString() const;
     std::vector<std::pair<OUString, OUString>> getChildren(const OUString& 
rParentId) const;
-    OUString addNode(const OUString& rText);
-    bool removeNode(const OUString& rNodeId);
 
     const css::uno::Reference< css::xml::dom::XDocument >& getThemeDocument() 
const { return mxThemeDocument; }
     void setThemeDocument( const css::uno::Reference< css::xml::dom::XDocument 
>& xRef ) { mxThemeDocument = xRef; }
 
+    const OUString& getBackgroundShapeModelID() const { return 
msBackgroundShapeModelID; }
+    void setBackgroundShapeModelID( const OUString& rModelID ) { 
msBackgroundShapeModelID = rModelID; }
+
+    // model modifiers
+    OUString addNode(const OUString& rText);
+    bool removeNode(const OUString& rNodeId);
+
 protected:
+    // helpers
     void getChildrenString(OUStringBuffer& rBuf, const Point* pPoint, 
sal_Int32 nLevel) const;
     void addConnection(TypeConstant nType, const OUString& sSourceId, const 
OUString& sDestId);
 
@@ -211,22 +218,31 @@ protected:
     // The model definition, the parts available in svx.
     // See evtl. parts in oox::drawingml::DiagramData that may need t obe 
accessed
     // - logic connections/associations
+    Connections maConnections;
+
     // - data point entries
+    Points maPoints;
+
+    // - style for the BackgroundShape (if used)
+    //   this is the property sequence of pairs<OUString, css::uno::Any>,
+    //   as interpreted & assigned by the ::addShape(s) creators in the
+    //   import filter
+    PointStylePtr maBackgroundShapeStyle;
+
     // - Theme definition as css::xml::dom::XDocument
     //    Note: I decided to use dom::XDocument which is already in use, 
instead of a
     //          temp file what is also possible (implemented that for POC) but 
would
     //          need to be created in 
PresentationFragmentHandler::importSlide. If
     //          this needs to be written to a File, please refer to
     //          fileDocxExport::WriteTheme(), look for "OOXTheme"
-    Connections maConnections;
-    Points maPoints;
     css::uno::Reference< css::xml::dom::XDocument > mxThemeDocument;
 
-    // temporary processing data, deleted when using build()
+    // temporary processing data, partially deleted when using build()
     PointNameMap      maPointNameMap;
     PointsNameMap     maPointsPresNameMap;
     ConnectionNameMap maConnectionNameMap;
     StringMap         maPresOfNameMap;
+    OUString          msBackgroundShapeModelID;
 };
 
 typedef std::shared_ptr< DiagramData > DiagramDataPtr;
diff --git a/include/svx/svdogrp.hxx b/include/svx/svdogrp.hxx
index 176892fdd8ac..b6fb1b74e4c2 100644
--- a/include/svx/svdogrp.hxx
+++ b/include/svx/svdogrp.hxx
@@ -32,6 +32,32 @@ class SdrObjGroup;
 // data and functionality
 class SVXCORE_DLLPUBLIC IDiagramHelper
 {
+private:
+    // These values define behaviour to where take data from at re-creation 
time.
+    // Different definitions will have different consequences for re-creation
+    // of Diagram visualization (if needed/triggered).
+    // The style attributes per shape e.g. can be re-stored frm either an
+    // existing Theme, or the preserved key/value list of properties per 
XShape.
+    // With the current default settings the re-ceation uses the preserved
+    // key/value pairs, but re-creation from Theme may also be desirable. It
+    // is also good to preserve both data packages at initial import to allow
+    // alternatively one of these two methods for re-construction
+
+    // If true, the oox::Theme data from ::DiagramData get/set/ThemeDocument()
+    // aka mxThemeDocument - if it exists - will be used to create the style
+    // attributes for the to-be-created XShapes (theoretically allows 
re-creation
+    // with other Theme)
+    bool mbUseDiagramThemeData; // false
+
+    // If true, the UNO API form of attributes per Point as Key/value list
+    // that was secured after initial XShape creation is used to create the
+    // style attributes for the to-be-created XShapes
+    bool mbUseDiagramModelData; // true
+
+    // If true and mxThemeDocument exists it will be re-imported to
+    // a newly created oox::drawingml::Theme object
+    bool mbForceThemePtrReceation; // false
+
 protected:
     void anchorToSdrObjGroup(SdrObjGroup& rTarget);
 
@@ -54,6 +80,10 @@ public:
     // add/remove new top-level node to data model, returns its id
     virtual OUString addNode(const OUString& rText) = 0;
     virtual bool removeNode(const OUString& rNodeId) = 0;
+
+    bool UseDiagramThemeData() const { return mbUseDiagramThemeData; }
+    bool UseDiagramModelData() const { return mbUseDiagramModelData; }
+    bool ForceThemePtrReceation() const { return mbForceThemePtrReceation; };
 };
 
 //   SdrObjGroup
diff --git a/oox/source/drawingml/diagram/datamodel.cxx 
b/oox/source/drawingml/diagram/datamodel.cxx
index f0a3cef66903..bbe23041cf28 100644
--- a/oox/source/drawingml/diagram/datamodel.cxx
+++ b/oox/source/drawingml/diagram/datamodel.cxx
@@ -26,6 +26,10 @@
 #include <drawingml/textparagraph.hxx>
 #include <drawingml/textrun.hxx>
 #include <oox/drawingml/shape.hxx>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <editeng/unoprnms.hxx>
 
 #include <unordered_set>
 
@@ -60,7 +64,7 @@ void 
DiagramData::restoreDataFromModelToShapeAfterReCreation(const svx::diagram:
     // available data from the Diagram ModelData to it as preparation
 
     // This is e.g. the Text, but may get more (styles?)
-    if(rPoint.msTextBody && !rPoint.msTextBody->msText.isEmpty())
+    if(!rPoint.msTextBody->msText.isEmpty())
     {
         TextBodyPtr aNewTextBody(std::make_shared<TextBody>());
         rNewShape.setTextBody(aNewTextBody);
@@ -82,8 +86,199 @@ void 
DiagramData::restoreDataFromModelToShapeAfterReCreation(const svx::diagram:
     }
 }
 
-void DiagramData::secureDataFromShapeToModelAfterDiagramImport()
+static void addProperty(const OUString& rName,
+    const css::uno::Reference< css::beans::XPropertySetInfo >& xInfo,
+    std::vector< std::pair< OUString, css::uno::Any >>& rTarget,
+    const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
 {
+    if(xInfo->hasPropertyByName(rName))
+            rTarget.push_back(std::pair(OUString(rName), 
xPropSet->getPropertyValue(rName)));
+}
+
+void DiagramData::secureStyleDataFromShapeToModel(::oox::drawingml::Shape& 
rShape)
+{
+    const std::vector< ShapePtr >& rChildren(rShape.getChildren());
+
+    if(!rChildren.empty())
+    {
+        // group shape
+        for (auto& child : rChildren)
+        {
+            secureStyleDataFromShapeToModel(*child);
+        }
+
+        // if group shape we are done. Do not secure properties for group 
shapes
+        return;
+    }
+
+    // we need a XShape
+    const css::uno::Reference< css::drawing::XShape > 
&rXShape(rShape.getXShape());
+    if(!rXShape)
+        return;
+
+    // we need a ModelID for association
+    if(rShape.getDiagramDataModelID().isEmpty())
+        return;
+
+    // define target to save to
+    svx::diagram::PointStyle* pTarget(nullptr);
+    const bool bIsBackgroundShape(rShape.getDiagramDataModelID() == 
msBackgroundShapeModelID);
+
+    if(bIsBackgroundShape)
+    {
+        // if BackgroundShape, create properties & set as target
+        if(!maBackgroundShapeStyle)
+            maBackgroundShapeStyle = std::make_shared< 
svx::diagram::PointStyle >();
+        pTarget = maBackgroundShapeStyle.get();
+    }
+    else
+    {
+        // if Shape, seek association
+        for (auto & point : maPoints)
+        {
+            if(point.msModelId == rShape.getDiagramDataModelID())
+            {
+                // found - create properties & set as target
+                pTarget = point.msPointStylePtr.get();
+
+                // we are done, there is no 2nd shape with the same ModelID by 
definition
+                break;
+            }
+        }
+    }
+
+    // no target -> nothing to do
+    if(nullptr == pTarget)
+        return;
+
+#ifdef DBG_UTIL
+    // to easier decide which additional properties may/should be preserved,
+    // create a full list of set properties to browse/decide (in debugger)
+    const css::uno::Reference< css::beans::XPropertyState > 
xAllPropStates(rXShape, css::uno::UNO_QUERY);
+    const css::uno::Reference< css::beans::XPropertySet > xAllPropSet( 
rXShape, css::uno::UNO_QUERY );
+    const css::uno::Sequence< css::beans::Property > 
allSequence(xAllPropSet->getPropertySetInfo()->getProperties());
+    std::vector< std::pair< OUString, css::uno::Any >> allSetProps;
+    for (auto& rProp : allSequence)
+    {
+        try
+        {
+            if (xAllPropStates->getPropertyState(rProp.Name) == 
css::beans::PropertyState::PropertyState_DIRECT_VALUE)
+            {
+                css::uno::Any 
aValue(xAllPropSet->getPropertyValue(rProp.Name));
+                if(aValue.hasValue())
+                    allSetProps.push_back(std::pair(rProp.Name, aValue));
+            }
+        }
+        catch (...)
+        {
+        }
+    }
+#endif
+
+    const css::uno::Reference< css::beans::XPropertySet > xPropSet( rXShape, 
css::uno::UNO_QUERY );
+    if(!xPropSet)
+        return;
+
+    const css::uno::Reference< css::lang::XServiceInfo > xServiceInfo( 
rXShape, css::uno::UNO_QUERY );
+    if(!xServiceInfo)
+        return;
+
+    const css::uno::Reference< css::beans::XPropertySetInfo > 
xInfo(xPropSet->getPropertySetInfo());
+    if (!xInfo.is())
+        return;
+
+    // Note: The Text may also be secured here, so it may also be possible to
+    // secure/store it at PointStyle instead of at TextBody, same maybe 
evaluated
+    // for the text attributes - where when securing here the attributes would 
be
+    // in our UNO API format already.
+    // if(xServiceInfo->supportsService("com.sun.star.drawing.Text"))
+    // {
+    //     css::uno::Reference< css::text::XText > xText(rXShape, 
css::uno::UNO_QUERY);
+    //     const OUString aText(xText->getString());
+    //
+    //     if(!aText.isEmpty())
+    //     {
+    //     }
+    // }
+
+    // Add all kinds of properties that are needed to re-create the XShape.
+    // For now this is a minimal example-selection, it will need to be extended
+    // over time for all kind of cases/properties
+
+    // text properties
+    if(!bIsBackgroundShape
+        && 
xServiceInfo->supportsService("com.sun.star.drawing.TextProperties"))
+    {
+        addProperty(UNO_NAME_CHAR_COLOR, xInfo, pTarget->maProperties, 
xPropSet);
+        addProperty(UNO_NAME_CHAR_HEIGHT, xInfo, pTarget->maProperties, 
xPropSet);
+        addProperty(UNO_NAME_CHAR_SHADOWED, xInfo, pTarget->maProperties, 
xPropSet);
+        addProperty(UNO_NAME_CHAR_WEIGHT, xInfo, pTarget->maProperties, 
xPropSet);
+    }
+
+    // fill properties
+    if(xServiceInfo->supportsService("com.sun.star.drawing.FillProperties"))
+    {
+        css::drawing::FillStyle eFillStyle(css::drawing::FillStyle_NONE);
+        if (xInfo->hasPropertyByName(UNO_NAME_FILLSTYLE))
+            xPropSet->getPropertyValue(UNO_NAME_FILLSTYLE) >>= eFillStyle;
+
+        if(css::drawing::FillStyle_NONE != eFillStyle)
+        {
+            addProperty(UNO_NAME_FILLSTYLE, xInfo, pTarget->maProperties, 
xPropSet);
+
+            switch(eFillStyle)
+            {
+                case css::drawing::FillStyle_SOLID:
+                {
+                    addProperty(UNO_NAME_FILLCOLOR, xInfo, 
pTarget->maProperties, xPropSet);
+                    break;
+                }
+                default:
+                case css::drawing::FillStyle_NONE:
+                case css::drawing::FillStyle_GRADIENT:
+                case css::drawing::FillStyle_HATCH:
+                case css::drawing::FillStyle_BITMAP:
+                    break;
+            }
+        }
+    }
+
+    // line properties
+    if(!bIsBackgroundShape
+        && 
xServiceInfo->supportsService("com.sun.star.drawing.LineProperties"))
+    {
+        css::drawing::LineStyle eLineStyle(css::drawing::LineStyle_NONE);
+        if (xInfo->hasPropertyByName(UNO_NAME_LINESTYLE))
+            xPropSet->getPropertyValue(UNO_NAME_LINESTYLE) >>= eLineStyle;
+
+        if(css::drawing::LineStyle_NONE != eLineStyle)
+        {
+            addProperty(UNO_NAME_LINESTYLE, xInfo, pTarget->maProperties, 
xPropSet);
+            addProperty(UNO_NAME_LINECOLOR, xInfo, pTarget->maProperties, 
xPropSet);
+            addProperty(UNO_NAME_LINEWIDTH, xInfo, pTarget->maProperties, 
xPropSet);
+
+            switch(eLineStyle)
+            {
+                case css::drawing::LineStyle_SOLID:
+                    break;
+                default:
+                case css::drawing::LineStyle_NONE:
+                case css::drawing::LineStyle_DASH:
+                    break;
+            }
+        }
+    }
+}
+
+void 
DiagramData::secureDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape&
 rRootShape)
+{
+    const std::vector< ShapePtr >& rChildren(rRootShape.getChildren());
+
+    for (auto& child : rChildren)
+    {
+        secureStyleDataFromShapeToModel(*child);
+    }
+
     // After Diagram import, parts of the Diagram ModelData is at the
     // oox::drawingml::Shape. Since these objects are temporary helpers,
     // secure that data at the Diagram ModelData by copying.
@@ -97,7 +292,6 @@ void 
DiagramData::secureDataFromShapeToModelAfterDiagramImport()
         {
             if(pShapeCandidate->getTextBody() && 
!pShapeCandidate->getTextBody()->isEmpty())
             {
-                point.msTextBody = std::make_shared<svx::diagram::TextBody>();
                 point.msTextBody->msText = 
pShapeCandidate->getTextBody()->toString();
 
                 const uno::Sequence< beans::PropertyValue > aTextProps(
@@ -129,9 +323,85 @@ void 
DiagramData::secureDataFromShapeToModelAfterDiagramImport()
     }
 }
 
+void DiagramData::restoreStyleDataFromShapeToModel(::oox::drawingml::Shape& 
rShape)
+{
+    const std::vector< ShapePtr >& rChildren(rShape.getChildren());
+
+    if(!rChildren.empty())
+    {
+        // group shape
+        for (auto& child : rChildren)
+        {
+            restoreStyleDataFromShapeToModel(*child);
+        }
+
+        // if group shape we are done. Do not restore properties for group 
shapes
+        return;
+    }
+
+    // we need a XShape
+    const css::uno::Reference< css::drawing::XShape > 
&rXShape(rShape.getXShape());
+    if(!rXShape)
+        return;
+
+    // we need a ModelID for association
+    if(rShape.getDiagramDataModelID().isEmpty())
+        return;
+
+    // define source to save to
+    svx::diagram::PointStyle* pSource(nullptr);
+
+    if(rShape.getDiagramDataModelID() == msBackgroundShapeModelID)
+    {
+        // if BackgroundShape, set BackgroundShapeStyle as source
+        if(maBackgroundShapeStyle)
+            pSource = maBackgroundShapeStyle.get();
+    }
+    else
+    {
+        // if Shape, seek association
+        for (auto & point : maPoints)
+        {
+            if(point.msModelId == rShape.getDiagramDataModelID())
+            {
+                // found - create properties & set as source
+                pSource = point.msPointStylePtr.get();
+
+                // we are done, there is no 2nd shape with the same ModelID by 
definition
+                break;
+            }
+        }
+    }
+
+    // no source -> nothing to do
+    if(nullptr == pSource)
+        return;
+
+    // get target  ProperySet of new XShape
+    css::uno::Reference<css::beans::XPropertySet> xPropSet(rXShape, 
css::uno::UNO_QUERY);
+    if(!xPropSet)
+        return;
+
+    // apply properties
+    for (auto const& prop : pSource->maProperties)
+    {
+        xPropSet->setPropertyValue(prop.first, prop.second);
+    }
+}
+
+void 
DiagramData::restoreDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape&
 rRootShape)
+{
+    const std::vector< ShapePtr >& rChildren(rRootShape.getChildren());
+
+    for (auto& child : rChildren)
+    {
+        restoreStyleDataFromShapeToModel(*child);
+    }
+}
+
 DiagramData::DiagramData()
 : svx::diagram::DiagramData()
-, mpBackgroundFillProperties( std::make_shared<FillProperties>() )
+, mpBackgroundShapeFillProperties( std::make_shared<FillProperties>() )
 {
 }
 
diff --git a/oox/source/drawingml/diagram/datamodel.hxx 
b/oox/source/drawingml/diagram/datamodel.hxx
index f7402cb0681e..21137f6e05d2 100644
--- a/oox/source/drawingml/diagram/datamodel.hxx
+++ b/oox/source/drawingml/diagram/datamodel.hxx
@@ -44,21 +44,25 @@ public:
     // creates temporary processing data from model data
     virtual void buildDiagramDataModel(bool bClearOoxShapes);
 
-    FillPropertiesPtr& getBackgroundFillProperties() { return 
mpBackgroundFillProperties; }
+    FillPropertiesPtr& getBackgroundShapeFillProperties() { return 
mpBackgroundShapeFillProperties; }
     virtual void dump() const;
 
     Shape* getOrCreateAssociatedShape(const svx::diagram::Point& rPoint, bool 
bCreateOnDemand = false) const;
 
     // get/set data between Diagram DataModel and oox::drawingml::Shape
-    void secureDataFromShapeToModelAfterDiagramImport();
+    void secureDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& 
rRootShape);
+    void 
restoreDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& 
rRootShape);
     static void restoreDataFromModelToShapeAfterReCreation(const 
svx::diagram::Point& rPoint, Shape& rNewShape);
 
 protected:
+    void secureStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape);
+    void restoreStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape);
+
     // The model definition, the parts *only* available in oox. Also look for 
already
     // defined ModelData in svx::diagram::DiagramData
 
     // - FillStyle for Diagram Background (empty constructed, may stay empty)
-    FillPropertiesPtr mpBackgroundFillProperties;
+    FillPropertiesPtr mpBackgroundShapeFillProperties;
 
     // temporary processing data, deleted when using build(). Association
     // map between oox::drawingml::Shape and svx::diagram::Point ModelData
diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx 
b/oox/source/drawingml/diagram/datamodelcontext.cxx
index 97484c992ad3..4f0e3f047233 100644
--- a/oox/source/drawingml/diagram/datamodelcontext.cxx
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -317,7 +317,7 @@ public:
             case A_TOKEN( solidFill ):
                 // EG_FillProperties
                 return FillPropertiesContext::createFillContext(
-                    *this, aElementToken, rAttribs, 
*mpDataModel->getBackgroundFillProperties() );
+                    *this, aElementToken, rAttribs, 
*mpDataModel->getBackgroundShapeFillProperties() );
             case A_TOKEN( effectDag ):
             case A_TOKEN( effectLst ):
                 // TODO
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index 56b9b791e022..2ccc67805945 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -35,6 +35,7 @@
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <svx/svdpage.hxx>
 #include <oox/ppt/pptimport.hxx>
+#include <comphelper/xmltools.hxx>
 
 #include "diagramlayoutatoms.hxx"
 #include "layoutatomvisitors.hxx"
@@ -103,39 +104,6 @@ static void removeUnneededGroupShapes(const ShapePtr& 
pShape)
     }
 }
 
-void DiagramLayout::secureDataFromXShapeToModelAfterDiagramImport()
-{
-    // maPresPointShapeMap types: < const svx::diagram::Point*, ShapePtr >
-    for (const auto& pEntry : maPresPointShapeMap)
-    {
-        if(nullptr != pEntry.first && pEntry.second)
-        {
-            const css::uno::Reference< css::drawing::XShape >& 
rXShape(pEntry.second->getXShape());
-
-            if(rXShape)
-            {
-                
const_cast<svx::diagram::Point*>(pEntry.first)->securePropertiesFromXShape(rXShape);
-            }
-        }
-    }
-}
-
-void DiagramLayout::restoreDataFromModelToXShapeAfterDiagramReCreate()
-{
-    // maPresPointShapeMap types: < const svx::diagram::Point*, ShapePtr >
-    for (const auto& pEntry : maPresPointShapeMap)
-    {
-        if(nullptr != pEntry.first && pEntry.second)
-        {
-            const css::uno::Reference< css::drawing::XShape >& 
rXShape(pEntry.second->getXShape());
-
-            if(rXShape)
-            {
-                pEntry.first->restorePropertiesToXShape(rXShape);
-            }
-        }
-    }
-}
 
 void Diagram::addTo( const ShapePtr & pParentShape )
 {
@@ -165,8 +133,13 @@ void Diagram::addTo( const ShapePtr & pParentShape )
     pBackground->setSubType(XML_rect);
     pBackground->getCustomShapeProperties()->setShapePresetType(XML_rect);
     pBackground->setSize(pParentShape->getSize());
-    pBackground->getFillProperties() = *mpData->getBackgroundFillProperties();
+    pBackground->getFillProperties() = 
*mpData->getBackgroundShapeFillProperties();
     pBackground->setLocked(true);
+
+    // create and set ModelID for BackgroundShape to allow later association
+    
getData()->setBackgroundShapeModelID(OStringToOUString(comphelper::xml::generateGUIDString(),
 RTL_TEXTENCODING_UTF8));
+    pBackground->setDiagramDataModelID(getData()->getBackgroundShapeModelID());
+
     auto& aChildren = pParentShape->getChildren();
     aChildren.insert(aChildren.begin(), pBackground);
 }
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index 43516d4a270d..f58c762f6a1a 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -79,10 +79,6 @@ public:
     PresPointShapeMap & getPresPointShapeMap()
         { return maPresPointShapeMap; }
 
-    // get/set data between Diagram DataModel and oox::drawingml::Shape
-    void secureDataFromXShapeToModelAfterDiagramImport();
-    void restoreDataFromModelToXShapeAfterDiagramReCreate();
-
 private:
     Diagram& mrDgm;
     OUString msDefStyle;
diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx 
b/oox/source/drawingml/diagram/diagramhelper.cxx
index 6dc991149b01..2ee9e64f2535 100644
--- a/oox/source/drawingml/diagram/diagramhelper.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper.cxx
@@ -103,8 +103,7 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
 
     // set oox::Theme at Filter. All LineStyle/FillStyle/Colors/Attributes
     // will be taken from there
-    static bool bUseDiagramThemeData(false);
-    if(bUseDiagramThemeData)
+    if(UseDiagramThemeData())
         xFilter->setCurrentTheme(getOrCreateThemePtr(xFilter));
 
     css::uno::Reference< css::lang::XComponent > aComponentModel( rUnoModel, 
uno::UNO_QUERY );
@@ -132,9 +131,8 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
     mpDiagramPtr->syncDiagramFontHeights();
 
     // re-apply secured data from ModelData
-    static bool bUseDiagramModelData(true);
-    if(bUseDiagramModelData)
-        
mpDiagramPtr->getLayout()->restoreDataFromModelToXShapeAfterDiagramReCreate();
+    if(UseDiagramModelData())
+        
mpDiagramPtr->getData()->restoreDataFromShapeToModelAfterDiagramImport(*pShapePtr);
 
     // Re-apply remembered geometry
     rTarget.TRSetBaseGeometry(aTransformation, aPolyPolygon);
@@ -200,7 +198,7 @@ bool AdvancedDiagramHelper::removeNode(const OUString& 
rNodeId)
     return bRetval;
 }
 
-void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
+void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget, 
::oox::drawingml::Shape& rRootShape)
 {
     if(!mpDiagramPtr)
     {
@@ -212,8 +210,7 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
     // After Diagram import, parts of the Diagram ModelData is at the
     // oox::drawingml::Shape. Since these objects are temporary helpers,
     // secure that data at the Diagram ModelData by copying.
-    mpDiagramPtr->getData()->secureDataFromShapeToModelAfterDiagramImport();
-    mpDiagramPtr->getLayout()->secureDataFromXShapeToModelAfterDiagramImport();
+    
mpDiagramPtr->getData()->secureDataFromShapeToModelAfterDiagramImport(rRootShape);
 
     anchorToSdrObjGroup(rTarget);
 }
@@ -221,11 +218,9 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
 std::shared_ptr< ::oox::drawingml::Theme > 
AdvancedDiagramHelper::getOrCreateThemePtr(
     rtl::Reference< oox::shape::ShapeFilterBase >& rxFilter) const
 {
-    static bool bForceThemePtrReceation(false);
-
     // (Re-)Use already existing Theme if existing/imported if possible.
     // If not, re-import Theme if data is available and thus possible
-    if(hasDiagramData() && (bForceThemePtrReceation || !mpThemePtr))
+    if(hasDiagramData() && (ForceThemePtrReceation() || !mpThemePtr))
     {
         // get the originally imported dom::XDocument
         const uno::Reference< css::xml::dom::XDocument >& 
xThemeDocument(mpDiagramPtr->getData()->getThemeDocument());
diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx 
b/oox/source/drawingml/diagram/diagramhelper.hxx
index d8fd46ce57a1..cede1aeeccf9 100644
--- a/oox/source/drawingml/diagram/diagramhelper.hxx
+++ b/oox/source/drawingml/diagram/diagramhelper.hxx
@@ -73,7 +73,7 @@ public:
     virtual OUString addNode(const OUString& rText) override;
     virtual bool removeNode(const OUString& rNodeId) override;
 
-    void doAnchor(SdrObjGroup& rTarget);
+    void doAnchor(SdrObjGroup& rTarget, ::oox::drawingml::Shape& rRootShape);
     std::shared_ptr< ::oox::drawingml::Theme > getOrCreateThemePtr(
         rtl::Reference< oox::shape::ShapeFilterBase>& rxFilter ) const;
 };
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx 
b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 927c869a9c38..45f85f808458 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -183,6 +183,10 @@ void ShapeTemplateVisitor::visit(ShapeAtom& rAtom)
     // Fill properties have to be changed as sometimes only the presentation 
node contains the blip
     // fill, unshare those.
     mpShape->cloneFillProperties();
+
+    // add/set ModelID from currrent node to allow later association
+    if (mpCurrentNode)
+        mpShape->setDiagramDataModelID(mpCurrentNode->msModelId);
 }
 
 void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom)
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 12eb72d40542..64ff93fc9bec 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -193,6 +193,7 @@ Shape::Shape( const ShapePtr& pSourceShape )
 , mfAspectRatio(pSourceShape->mfAspectRatio)
 , mbUseBgFill(pSourceShape->mbUseBgFill)
 , mpDiagramHelper( nullptr )
+, msDiagramDataModelID(pSourceShape->msDiagramDataModelID)
 {}
 
 Shape::~Shape()
@@ -225,7 +226,7 @@ void Shape::propagateDiagramHelper()
 
         if(pAnchorObj)
         {
-            
static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->doAnchor(*pAnchorObj);
+            
static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->doAnchor(*pAnchorObj, 
*this);
             mpDiagramHelper = nullptr;
         }
     }
diff --git a/svx/source/diagram/datamodel.cxx b/svx/source/diagram/datamodel.cxx
index 44e9977326a0..fd562645eaa0 100644
--- a/svx/source/diagram/datamodel.cxx
+++ b/svx/source/diagram/datamodel.cxx
@@ -23,15 +23,6 @@
 
 #include <svx/diagram/datamodel.hxx>
 #include <comphelper/xmltools.hxx>
-#include <com/sun/star/uno/Reference.hxx>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/beans/XPropertyState.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/drawing/FillStyle.hpp>
-#include <com/sun/star/drawing/LineStyle.hpp>
-#include <com/sun/star/text/XText.hpp>
-
-#include <editeng/unoprnms.hxx>
 #include <sal/log.hxx>
 
 namespace svx::diagram {
@@ -44,7 +35,9 @@ Connection::Connection()
 }
 
 Point::Point()
-: mnXMLType(XML_none)
+: msTextBody(std::make_shared< TextBody >())
+, msPointStylePtr(std::make_shared< PointStyle >())
+, mnXMLType(XML_none)
 , mnMaxChildren(-1)
 , mnPreferredChildren(-1)
 , mnDirection(XML_norm)
@@ -72,163 +65,6 @@ Point::Point()
 {
 }
 
-static void addProperty(const OUString& rName,
-    const css::uno::Reference< css::beans::XPropertySetInfo >& xInfo,
-    std::vector< std::pair< OUString, css::uno::Any >>& rTarget,
-    const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
-{
-    if(xInfo->hasPropertyByName(rName))
-            rTarget.push_back(std::pair(OUString(rName), 
xPropSet->getPropertyValue(rName)));
-}
-
-void Point::securePropertiesFromXShape(const css::uno::Reference< 
css::drawing::XShape >& rXShape)
-{
-    if(!rXShape)
-        return;
-
-#ifdef DBG_UTIL
-    // to easier decide which additional properties may/should be preserved,
-    // create a full list of set properties to browse/decide (in debugger)
-    const css::uno::Reference< css::beans::XPropertyState > 
xAllPropStates(rXShape, css::uno::UNO_QUERY);
-    const css::uno::Reference< css::beans::XPropertySet > xAllPropSet( 
rXShape, css::uno::UNO_QUERY );
-    const css::uno::Sequence< css::beans::Property > 
allSequence(xAllPropSet->getPropertySetInfo()->getProperties());
-    std::vector< std::pair< OUString, css::uno::Any >> allSetProps;
-    for (auto& rProp : allSequence)
-    {
-        try
-        {
-            if (xAllPropStates->getPropertyState(rProp.Name) == 
css::beans::PropertyState::PropertyState_DIRECT_VALUE)
-            {
-                css::uno::Any 
aValue(xAllPropSet->getPropertyValue(rProp.Name));
-                if(aValue.hasValue())
-                    allSetProps.push_back(std::pair(rProp.Name, aValue));
-            }
-        }
-        catch (...)
-        {
-        }
-    }
-#endif
-
-    const css::uno::Reference< css::beans::XPropertySet > xPropSet( rXShape, 
css::uno::UNO_QUERY );
-    if(!xPropSet)
-        return;
-
-    const css::uno::Reference< css::lang::XServiceInfo > xServiceInfo( 
rXShape, css::uno::UNO_QUERY );
-    if(!xServiceInfo)
-        return;
-
-    const css::uno::Reference< css::beans::XPropertySetInfo > 
xInfo(xPropSet->getPropertySetInfo());
-    if (!xInfo.is())
-        return;
-
-    if(!msPointStylePtr)
-        msPointStylePtr = std::make_shared< svx::diagram::PointStyle >();
-
-    // shortcut to target
-    std::vector< std::pair< OUString, css::uno::Any >>& 
rTarget(msPointStylePtr->maProperties);
-
-    // Note: The Text may also be secured here, so it may also be possible to
-    // secure/store it at PointStyle instead of at TextBody, same maybe 
evaluated
-    // for the text attributes - where when securing here the attributes would 
be
-    // in our UNO API format already.
-    // if(xServiceInfo->supportsService("com.sun.star.drawing.Text"))
-    // {
-    //     css::uno::Reference< css::text::XText > xText(rXShape, 
css::uno::UNO_QUERY);
-    //     const OUString aText(xText->getString());
-    //
-    //     if(!aText.isEmpty())
-    //     {
-    //     }
-    // }
-
-    // Add all kinds of properties that are needed to re-create the XShape.
-    // For now this is a minimal example-selection, it will need to be extended
-    // over time for all kind of cases/properties
-
-    // text properties
-    if(xServiceInfo->supportsService("com.sun.star.drawing.TextProperties"))
-    {
-        addProperty(UNO_NAME_CHAR_COLOR, xInfo, rTarget, xPropSet);
-        addProperty(UNO_NAME_CHAR_HEIGHT, xInfo, rTarget, xPropSet);
-        addProperty(UNO_NAME_CHAR_SHADOWED, xInfo, rTarget, xPropSet);
-        addProperty(UNO_NAME_CHAR_WEIGHT, xInfo, rTarget, xPropSet);
-    }
-
-    // fill properties
-    if(xServiceInfo->supportsService("com.sun.star.drawing.FillProperties"))
-    {
-        css::drawing::FillStyle eFillStyle(css::drawing::FillStyle_NONE);
-        if (xInfo->hasPropertyByName(UNO_NAME_FILLSTYLE))
-            xPropSet->getPropertyValue(UNO_NAME_FILLSTYLE) >>= eFillStyle;
-
-        if(css::drawing::FillStyle_NONE != eFillStyle)
-        {
-            addProperty(UNO_NAME_FILLSTYLE, xInfo, rTarget, xPropSet);
-
-            switch(eFillStyle)
-            {
-                case css::drawing::FillStyle_SOLID:
-                {
-                    addProperty(UNO_NAME_FILLCOLOR, xInfo, rTarget, xPropSet);
-                    break;
-                }
-                default:
-                case css::drawing::FillStyle_NONE:
-                case css::drawing::FillStyle_GRADIENT:
-                case css::drawing::FillStyle_HATCH:
-                case css::drawing::FillStyle_BITMAP:
-                    break;
-            }
-        }
-    }
-
-    // line properties
-    if(xServiceInfo->supportsService("com.sun.star.drawing.LineProperties"))
-    {
-        css::drawing::LineStyle eLineStyle(css::drawing::LineStyle_NONE);
-        if (xInfo->hasPropertyByName(UNO_NAME_LINESTYLE))
-            xPropSet->getPropertyValue(UNO_NAME_LINESTYLE) >>= eLineStyle;
-
-        if(css::drawing::LineStyle_NONE != eLineStyle)
-        {
-            addProperty(UNO_NAME_LINESTYLE, xInfo, rTarget, xPropSet);
-            addProperty(UNO_NAME_LINECOLOR, xInfo, rTarget, xPropSet);
-            addProperty(UNO_NAME_LINEWIDTH, xInfo, rTarget, xPropSet);
-
-            switch(eLineStyle)
-            {
-                case css::drawing::LineStyle_SOLID:
-                    break;
-                default:
-                case css::drawing::LineStyle_NONE:
-                case css::drawing::LineStyle_DASH:
-                    break;
-            }
-        }
-    }
-}
-
-void Point::restorePropertiesToXShape(const css::uno::Reference< 
css::drawing::XShape >& rXShape) const
-{
-    if(!msPointStylePtr)
-        return;
-
-    if(!rXShape)
-        return;
-
-    css::uno::Reference<css::beans::XPropertySet> xPropSet(rXShape, 
css::uno::UNO_QUERY);
-    if(!xPropSet)
-        return;
-
-    std::vector< std::pair< OUString, css::uno::Any >>& 
rSource(msPointStylePtr->maProperties);
-
-    for (auto const& prop : rSource)
-    {
-        xPropSet->setPropertyValue(prop.first, prop.second);
-    }
-}
-
 DiagramData::DiagramData()
 {
 }
@@ -319,8 +155,7 @@ void DiagramData::getChildrenString(
             rBuf.append('\t');
         rBuf.append('+');
         rBuf.append(' ');
-        if(pPoint->msTextBody)
-            rBuf.append(pPoint->msTextBody->msText);
+        rBuf.append(pPoint->msTextBody->msText);
         rBuf.append('\n');
     }
 
@@ -353,7 +188,7 @@ std::vector<std::pair<OUString, OUString>> 
DiagramData::getChildren(const OUStri
             {
                 aChildren[rCxn.mnSourceOrder] = std::make_pair(
                     pChild->second->msModelId,
-                    pChild->second->msTextBody ? 
pChild->second->msTextBody->msText : OUString());
+                    pChild->second->msTextBody->msText);
             }
         }
 
@@ -381,7 +216,6 @@ OUString DiagramData::addNode(const OUString& rText)
     svx::diagram::Point aDataPoint;
     aDataPoint.mnXMLType = TypeConstant::XML_node;
     aDataPoint.msModelId = sNewNodeId;
-    aDataPoint.msTextBody = std::make_shared<TextBody>();
     aDataPoint.msTextBody->msText = rText;
 
     OUString sDataSibling;
@@ -482,6 +316,7 @@ void DiagramData::buildDiagramDataModel(bool 
/*bClearOoxShapes*/)
     maPointsPresNameMap.clear();
     maConnectionNameMap.clear();
     maPresOfNameMap.clear();
+    msBackgroundShapeModelID.clear();
 
 #ifdef DEBUG_OOX_DIAGRAM
     std::ofstream output("tree.dot");
@@ -522,7 +357,7 @@ void DiagramData::buildDiagramDataModel(bool 
/*bClearOoxShapes*/)
 #endif
 
         // does currpoint have any text set?
-        if(point.msTextBody && !point.msTextBody->msText.isEmpty())
+        if(!point.msTextBody->msText.isEmpty())
         {
 #ifdef DEBUG_OOX_DIAGRAM
             static sal_Int32 nCount=0;
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
index 91e8174eea70..b1ad4b729e7e 100644
--- a/svx/source/svdraw/svdogrp.cxx
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -34,7 +34,13 @@
 #include <libxml/xmlwriter.h>
 #include <vcl/canvastools.hxx>
 
-IDiagramHelper::IDiagramHelper() {}
+IDiagramHelper::IDiagramHelper()
+: mbUseDiagramThemeData(false)
+, mbUseDiagramModelData(true)
+, mbForceThemePtrReceation(false)
+{
+}
+
 IDiagramHelper::~IDiagramHelper() {}
 
 void IDiagramHelper::anchorToSdrObjGroup(SdrObjGroup& rTarget)

Reply via email to