summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <Armin.Le.Grand@me.com>2022-04-19 11:37:57 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2022-04-20 09:32:52 +0200
commitd9b3374b13108cf6b847f6eb92fb666194a68770 (patch)
treeeba87516cdef9e68a15ef85fa834b1e89eec54ca
parentf22f83fbac3a0a419c2e95d7b725525fd02649e6 (diff)
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 <Armin.Le.Grand@me.com>
-rw-r--r--include/oox/drawingml/shape.hxx6
-rw-r--r--include/svx/diagram/datamodel.hxx46
-rw-r--r--include/svx/svdogrp.hxx30
-rw-r--r--oox/source/drawingml/diagram/datamodel.cxx278
-rw-r--r--oox/source/drawingml/diagram/datamodel.hxx10
-rw-r--r--oox/source/drawingml/diagram/datamodelcontext.cxx2
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx41
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx4
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.cxx17
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.hxx2
-rw-r--r--oox/source/drawingml/diagram/layoutatomvisitors.cxx4
-rw-r--r--oox/source/drawingml/shape.cxx3
-rw-r--r--svx/source/diagram/datamodel.cxx179
-rw-r--r--svx/source/svdraw/svdogrp.cxx8
14 files changed, 383 insertions, 247 deletions
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)