SmartArt: Progress in standard FileFormat RoundTrip

Added functionality to ex/import using boost::property_tree
and it's read/write_info functionality, based on conversion
to/from OUString. This keeps it most user-readable in XML
format. I currently use <svg:desc> to add it, secured by a
token and preserving evtl. existing Description at the
GroupObject hosting the Diagram, but may move somewhere
else. This has the advantage that <svg:desc> is supported
since version 1.0 and the SmartArt/Diagram ModelData *is*
the object's Description. Not sure yet, we will see.

There were some hard parts, e.g. I needed to find a way to
incarnate a class defined in oox inside svx and that class
is derived from baseclass in svx in oox, but got that done.

Still secured by ACTIVATE_ADVANCED_DIAGRAM_FEATURES since
this will still need some corrections, but basic round-trip
is functional.

This will allow to copy/paste between two office instances
and is also the base for thinking about providing gallery
functionality for Diagrams.

Had some problems with boost/property_tree stuff var
shadowing, also lock of model was missing in
SvxDrawingLayerExport, will change that in next version
to ssth more sophisticated.

Change-Id: I526d3b2477b5de40df990345c9c06d0a2f9cbfeb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200219
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This commit is contained in:
Armin Le Grand (collabora)
2026-02-26 16:42:59 +01:00
committed by Armin Le Grand
parent 651064b9dd
commit 09605513f4
14 changed files with 720 additions and 76 deletions
@@ -0,0 +1,32 @@
/* generated by bin/gen-boost-headers, do not edit! */
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
#pragma GCC diagnostic ignored "-Wdeprecated-builtins"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Winvalid-constexpr"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
#pragma GCC diagnostic ignored "-Wnonnull"
#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wplacement-new"
#pragma GCC diagnostic ignored "-Wreturn-type"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
#pragma GCC diagnostic ignored "-Wtype-limits"
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-macros"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#include_next <boost/property_tree/info_parser.hpp>
#pragma GCC diagnostic pop
@@ -71,6 +71,7 @@ public:
std::shared_ptr<::oox::drawingml::Theme> xTheme,
css::awt::Size aImportSize);
explicit DiagramHelper_oox(DiagramHelper_oox const& rSource);
explicit DiagramHelper_oox(const boost::property_tree::ptree& rDiagramModel);
virtual ~DiagramHelper_oox();
// re-create XShapes
@@ -110,6 +111,19 @@ public:
// needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
virtual DiagramHelper_oox* clone() const override;
// write data to boost::property_tree
virtual void addDiagramModelData(boost::property_tree::ptree& rTarget) const override;
};
class DiagramHelperFactory_oox : public svx::diagram::DiagramHelperFactory_svx
{
public:
DiagramHelperFactory_oox();
virtual ~DiagramHelperFactory_oox();
// overloaded here to allow instantiation of a DiagramHelper_oox
virtual std::shared_ptr<svx::diagram::DiagramHelper_svx> createDiagramHelper_svx(boost::property_tree::ptree& rTarget) const override;
};
}
+21
View File
@@ -134,6 +134,27 @@ public:
// needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
virtual DiagramHelper_svx* clone() const = 0;
// write data to boost::property_tree
virtual void addDiagramModelData(boost::property_tree::ptree& rTarget) const = 0;
};
class SVXCORE_DLLPUBLIC DiagramHelperFactory_svx
{
protected:
// do prohibit direct instantiation, only DiagramHelper_oox is intended
DiagramHelperFactory_svx();
// keep global var of this module hidden
static DiagramHelperFactory_svx* pSingleGlobalDiagramHelperFactory_svx;
public:
// try to access global static single instance of DiagramHelperFactory
static DiagramHelperFactory_svx& getDiagramHelperFactory_svx();
// virtual call to instantiate a new DiagramHelper, overloaded in oox to
// allow instantiation of a DiagramHelper_oox
virtual std::shared_ptr<svx::diagram::DiagramHelper_svx> createDiagramHelper_svx(boost::property_tree::ptree& rTarget) const = 0;
};
}} // end of namespace
+63 -47
View File
@@ -35,6 +35,7 @@
#include <com/sun/star/drawing/XShape.hpp>
#include <oox/token/tokens.hxx>
#include <sax/fshelper.hxx>
#include <boost/property_tree/ptree.hpp>
namespace svx::diagram {
@@ -59,18 +60,21 @@ enum TypeConstant {
struct SVXCORE_DLLPUBLIC Connection
{
Connection();
explicit Connection(const boost::property_tree::ptree& rConnectionData);
TypeConstant mnXMLType; // default is XML_parOf
OUString msModelId;
OUString msSourceId;
OUString msDestId;
OUString msParTransId;
OUString msPresId;
OUString msSibTransId;
sal_Int32 mnSourceOrder;
sal_Int32 mnDestOrder;
/* DEFAULT Variable varName XML_Tag */
/* XML_parOf */ TypeConstant mnXMLType; // XML_type
/* (empty) */ OUString msModelId; // XML_modelId
/* (empty) */ OUString msSourceId; // XML_srcId
/* (empty) */ OUString msDestId; // XML_destId
/* (empty) */ OUString msPresId; // XML_presId
/* (empty) */ OUString msSibTransId; // XML_sibTransId
/* (empty) */ OUString msParTransId; // XML_parTransId
/* 0 */ sal_Int32 mnSourceOrder; // XML_srcOrd
/* 0 */ sal_Int32 mnDestOrder; // XML_destOrd
void writeDiagramData(sax_fastparser::FSHelperPtr& rTarget);
void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
};
typedef std::vector< Connection > Connections;
@@ -80,57 +84,64 @@ typedef std::vector< Connection > Connections;
struct SVXCORE_DLLPUBLIC Point
{
Point();
explicit Point(const boost::property_tree::ptree& rPointData);
// PT: dgm:pt
// PRS: dgm:prSet
// PLV: dgm:presLayoutVars
/* PT */ OUString msCnxId;
/* PT */ OUString msModelId;
/* PRS */ OUString msColorTransformCategoryId;
/* PRS */ OUString msColorTransformTypeId;
/* PRS */ OUString msLayoutCategoryId;
/* PRS */ OUString msLayoutTypeId;
/* PRS */ OUString msPlaceholderText;
/* PRS */ OUString msPresentationAssociationId;
/* PRS */ OUString msPresentationLayoutName;
/* PRS */ OUString msPresentationLayoutStyleLabel;
/* PRS */ OUString msQuickStyleCategoryId;
/* PRS */ OUString msQuickStyleTypeId;
/* PLV */ OUString msResizeHandles;
/* TYP DEFAULT Variable varName XML_Tag */
/* PT (empty) */ OUString msCnxId; // XML_cxnId
/* PT (empty) */ OUString msModelId; // XML_modelId
/* PRS (empty) */ OUString msColorTransformCategoryId; // XML_csCatId
/* PRS (empty) */ OUString msColorTransformTypeId; // XML_csTypeId
/* PRS (empty) */ OUString msLayoutCategoryId; // XML_loCatId
/* PRS (empty) */ OUString msLayoutTypeId; // XML_loTypeId
/* PRS (empty) */ OUString msPlaceholderText; // XML_phldrT
/* PRS (empty) */ OUString msPresentationAssociationId; // XML_presAssocID
/* PRS (empty) */ OUString msPresentationLayoutName; // XML_presName
/* PRS (empty) */ OUString msPresentationLayoutStyleLabel; // XML_presStyleLbl
/* PRS (empty) */ OUString msQuickStyleCategoryId; // XML_qsCatId
/* PRS (empty) */ OUString msQuickStyleTypeId; // XML_qsTypeId
/* PLV (empty) */ OUString msResizeHandles; // XML_resizeHandles
/* PT */ TypeConstant mnXMLType; // default is XML_node
/* PLV */ sal_Int32 mnMaxChildren;
/* PLV */ sal_Int32 mnPreferredChildren;
/* PLV */ sal_Int32 mnDirection;
/* PLV */ std::optional<sal_Int32> moHierarchyBranch;
/* PT XML_node */ TypeConstant mnXMLType; // default is XML_node // XML_type
/* PLV -1 */ sal_Int32 mnMaxChildren; // XML_chMax
/* PLV -1 */ sal_Int32 mnPreferredChildren; // XML_chPref
/* PLV XML_norm */ sal_Int32 mnDirection; // XML_dir
/* PLV (opt) */ std::optional<sal_Int32> moHierarchyBranch; // XML_hierBranch
/* PRS */ sal_Int32 mnCustomAngle;
/* PRS */ sal_Int32 mnPercentageNeighbourWidth;
/* PRS */ sal_Int32 mnPercentageNeighbourHeight;
/* PRS */ sal_Int32 mnPercentageOwnWidth;
/* PRS */ sal_Int32 mnPercentageOwnHeight;
/* PRS */ sal_Int32 mnIncludeAngleScale;
/* PRS */ sal_Int32 mnRadiusScale;
/* PRS */ sal_Int32 mnWidthScale;
/* PRS */ sal_Int32 mnHeightScale;
/* PRS */ sal_Int32 mnWidthOverride;
/* PRS */ sal_Int32 mnHeightOverride;
/* PRS */ sal_Int32 mnLayoutStyleCount;
/* PRS */ sal_Int32 mnLayoutStyleIndex;
/* PRS -1 */ sal_Int32 mnCustomAngle; // XML_custAng
/* PRS -1 */ sal_Int32 mnPercentageNeighbourWidth; // XML_custLinFactNeighborX
/* PRS -1 */ sal_Int32 mnPercentageNeighbourHeight; // XML_custLinFactNeighborY
/* PRS -1 */ sal_Int32 mnPercentageOwnWidth; // XML_custLinFactX
/* PRS -1 */ sal_Int32 mnPercentageOwnHeight; // XML_custLinFactY
/* PRS -1 */ sal_Int32 mnIncludeAngleScale; // XML_custRadScaleInc
/* PRS -1 */ sal_Int32 mnRadiusScale; // XML_custRadScaleRad
/* PRS -1 */ sal_Int32 mnWidthScale; // XML_custScaleX
/* PRS -1 */ sal_Int32 mnHeightScale; // XML_custScaleY
/* PRS -1 */ sal_Int32 mnWidthOverride; // XML_custSzX
/* PRS -1 */ sal_Int32 mnHeightOverride; // XML_custSzY
/* PRS -1 */ sal_Int32 mnLayoutStyleCount; // XML_presStyleCnt
/* PRS -1 */ sal_Int32 mnLayoutStyleIndex; // XML_presStyleIdx
/* PLV */ bool mbOrgChartEnabled : 1;
/* PLV */ bool mbBulletEnabled : 1;
/* PRS */ bool mbCoherent3DOffset : 1;
/* PRS */ bool mbCustomHorizontalFlip : 1;
/* PRS */ bool mbCustomVerticalFlip : 1;
/* PRS */ bool mbCustomText : 1;
/* PRS */ bool mbIsPlaceholder : 1;
/* PLV (false) */ bool mbOrgChartEnabled : 1; // XML_orgChart
/* PLV (false) */ bool mbBulletEnabled : 1; // XML_bulletEnabled
/* PRS (false) */ bool mbCoherent3DOffset : 1; // XML_coherent3DOff
/* PRS (false) */ bool mbCustomHorizontalFlip : 1; // XML_custFlipHor
/* PRS (false) */ bool mbCustomVerticalFlip : 1; // XML_custFlipVert
/* PRS (false) */ bool mbCustomText : 1; // XML_custT
/* PRS (false) */ bool mbIsPlaceholder : 1; // XML_phldr
void writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget);
void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
};
TypeConstant SVXCORE_DLLPUBLIC getTypeConstantForName(std::u16string_view aName);
std::u16string_view SVXCORE_DLLPUBLIC getNameForTypeConstant(TypeConstant aTypeConstant);
void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint);
void SVXCORE_DLLPUBLIC addTypeConstantToDiagramModelData(TypeConstant aTypeConstant, boost::property_tree::ptree& rTarget, bool bPoint);
typedef std::vector< Point > Points;
/** Snippet of Diagram ModelData for Diagram-defining data undo/redo
@@ -171,6 +182,7 @@ protected:
// shall not be incarnated - target to use is oox::drawingml::DiagramData_oox
DiagramData_svx();
explicit DiagramData_svx(DiagramData_svx const& rSource);
explicit DiagramData_svx(const boost::property_tree::ptree& rDiagramModel);
public:
// access associated SdrObjGroup/XShape/RootShape
@@ -189,6 +201,7 @@ public:
// read accesses
Connections& getConnections() { return maConnections; }
const Connections& getConnections() const { return maConnections; }
Points& getPoints() { return maPoints; }
const Points& getPoints() const { return maPoints; }
StringMap& getPresOfNameMap() { return maPresOfNameMap; }
@@ -217,6 +230,9 @@ public:
css::uno::Reference<css::drawing::XShape> getXShapeByModelID(std::u16string_view rModelID) const;
const Point* getPointByModelID(std::u16string_view rModelID) const;
// write data to boost::property_tree
void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
protected:
// helpers
void getDiagramChildrenString(OUStringBuffer& rBuf, const Point* pPoint, sal_Int32 nLevel) const;
+3
View File
@@ -114,6 +114,9 @@ public:
virtual rtl::Reference<SdrObject> DoConvertToPolyObj(bool bBezier,
bool bAddText) const override;
virtual void SetDescription(const OUString& rStr) override;
virtual OUString GetDescription() const override;
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
};
@@ -35,6 +35,7 @@
#include <oox/export/drawingml.hxx>
#include <sax/fastattribs.hxx>
#include <oox/export/shapes.hxx>
#include <boost/property_tree/ptree.hpp>
#include <unordered_set>
@@ -295,11 +296,17 @@ DiagramData_oox::DiagramData_oox()
DiagramData_oox::DiagramData_oox(DiagramData_oox const& rSource)
: svx::diagram::DiagramData_svx(rSource)
, mpBackgroundShapeFillProperties()
, mpBackgroundShapeFillProperties(rSource.mpBackgroundShapeFillProperties)
, maPointShapeMap()
{
}
DiagramData_oox::DiagramData_oox(const boost::property_tree::ptree& rDiagramModel)
: svx::diagram::DiagramData_svx(rDiagramModel)
, mpBackgroundShapeFillProperties( std::make_shared<FillProperties>() )
{
}
DiagramData_oox::~DiagramData_oox()
{
}
@@ -43,6 +43,7 @@ public:
DiagramData_oox();
explicit DiagramData_oox(DiagramData_oox const& rSource);
explicit DiagramData_oox(const boost::property_tree::ptree& rDiagramModel);
virtual ~DiagramData_oox();
// creates temporary processing data from model data
+146
View File
@@ -46,6 +46,12 @@
#include <com/sun/star/io/TempFile.hpp>
#include <oox/export/drawingml.hxx>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
#include <oox/core/fastparser.hxx>
#include <unotools/streamwrap.hxx>
#include <tools/stream.hxx>
#ifdef DBG_UTIL
#include <osl/file.hxx>
#include <o3tl/environment.hxx>
@@ -172,6 +178,89 @@ SmartArtDiagram::SmartArtDiagram()
{
}
SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel)
: maDiagramFontHeights()
, mpData(std::make_shared<DiagramData_oox>(rDiagramModel))
, mpLayout(std::make_shared<DiagramLayout>(*this))
, maStyles()
, maColors()
, maDiagramPRDomMap()
{
#ifdef DBG_UTIL
mpData->dump();
#endif
const OUString aOOXLayoutDOM(OUString::fromUtf8(rDiagramModel.get("OOXLayout", "")));
const OUString aOOXStyleDOM(OUString::fromUtf8(rDiagramModel.get("OOXStyle", "")));
const OUString aOOXColorDOM(OUString::fromUtf8(rDiagramModel.get("OOXColor", "")));
if (!aOOXLayoutDOM.isEmpty() || !aOOXStyleDOM.isEmpty() || !aOOXColorDOM.isEmpty())
{
// we need a PowerPointImport for the FragmentHandlers, so create a single
// temporary one. Use this for all possible DomTrees
rtl::Reference<oox::ppt::PowerPointImport> xPPTImport(new oox::ppt::PowerPointImport(comphelper::getProcessComponentContext()));
if (!aOOXLayoutDOM.isEmpty())
{
// construct MemoryStream and OStreamWrapper with SVG in OUString
const OString sUtf8(OUStringToOString(aOOXLayoutDOM, RTL_TEXTENCODING_UTF8));
SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), sUtf8.getLength(), StreamMode::READ);
rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new utl::OStreamWrapper(aStream);
// create the dom parser & create DomTree
uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
uno::Reference<xml::dom::XDocument> aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
// set DomTree locally
setOOXDomValue(svx::diagram::DomMapFlag::OOXLayout, uno::Any(aDomTree));
// import DomTree to mpLayout
uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(aDomTree, uno::UNO_QUERY_THROW);
rtl::Reference< core::FragmentHandler > xRefLayout(new DiagramLayoutFragmentHandler(*xPPTImport, "internal", mpLayout));
xPPTImport->importFragment(xRefLayout, xSerializer);
}
if (!aOOXStyleDOM.isEmpty())
{
// construct MemoryStream and OStreamWrapper with SVG in OUString
const OString sUtf8(OUStringToOString(aOOXStyleDOM, RTL_TEXTENCODING_UTF8));
SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), sUtf8.getLength(), StreamMode::READ);
rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new utl::OStreamWrapper(aStream);
// create the dom parser & create DomTree
uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
uno::Reference<xml::dom::XDocument> aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
// set DomTree locally
setOOXDomValue(svx::diagram::DomMapFlag::OOXStyle, uno::Any(aDomTree));
// import DomTree to maStyles
uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(aDomTree, uno::UNO_QUERY_THROW);
rtl::Reference< core::FragmentHandler > xRefLayout(new DiagramQStylesFragmentHandler(*xPPTImport, "internal", maStyles));
xPPTImport->importFragment(xRefLayout, xSerializer);
}
if (!aOOXColorDOM.isEmpty())
{
// construct MemoryStream and OStreamWrapper with SVG in OUString
const OString sUtf8(OUStringToOString(aOOXColorDOM, RTL_TEXTENCODING_UTF8));
SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), sUtf8.getLength(), StreamMode::READ);
rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new utl::OStreamWrapper(aStream);
// create the dom parser & create DomTree
uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
uno::Reference<xml::dom::XDocument> aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
// set DomTree locally
setOOXDomValue(svx::diagram::DomMapFlag::OOXColor, uno::Any(aDomTree));
// import DomTree to maColors
uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(aDomTree, uno::UNO_QUERY_THROW);
rtl::Reference< core::FragmentHandler > xRefLayout(new ColorFragmentHandler(*xPPTImport, "internal", maColors));
xPPTImport->importFragment(xRefLayout, xSerializer);
}
}
}
SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource)
: maDiagramFontHeights()
, mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr)
@@ -307,6 +396,63 @@ void SmartArtDiagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, uno:
#endif
}
void SmartArtDiagram::addDomTreeToModelData(svx::diagram::DomMapFlag aId, std::u16string_view aName, boost::property_tree::ptree& rTarget) const
{
uno::Reference<xml::dom::XDocument> aDomTree;
getOOXDomValue(aId) >>= aDomTree;
if (aDomTree)
{
// serialize DomTree to a MemoryStream
SvMemoryStream aStream( 1024, 1024 );
rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new utl::OStreamWrapper( aStream );
uno::Reference<xml::sax::XSAXSerializable> serializer;
uno::Reference<xml::sax::XWriter> writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
serializer.set(aDomTree, uno::UNO_QUERY);
writer->setOutputStream(pStreamWrapper->getOutputStream());
serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW), uno::Sequence<beans::StringPair>());
// put into string
const OUString aContent(static_cast<const char*>(aStream.GetData()), aStream.TellEnd(), RTL_TEXTENCODING_UTF8);
// add to ModelData
const OString sUtf8(OUStringToOString(aName, RTL_TEXTENCODING_UTF8));
rTarget.put(sUtf8.getStr(), aContent);
}
}
void SmartArtDiagram::addDiagramModelData(boost::property_tree::ptree& rTarget) const
{
// add Point and Connection data
getData()->addDiagramModelData(rTarget);
// What DomMaps are needed?
//
// With the above OOXData is covered. OOXDataImageRels/OOXDataHlinkRels also,
// these may/will be re-created when OOX export and a new OOXDataDomTree
// needs to be created.
// Similar with OOXDrawing: This contains parts of ModelData, e.g. Text and
// Attributes represented by the XShapes/Sdrobjects, so for internal formats
// this is not needed to be saved. This also true for OOXDrawingImageRels
// and OOXDrawingHlinkRels.
// We *do* import OOXLayoutDomTree/ModelInfo and this is used in the layouting
// mechanism (reLayout), but it is not changed. We could add an export of that
// for internal formats, but since it's not changed it just needs to be
// preserved, either for internal use or export to OOX formats.
// OOXStyle and OOXColor are imported only on oox import side, partially held
// for initial import at Diagram classes. Also never changed, but maybe needed
// for export to OOX formats. Not sure about that since Style and Color is
// part of XShape/SdrObject Model Hierarchy, so exports to OOX should be possible
// without these, but maybe MSO wants that data...
//
// OOXLayout = 3,
// OOXStyle = 4,
// OOXColor = 5,
addDomTreeToModelData(svx::diagram::DomMapFlag::OOXLayout, u"OOXLayout", rTarget);
addDomTreeToModelData(svx::diagram::DomMapFlag::OOXStyle, u"OOXStyle", rTarget);
addDomTreeToModelData(svx::diagram::DomMapFlag::OOXColor, u"OOXColor", rTarget);
}
using ShapePairs
= std::map<std::shared_ptr<drawingml::Shape>, uno::Reference<drawing::XShape>>;
+7
View File
@@ -130,6 +130,7 @@ class SmartArtDiagram
public:
explicit SmartArtDiagram();
explicit SmartArtDiagram(SmartArtDiagram const& rSource);
explicit SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel);
void setData( const OoxDiagramDataPtr& pData )
{ mpData = pData; }
const OoxDiagramDataPtr& getData() const
@@ -159,7 +160,13 @@ public:
void writeDiagramOOXData(DrawingML& rOriginalDrawingML, css::uno::Reference<css::io::XOutputStream>& xOutputStream, std::u16string_view rDrawingRelId) const;
void writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, css::uno::Reference<css::io::XOutputStream>& xOutputStream) const;
// write data to boost::property_tree
void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
private:
// helper for addDiagramModelData
void addDomTreeToModelData(svx::diagram::DomMapFlag aId, std::u16string_view aName, boost::property_tree::ptree& rTarget) const;
// This contains groups of shapes: automatic font size is the same in each group.
oox::core::NamedShapePairs maDiagramFontHeights;
@@ -63,6 +63,16 @@ DiagramHelper_oox::DiagramHelper_oox(DiagramHelper_oox const& rSource)
{
}
DiagramHelper_oox::DiagramHelper_oox(const boost::property_tree::ptree& rDiagramModel)
: DiagramHelper_svx()
, mpDiagramPtr(new SmartArtDiagram(rDiagramModel))
, mpDiagramThemePtr()
, maDiagramImportSize()
, msNewNodeId()
, msNewNodeText()
{
}
DiagramHelper_oox::~DiagramHelper_oox() {}
void DiagramHelper_oox::moveDiagramModelDataFromOldToNewXShape(
@@ -303,7 +313,7 @@ OUString DiagramHelper_oox::getDiagramString() const
return mpDiagramPtr->getData()->getDiagramString();
}
return OUString();
return EMPTY_OUSTRING;
}
std::vector<std::pair<OUString, OUString>>
@@ -516,6 +526,45 @@ DiagramHelper_oox* DiagramHelper_oox::clone() const
return new DiagramHelper_oox(*this);
}
void DiagramHelper_oox::addDiagramModelData(boost::property_tree::ptree& rTarget) const
{
if (!mpDiagramPtr)
return;
mpDiagramPtr->addDiagramModelData(rTarget);
}
DiagramHelperFactory_oox::DiagramHelperFactory_oox()
: DiagramHelperFactory_svx()
{
// make clear that this is supposed to happen only once
assert(nullptr == pSingleGlobalDiagramHelperFactory_svx
&& "DiagramHelperFactory initialized multiple times (!)");
// directly assign created instance to global pointer in svx for access from there
if (nullptr == pSingleGlobalDiagramHelperFactory_svx)
pSingleGlobalDiagramHelperFactory_svx = this;
}
DiagramHelperFactory_oox::~DiagramHelperFactory_oox()
{
if (this == pSingleGlobalDiagramHelperFactory_svx)
pSingleGlobalDiagramHelperFactory_svx = nullptr;
}
std::shared_ptr<svx::diagram::DiagramHelper_svx>
DiagramHelperFactory_oox::createDiagramHelper_svx(boost::property_tree::ptree& rTarget) const
{
// from here we can instantiate DiagramHelper_oox and return
return std::make_shared<DiagramHelper_oox>(rTarget);
}
// this is the global needed anchor in oox module for an instantiation of
// DiagramHelperFactory_oox and thus for DiagramHelperFactory_svx. This
// is needed since in svx where a Diagram has to be imported an instance
// of DiagramHelper_oox needs to be instantiated, but svx cannot access oox
static DiagramHelperFactory_oox aSingleGlobalDiagramHelperFactory_oox;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+16
View File
@@ -467,6 +467,22 @@ void DiagramHelper_svx::AddAdditionalVisualization(const SdrObjGroup& rTarget, S
rHdlList.AddHdl(std::move(pHdl));
}
DiagramHelperFactory_svx::DiagramHelperFactory_svx()
{
}
DiagramHelperFactory_svx& DiagramHelperFactory_svx::getDiagramHelperFactory_svx()
{
assert(nullptr != pSingleGlobalDiagramHelperFactory_svx && "DiagramHelperFactory not yet initialized (!)");
return *pSingleGlobalDiagramHelperFactory_svx;
}
// init gobal member var of DiagramHelperFactory_svx. This will then be set
// by DiagramHelperFactory_oox::DiagramHelperFactory_oox when
// aSingleGlobalDiagramHelperFactory_oox gets incarnated by oox library at
// that librarys load time
DiagramHelperFactory_svx* DiagramHelperFactory_svx::pSingleGlobalDiagramHelperFactory_svx = nullptr;
}} // end of namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+266 -26
View File
@@ -29,44 +29,111 @@
#include <utility>
#include <sax/fastattribs.hxx>
#include <com/sun/star/text/XText.hpp>
#include <xmloff/xmltoken.hxx>
using namespace ::oox;
using namespace ::com::sun::star;
namespace svx::diagram {
TypeConstant getTypeConstantForName(std::u16string_view aName)
{
if (u"Type" == aName) return TypeConstant::XML_type;
if (u"asst" == aName) return TypeConstant::XML_asst;
if (u"doc" == aName) return TypeConstant::XML_doc;
if (u"node" == aName) return TypeConstant::XML_node;
if (u"norm" == aName) return TypeConstant::XML_norm;
if (u"parOf" == aName) return TypeConstant::XML_parOf;
if (u"parTrans" == aName) return TypeConstant::XML_parTrans;
if (u"pres" == aName) return TypeConstant::XML_pres;
if (u"presOf" == aName) return TypeConstant::XML_presOf;
if (u"presParOf" == aName) return TypeConstant::XML_presParOf;
if (u"rel" == aName) return TypeConstant::XML_rel;
if (u"sibTrans" == aName) return TypeConstant::XML_sibTrans;
return TypeConstant::XML_none;
}
std::u16string_view getNameForTypeConstant(TypeConstant aTypeConstant)
{
switch (aTypeConstant)
{
case TypeConstant::XML_type: return u"Type"; break;
case TypeConstant::XML_asst: return u"asst"; break;
case TypeConstant::XML_doc: return u"doc"; break;
case TypeConstant::XML_node: return u"node"; break;
case TypeConstant::XML_norm: return u"norm"; break;
case TypeConstant::XML_parOf: return u"parOf"; break;
case TypeConstant::XML_parTrans: return u"parTrans"; break;
case TypeConstant::XML_pres: return u"pres"; break;
case TypeConstant::XML_presOf: return u"presOf"; break;
case TypeConstant::XML_presParOf: return u"presParOf"; break;
case TypeConstant::XML_rel: return u"rel"; break;
case TypeConstant::XML_sibTrans: return u"sibTrans"; break;
case TypeConstant::XML_none: break;
}
return u"";
}
void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint)
{
if (TypeConstant::XML_none != aTypeConstant)
{
switch (aTypeConstant)
{
// *CAUTION!* here '::XML_type' is *not* the same as 'XML_type' which would
// namespace expand to oox::XML_type as in enum TypeConstant definitions (!)
case TypeConstant::XML_type: rAttributeList->add(::XML_type, "Type"); break;
case TypeConstant::XML_asst: rAttributeList->add(::XML_type, "asst"); break;
case TypeConstant::XML_doc: rAttributeList->add(::XML_type, "doc"); break;
case TypeConstant::XML_node: if(!bPoint) rAttributeList->add(::XML_type, "node"); break;
case TypeConstant::XML_norm: rAttributeList->add(::XML_type, "norm"); break;
case TypeConstant::XML_parOf: if(bPoint) rAttributeList->add(::XML_type, "parOf"); break;
case TypeConstant::XML_parTrans: rAttributeList->add(::XML_type, "parTrans"); break;
case TypeConstant::XML_pres: rAttributeList->add(::XML_type, "pres"); break;
case TypeConstant::XML_presOf: rAttributeList->add(::XML_type, "presOf"); break;
case TypeConstant::XML_presParOf: rAttributeList->add(::XML_type, "presParOf"); break;
case TypeConstant::XML_rel: rAttributeList->add(::XML_type, "rel"); break;
case TypeConstant::XML_sibTrans: rAttributeList->add(::XML_type, "sibTrans"); break;
default: break; // XML_none
}
}
if (TypeConstant::XML_none == aTypeConstant)
return;
if (TypeConstant::XML_node == aTypeConstant && bPoint)
return;
if (TypeConstant::XML_parOf == aTypeConstant && !bPoint)
return;
const std::u16string_view aName(getNameForTypeConstant(aTypeConstant));
// *CAUTION!* here '::XML_type' is *not* the same as 'XML_type' which would
// namespace expand to oox::XML_type as in enum TypeConstant definitions (!)
if (!aName.empty())
rAttributeList->add(::XML_type, aName);
}
void addTypeConstantToDiagramModelData(TypeConstant aTypeConstant, boost::property_tree::ptree& rTarget, bool bPoint)
{
if (TypeConstant::XML_none == aTypeConstant)
return;
if (TypeConstant::XML_node == aTypeConstant && bPoint)
return;
if (TypeConstant::XML_parOf == aTypeConstant && !bPoint)
return;
const std::u16string_view aName(getNameForTypeConstant(aTypeConstant));
if (!aName.empty())
rTarget.put("XMLType", OUString(aName));
}
Connection::Connection()
: mnXMLType( XML_parOf )
, msModelId()
, msSourceId()
, msDestId()
, msPresId()
, msSibTransId()
, msParTransId()
, mnSourceOrder( 0 )
, mnDestOrder( 0 )
{
}
Connection::Connection(const boost::property_tree::ptree& rConnectionData)
: mnXMLType( XML_parOf )
, msModelId(OUString::fromUtf8(rConnectionData.get("modelId", "")))
, msSourceId(OUString::fromUtf8(rConnectionData.get("srcId", "")))
, msDestId(OUString::fromUtf8(rConnectionData.get("destId", "")))
, msPresId(OUString::fromUtf8(rConnectionData.get("presId", "")))
, msSibTransId(OUString::fromUtf8(rConnectionData.get("sibTransId", "")))
, msParTransId(OUString::fromUtf8(rConnectionData.get("parTransId", "")))
, mnSourceOrder(rConnectionData.get("srcOrd", 0))
, mnDestOrder(rConnectionData.get("destOrd", 0))
{
const OUString aXMLType(OUString::fromUtf8(rConnectionData.get("XMLType", "")));
if (!aXMLType.isEmpty())
mnXMLType = getTypeConstantForName(aXMLType);
}
void Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget)
{
if (!rTarget)
@@ -93,6 +160,19 @@ void Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget)
rTarget->singleElementNS(XML_dgm, XML_cxn, pAttributeList);
}
void Connection::addDiagramModelData(boost::property_tree::ptree& rTarget) const
{
addTypeConstantToDiagramModelData(mnXMLType, rTarget, false); // XML_type
if (!msModelId.isEmpty()) rTarget.put("modelId", msModelId); // XML_modelId
if (!msSourceId.isEmpty()) rTarget.put("srcId", msSourceId); // XML_srcId
if (!msDestId.isEmpty()) rTarget.put("destId", msDestId); // XML_destId
if (!msPresId.isEmpty()) rTarget.put("presId", msPresId); // XML_presId
if (!msSibTransId.isEmpty()) rTarget.put("sibTransId", msSibTransId); // XML_sibTransId
if (!msParTransId.isEmpty()) rTarget.put("parTransId", msParTransId); // XML_parTransId
if (0 != mnSourceOrder) rTarget.put("srcOrd", mnSourceOrder); // XML_srcOrd
if (0 != mnDestOrder) rTarget.put("destOrd", mnDestOrder); // XML_destOrd
}
Point::Point()
: mnXMLType(XML_node)
, mnMaxChildren(-1)
@@ -121,6 +201,55 @@ Point::Point()
{
}
Point::Point(const boost::property_tree::ptree& rPointData)
: msCnxId(OUString::fromUtf8(rPointData.get("cxnId", "")))
, msModelId(OUString::fromUtf8(rPointData.get("modelId", "")))
, msColorTransformCategoryId(OUString::fromUtf8(rPointData.get("csCatId", "")))
, msColorTransformTypeId(OUString::fromUtf8(rPointData.get("csTypeId", "")))
, msLayoutCategoryId(OUString::fromUtf8(rPointData.get("loCatId", "")))
, msLayoutTypeId(OUString::fromUtf8(rPointData.get("loTypeId", "")))
, msPlaceholderText(OUString::fromUtf8(rPointData.get("phldrT", "")))
, msPresentationAssociationId(OUString::fromUtf8(rPointData.get("presAssocID", "")))
, msPresentationLayoutName(OUString::fromUtf8(rPointData.get("presName", "")))
, msPresentationLayoutStyleLabel(OUString::fromUtf8(rPointData.get("presStyleLbl", "")))
, msQuickStyleCategoryId(OUString::fromUtf8(rPointData.get("qsCatId", "")))
, msQuickStyleTypeId(OUString::fromUtf8(rPointData.get("qsTypeId", "")))
, msResizeHandles(OUString::fromUtf8(rPointData.get("resizeHandles", "")))
, mnXMLType(XML_node)
, mnMaxChildren(rPointData.get("chMax", -1))
, mnPreferredChildren(rPointData.get("chPref", -1))
, mnDirection(rPointData.get<int>("dir", XML_norm))
, moHierarchyBranch()
, mnCustomAngle(rPointData.get("custAng", -1))
, mnPercentageNeighbourWidth(rPointData.get("custLinFactNeighborX", -1))
, mnPercentageNeighbourHeight(rPointData.get("custLinFactNeighborY", -1))
, mnPercentageOwnWidth(rPointData.get("custLinFactX", -1))
, mnPercentageOwnHeight(rPointData.get("custLinFactY", -1))
, mnIncludeAngleScale(rPointData.get("custRadScaleInc", -1))
, mnRadiusScale(rPointData.get("custRadScaleRad", -1))
, mnWidthScale(rPointData.get("custScaleX", -1))
, mnHeightScale(rPointData.get("custScaleY", -1))
, mnWidthOverride(rPointData.get("custSzX", -1))
, mnHeightOverride(rPointData.get("custSzY", -1))
, mnLayoutStyleCount(rPointData.get("presStyleCnt", -1))
, mnLayoutStyleIndex(rPointData.get("presStyleIdx", -1))
, mbOrgChartEnabled(rPointData.get("orgChart", false))
, mbBulletEnabled(rPointData.get("bulletEnabled", false))
, mbCoherent3DOffset(rPointData.get("coherent3DOff", false))
, mbCustomHorizontalFlip(rPointData.get("custFlipHor", false))
, mbCustomVerticalFlip(rPointData.get("custFlipVert", false))
, mbCustomText(rPointData.get("custT", false))
, mbIsPlaceholder(rPointData.get("phldr", false))
{
const OUString aXMLType(OUString::fromUtf8(rPointData.get("XMLType", "")));
if (!aXMLType.isEmpty())
mnXMLType = getTypeConstantForName(aXMLType);
const boost::optional<sal_Int32> aBranch(rPointData.get_optional<int>("hierBranch"));
if (aBranch.has_value())
moHierarchyBranch = aBranch.value();
}
void Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
{
rtl::Reference<sax_fastparser::FastAttributeList> pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList());
@@ -151,11 +280,11 @@ void Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
if (-1 != mnLayoutStyleIndex) pAttributeList->add(XML_presStyleIdx, OUString::number(mnLayoutStyleIndex));
static constexpr OUString aStrTrue = u"1"_ustr; // this uses "1", not "true"
if (true == mbCoherent3DOffset) pAttributeList->add(XML_coherent3DOff, aStrTrue);
if (true == mbCustomHorizontalFlip) pAttributeList->add(XML_custFlipHor, aStrTrue);
if (true == mbCustomVerticalFlip) pAttributeList->add(XML_custFlipVert, aStrTrue);
if (true == mbCustomText) pAttributeList->add(XML_custT, aStrTrue);
if (true == mbIsPlaceholder) pAttributeList->add(XML_phldr, aStrTrue);
if (mbCoherent3DOffset) pAttributeList->add(XML_coherent3DOff, aStrTrue);
if (mbCustomHorizontalFlip) pAttributeList->add(XML_custFlipHor, aStrTrue);
if (mbCustomVerticalFlip) pAttributeList->add(XML_custFlipVert, aStrTrue);
if (mbCustomText) pAttributeList->add(XML_custT, aStrTrue);
if (mbIsPlaceholder) pAttributeList->add(XML_phldr, aStrTrue);
const bool bNeed_presLayoutVars(mbBulletEnabled
|| -1 != mnMaxChildren
@@ -198,6 +327,51 @@ void Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
rTarget->singleElementNS(XML_dgm, XML_prSet, pAttributeList);
}
void Point::addDiagramModelData(boost::property_tree::ptree& rTarget) const
{
if (!msCnxId.isEmpty()) rTarget.put("cxnId", msCnxId); // XML_cxnId
if (!msModelId.isEmpty()) rTarget.put("modelId", msModelId); // XML_modelId
if (!msColorTransformCategoryId.isEmpty()) rTarget.put("csCatId", msColorTransformCategoryId); // XML_csCatId
if (!msColorTransformTypeId.isEmpty()) rTarget.put("csTypeId", msColorTransformTypeId); // XML_csTypeId
if (!msLayoutCategoryId.isEmpty()) rTarget.put("loCatId", msLayoutCategoryId); // XML_loCatId
if (!msLayoutTypeId.isEmpty()) rTarget.put("loTypeId", msLayoutTypeId); // XML_loTypeId
if (!msPlaceholderText.isEmpty()) rTarget.put("phldrT", msPlaceholderText); // XML_phldrT
if (!msPresentationAssociationId.isEmpty()) rTarget.put("presAssocID", msPresentationAssociationId); // XML_presAssocID
if (!msPresentationLayoutName.isEmpty()) rTarget.put("presName", msPresentationLayoutName); // XML_presName
if (!msPresentationLayoutStyleLabel.isEmpty()) rTarget.put("presStyleLbl", msPresentationLayoutStyleLabel); // XML_presStyleLbl
if (!msQuickStyleCategoryId.isEmpty()) rTarget.put("qsCatId", msQuickStyleCategoryId); // XML_qsCatId
if (!msQuickStyleTypeId.isEmpty()) rTarget.put("qsTypeId", msQuickStyleTypeId); // XML_qsTypeId
if (!msResizeHandles.isEmpty()) rTarget.put("resizeHandles", msResizeHandles); // XML_resizeHandles
addTypeConstantToDiagramModelData(mnXMLType, rTarget, true); // XML_type
if (-1 != mnMaxChildren) rTarget.put("chMax", mnMaxChildren); // XML_chMax
if (-1 != mnPreferredChildren) rTarget.put("chPref", mnPreferredChildren); // XML_chPref
if (XML_norm != mnDirection) rTarget.put("dir", mnDirection); // XML_dir
if (moHierarchyBranch.has_value()) rTarget.put("hierBranch", moHierarchyBranch.value()); // XML_hierBranch
if (-1 != mnCustomAngle) rTarget.put("custAng", mnCustomAngle); // XML_custAng
if (-1 != mnPercentageNeighbourWidth) rTarget.put("custLinFactNeighborX", mnPercentageNeighbourWidth); // XML_custLinFactNeighborX
if (-1 != mnPercentageNeighbourHeight) rTarget.put("custLinFactNeighborY", mnPercentageNeighbourHeight); // XML_custLinFactNeighborY
if (-1 != mnPercentageOwnWidth) rTarget.put("custLinFactX", mnPercentageOwnWidth); // XML_custLinFactX
if (-1 != mnPercentageOwnHeight) rTarget.put("custLinFactY", mnPercentageOwnHeight); // XML_custLinFactY
if (-1 != mnIncludeAngleScale) rTarget.put("custRadScaleInc", mnIncludeAngleScale); // XML_custRadScaleInc
if (-1 != mnRadiusScale) rTarget.put("custRadScaleRad", mnRadiusScale); // XML_custRadScaleRad
if (-1 != mnWidthScale) rTarget.put("custScaleX", mnWidthScale); // XML_custScaleX
if (-1 != mnHeightScale) rTarget.put("custScaleY", mnHeightScale); // XML_custScaleY
if (-1 != mnWidthOverride) rTarget.put("custSzX", mnWidthOverride); // XML_custSzX
if (-1 != mnHeightOverride) rTarget.put("custSzY", mnHeightOverride); // XML_custSzY
if (-1 != mnLayoutStyleCount) rTarget.put("presStyleCnt", mnLayoutStyleCount); // XML_presStyleCnt
if (-1 != mnLayoutStyleIndex) rTarget.put("presStyleIdx", mnLayoutStyleIndex); // XML_presStyleIdx
if (mbOrgChartEnabled) rTarget.put("orgChart", mbOrgChartEnabled); // XML_orgChart
if (mbBulletEnabled) rTarget.put("bulletEnabled", mbBulletEnabled); // XML_bulletEnabled
if (mbCoherent3DOffset) rTarget.put("coherent3DOff", mbCoherent3DOffset); // XML_coherent3DOff
if (mbCustomHorizontalFlip) rTarget.put("custFlipHor", mbCustomHorizontalFlip); // XML_custFlipHor
if (mbCustomVerticalFlip) rTarget.put("custFlipVert", mbCustomVerticalFlip); // XML_custFlipVert
if (mbCustomText) rTarget.put("custT", mbCustomText); // XML_custT
if (mbIsPlaceholder) rTarget.put("phldr", mbIsPlaceholder); // XML_phldr
}
DiagramData_svx::DiagramData_svx()
: mxRootShape()
, maExtDrawings()
@@ -227,6 +401,34 @@ DiagramData_svx::DiagramData_svx(DiagramData_svx const& rSource)
{
}
DiagramData_svx::DiagramData_svx(const boost::property_tree::ptree& rDiagramModel)
: mxRootShape()
, maExtDrawings()
, maConnections()
, maPoints()
, mxThemeDocument()
, maPointsPresNameMap()
, maConnectionNameMap()
, maPresOfNameMap()
, msBackgroundShapeModelID(OUString::fromUtf8(rDiagramModel.get("BGShapeModelID", "")))
{
const int nPtCnt(rDiagramModel.get_child("PtCnt").get_value<int>());
for (int a(0); a < nPtCnt; a++)
{
const OUString aName(OUString::Concat("Pt") + OUString::number(a));
boost::property_tree::ptree aPointData = rDiagramModel.get_child(aName.toUtf8().getStr());
maPoints.emplace_back(aPointData);
}
const int nConnCnt(rDiagramModel.get_child("ConnCnt").get_value<int>());
for (int a(0); a < nConnCnt; a++)
{
const OUString aName(OUString::Concat("Cn") + OUString::number(a));
boost::property_tree::ptree aConnectionData = rDiagramModel.get_child(aName.toUtf8().getStr());
maConnections.emplace_back(aConnectionData);
}
}
DiagramData_svx::~DiagramData_svx()
{
}
@@ -399,6 +601,44 @@ const Point* DiagramData_svx::getPointByModelID(std::u16string_view rModelID) co
return nullptr;
}
void DiagramData_svx::addDiagramModelData(boost::property_tree::ptree& rTarget) const
{
// write BGShapeModelID to boost::property_tree
rTarget.put("BGShapeModelID", getBackgroundShapeModelID());
// write points to boost::property_tree
const svx::diagram::Points& rPoints = getPoints();
if (!rPoints.empty())
{
rTarget.put("PtCnt", rPoints.size());
size_t count(0);
for (auto & point : rPoints)
{
boost::property_tree::ptree aPoints;
point.addDiagramModelData(aPoints);
const OUString aName(OUString::Concat("Pt") + OUString::number(count++));
rTarget.push_back(std::make_pair(aName.toUtf8().getStr(), aPoints));
}
}
// write connections to boost::property_tree
const svx::diagram::Connections& rConnections = getConnections();
if (!rConnections.empty())
{
rTarget.put("ConnCnt", rConnections.size());
size_t count(0);
for (auto & connection : rConnections)
{
boost::property_tree::ptree aConnections;
connection.addDiagramModelData(aConnections);
const OUString aName(OUString::Concat("Cn") + OUString::number(count++));
rTarget.push_back(std::make_pair(aName.toUtf8().getStr(), aConnections));
}
}
}
uno::Reference<drawing::XShape> DiagramData_svx::getMasterXShapeForPoint(const Point& rPoint) const
{
for (auto& rCandidate : getPoints())
+84
View File
@@ -33,6 +33,8 @@
#include <libxml/xmlwriter.h>
#include <vcl/canvastools.hxx>
#include <svx/diagram/DiagramHelper_svx.hxx>
#include <svx/diagram/DiagramHelper_svx.hxx>
#include <boost/property_tree/info_parser.hpp>
bool SdrObjGroup::isDiagram() const
{
@@ -762,6 +764,88 @@ rtl::Reference<SdrObject> SdrObjGroup::DoConvertToPolyObj(bool bBezier, bool bAd
return pGroup;
}
void SdrObjGroup::SetDescription(const OUString& rStr)
{
static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
if (!bActivateAdvancedDiagramFeatures)
{
SdrObject::SetDescription(rStr);
return;
}
OUString aOrigDescription(rStr);
if (!rStr.isEmpty() && getSdrModelFromSdrObject().isLocked())
{
// we maybe importing a Diagram. Try to get the Diagram ModelData and
// add needed Diagram ModelData
// NOTE: currently isLocked() is used to identify import, that *may* have
// to be made more specific in SdXMLImport
OUString aModelData;
// check if the identifying token is there
if (rStr.startsWith(u"SmartArtModelData:", &aModelData) && !aModelData.isEmpty())
{
// import to boost::property_tree
boost::property_tree::ptree aDiagramModel;
std::stringstream aStream(aModelData.toUtf8().getStr());
// try to read data
boost::property_tree::read_info(aStream, aDiagramModel);
if (!aDiagramModel.empty())
{
// extract possibly existing original description and set as target value
aOrigDescription = OUString::fromUtf8(aDiagramModel.get("origDesc", ""));
// parse content to a new Diagram DataModel
std::shared_ptr<svx::diagram::DiagramHelper_svx> aNewHelper(svx::diagram::DiagramHelperFactory_svx::getDiagramHelperFactory_svx().createDiagramHelper_svx(aDiagramModel));
mp_DiagramHelper = aNewHelper;
mp_DiagramHelper->getRootShape() = getUnoShape();
}
}
}
// call parent to set evtl. original description
SdrObject::SetDescription(aOrigDescription);
}
OUString SdrObjGroup::GetDescription() const
{
static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
if (!bActivateAdvancedDiagramFeatures)
return SdrObject::GetDescription();
// call parent to get original description
OUString aRetval(SdrObject::GetDescription());
if (mp_DiagramHelper && getSdrModelFromSdrObject().isLocked())
{
// we are a Diagram and are exporting. Get the Diagram ModelData and
// place it to the description
// NOTE: currently isLocked() is used to identify export, that *may* have
// to be made more specific in SdXMLExport
boost::property_tree::ptree aDiagramModel;
// get Diagram ModelData in property_tree
mp_DiagramHelper->addDiagramModelData(aDiagramModel);
// add original description if exists
if (!aRetval.isEmpty())
aDiagramModel.put("origDesc", aRetval);
// convert property_tree to OUString and return
std::stringstream aStream;
boost::property_tree::write_info(aStream, aDiagramModel);
// add identifying token at start
aRetval = u"SmartArtModelData:" + OUString::fromUtf8(aStream.str());
}
return aRetval;
}
void SdrObjGroup::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SdrObjGroup"));
+9 -1
View File
@@ -51,8 +51,9 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const uno::Reference<io::XOutputSt
Reference< document::XEmbeddedObjectResolver > xObjectResolver;
rtl::Reference<SvXMLEmbeddedObjectHelper> xObjectHelper;
Reference< lang::XComponent > xSourceDoc( xComponent );
Reference< frame::XModel > xSourceModel;
try
{
if( !xSourceDoc.is() )
@@ -62,6 +63,10 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const uno::Reference<io::XOutputSt
pModel->setUnoModel( pDrawingModel );
}
xSourceModel = Reference< frame::XModel >( xSourceDoc, UNO_QUERY );
if ( xSourceModel.is() )
xSourceModel->lockControllers();
const uno::Reference< uno::XComponentContext>& xContext( ::comphelper::getProcessComponentContext() );
if( bDocRet )
@@ -124,6 +129,9 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const uno::Reference<io::XOutputSt
if( xObjectHelper.is() )
xObjectHelper->dispose();
if ( xSourceModel.is() )
xSourceModel->unlockControllers();
return bDocRet;
}