diff --git a/include/oox/drawingml/diagram/diagramhelper_oox.hxx b/include/oox/drawingml/diagram/diagramhelper_oox.hxx index d6e31592d20d..9a7004a58fad 100644 --- a/include/oox/drawingml/diagram/diagramhelper_oox.hxx +++ b/include/oox/drawingml/diagram/diagramhelper_oox.hxx @@ -45,11 +45,9 @@ class DrawingML; // - im/export Diagram model to other representations class DiagramHelper_oox final : public svx::diagram::DiagramHelper_svx { - const std::shared_ptr< SmartArtDiagram > mpDiagramPtr; + const std::shared_ptr< SmartArtDiagram > mpDiagramPtr; std::shared_ptr<::oox::drawingml::Theme> mpDiagramThemePtr; - css::awt::Size maDiagramImportSize; - // data values set by addDiagramNode to be used by next reLayout call // when a new ode gets added OUString msNewNodeId; @@ -68,8 +66,7 @@ protected: public: DiagramHelper_oox( std::shared_ptr< SmartArtDiagram > xDiagramPtr, - std::shared_ptr<::oox::drawingml::Theme> xTheme, - css::awt::Size aImportSize); + std::shared_ptr<::oox::drawingml::Theme> xTheme); explicit DiagramHelper_oox(DiagramHelper_oox const& rSource); explicit DiagramHelper_oox(const boost::property_tree::ptree& rDiagramModel); virtual ~DiagramHelper_oox(); diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx index c89054d49443..78914382fde0 100644 --- a/include/svx/svdmodel.hxx +++ b/include/svx/svdmodel.hxx @@ -151,6 +151,7 @@ class SVXCORE_DLLPUBLIC SdrModel : public SfxBroadcaster, public tools::WeakBase friend void impAddIncarnatedSdrObjectToSdrModel(SdrObject& rSdrObject, SdrModel& rSdrModel); friend void impRemoveIncarnatedSdrObjectToSdrModel(SdrObject& rSdrObject, SdrModel& rSdrModel); std::unordered_set< SdrObject* > maAllIncarnatedObjects; + sal_uInt16 mnImExCnt; protected: std::vector> maMasterPages; std::vector> maPages; @@ -622,6 +623,10 @@ public: bool IsVOCInvalidationIsReliable() const { return mbVOCInvalidationIsReliable; } void SetVOCInvalidationIsReliable(bool b) { mbVOCInvalidationIsReliable = b; } + + bool isInImportExport() { return 0 != mnImExCnt; } + void incImportExport() { mnImExCnt++; } + void decImportExport() { if(mnImExCnt) mnImExCnt--; } }; /* diff --git a/include/svx/svdogrp.hxx b/include/svx/svdogrp.hxx index 6f1478eeff12..f74c84f71382 100644 --- a/include/svx/svdogrp.hxx +++ b/include/svx/svdogrp.hxx @@ -119,6 +119,9 @@ public: virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override; virtual void AddToHdlList(SdrHdlList& rHdlList) const override; + + virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const override; + virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon) override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index b196c61bbd53..05700c83112d 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -176,6 +176,16 @@ SmartArtDiagram::SmartArtDiagram() { } +SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource) +: maDiagramFontHeights() +, mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr) +, mpLayout(rSource.mpLayout) +, maStyles(rSource.maStyles) +, maColors(rSource.maColors) +, maDiagramPRDomMap(rSource.maDiagramPRDomMap) +{ +} + SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel) : maDiagramFontHeights() , mpData(std::make_shared(rDiagramModel)) @@ -213,8 +223,15 @@ SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& rDiagramMode // import DomTree to mpLayout uno::Reference xSerializer(aDomTree, uno::UNO_QUERY_THROW); - rtl::Reference< core::FragmentHandler > xRefLayout(new DiagramLayoutFragmentHandler(*xPPTImport, "internal", mpLayout)); + rtl::Reference< core::FragmentHandler > xRefLayout(new DiagramLayoutFragmentHandler(*this, *xPPTImport, "internal", mpLayout)); xPPTImport->importFragment(xRefLayout, xSerializer); + + // Data is loaded, so we already have Points and Connections. Also + // need to rebuild buffers for layouting (maPointsPresNameMap, + // maConnectionNameMap, maPresOfNameMap). Call with false due to + // we are in ODF import and have no oox::Shapes to delete and do + // *not* want these to be created (would not hurt, but not needed) + // getData()->buildDiagramDataModel(false); } if (!aOOXStyleDOM.isEmpty()) @@ -259,13 +276,7 @@ SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& rDiagramMode } } -SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource) -: maDiagramFontHeights() -, mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr) -, mpLayout(rSource.mpLayout) -, maStyles(rSource.maStyles) -, maColors(rSource.maColors) -, maDiagramPRDomMap(rSource.maDiagramPRDomMap) +SmartArtDiagram::~SmartArtDiagram() { } @@ -654,7 +665,7 @@ void loadDiagram( ShapePtr const & pShape, if (!rLayoutPath.isEmpty()) { rtl::Reference< core::FragmentHandler > xRefLayout( - new DiagramLayoutFragmentHandler( rFilter, rLayoutPath, + new DiagramLayoutFragmentHandler( *pDiagram, rFilter, rLayoutPath, std::move(pLayout) )); importFragment(rFilter, diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx index e4988aa70cc3..327787d9f0b5 100644 --- a/oox/source/drawingml/diagram/diagram.hxx +++ b/oox/source/drawingml/diagram/diagram.hxx @@ -131,6 +131,7 @@ public: explicit SmartArtDiagram(); explicit SmartArtDiagram(SmartArtDiagram const& rSource); explicit SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel); + ~SmartArtDiagram(); void setData( const OoxDiagramDataPtr& pData ) { mpData = pData; } const OoxDiagramDataPtr& getData() const diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx index 25644c70d29a..8078d8d3c9a1 100644 --- a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx +++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx @@ -30,11 +30,13 @@ using namespace ::oox::core; namespace oox::drawingml { // CT_DiagramDefinition -DiagramDefinitionContext::DiagramDefinitionContext( ContextHandler2Helper const & rParent, +DiagramDefinitionContext::DiagramDefinitionContext( SmartArtDiagram& rDgm, + ContextHandler2Helper const & rParent, const AttributeList& rAttributes, DiagramLayoutPtr pLayout ) : ContextHandler2( rParent ) , mpLayout(std::move( pLayout )) + , mrDgm(rDgm) { mpLayout->setDefStyle( rAttributes.getStringDefaulted( XML_defStyle ) ); OUString sValue = rAttributes.getStringDefaulted( XML_minVer ); @@ -67,12 +69,12 @@ DiagramDefinitionContext::onCreateContext( ::sal_Int32 aElement, break; case DGM_TOKEN( layoutNode ): { - LayoutNodePtr pNode = std::make_shared(mpLayout->getDiagram()); + LayoutNodePtr pNode = std::make_shared(); mpLayout->getNode() = pNode; pNode->setChildOrder( rAttribs.getToken( XML_chOrder, XML_b ) ); pNode->setMoveWith( rAttribs.getStringDefaulted( XML_moveWith ) ); pNode->setStyleLabel( rAttribs.getStringDefaulted( XML_styleLbl ) ); - return new LayoutNodeContext( *this, rAttribs, pNode ); + return new LayoutNodeContext(mrDgm, *this, rAttribs, pNode ); } case DGM_TOKEN( clrData ): // TODO, does not matter for the UI. skip. diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx index 022299852706..c206aad769b9 100644 --- a/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx +++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx @@ -28,13 +28,14 @@ namespace oox::drawingml { class DiagramDefinitionContext : public ::oox::core::ContextHandler2 { public: - DiagramDefinitionContext( ::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttributes, DiagramLayoutPtr pLayout ); + DiagramDefinitionContext( SmartArtDiagram& rDgm, ::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttributes, DiagramLayoutPtr pLayout ); virtual ~DiagramDefinitionContext() override; virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override; private: DiagramLayoutPtr mpLayout; + SmartArtDiagram& mrDgm; }; } diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx index 71adf3dce612..0395da6a2cf5 100644 --- a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx +++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx @@ -63,11 +63,13 @@ DiagramDataFragmentHandler::onCreateContext( ::sal_Int32 aElement, return this; } -DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( XmlFilterBase& rFilter, +DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( SmartArtDiagram& rDgm, + XmlFilterBase& rFilter, const OUString& rFragmentPath, DiagramLayoutPtr xDataPtr ) : FragmentHandler2( rFilter, rFragmentPath ) , mpDataPtr(std::move( xDataPtr )) + , mrDgm(rDgm) { } @@ -88,7 +90,7 @@ DiagramLayoutFragmentHandler::onCreateContext( ::sal_Int32 aElement, switch( aElement ) { case DGM_TOKEN( layoutDef ): - return new DiagramDefinitionContext( *this, rAttribs, mpDataPtr ); + return new DiagramDefinitionContext( mrDgm, *this, rAttribs, mpDataPtr ); default: break; } diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx index caecb4886ae6..caa43c9bc634 100644 --- a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx +++ b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx @@ -43,15 +43,15 @@ private: class DiagramLayoutFragmentHandler : public ::oox::core::FragmentHandler2 { public: - DiagramLayoutFragmentHandler(oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, DiagramLayoutPtr xDataPtr); + DiagramLayoutFragmentHandler(SmartArtDiagram& rDgm, oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, DiagramLayoutPtr xDataPtr); virtual ~DiagramLayoutFragmentHandler() noexcept override; virtual void SAL_CALL endDocument() override; virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override; private: - DiagramLayoutPtr mpDataPtr; + SmartArtDiagram& mrDgm; }; class DiagramQStylesFragmentHandler : public ::oox::core::FragmentHandler2 diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx b/oox/source/drawingml/diagram/diagramhelper_oox.cxx index 5beba10cc781..29294a3313bb 100644 --- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx +++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx @@ -43,11 +43,9 @@ namespace oox::drawingml bool DiagramHelper_oox::hasDiagramData() const { return mpDiagramPtr && mpDiagramPtr->getData(); } DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr xDiagramPtr, - std::shared_ptr<::oox::drawingml::Theme> xTheme, - awt::Size aImportSize) + std::shared_ptr<::oox::drawingml::Theme> xTheme) : mpDiagramPtr(std::move(xDiagramPtr)) , mpDiagramThemePtr(std::move(xTheme)) - , maDiagramImportSize(aImportSize) , msNewNodeId() , msNewNodeText() { @@ -57,7 +55,6 @@ DiagramHelper_oox::DiagramHelper_oox(DiagramHelper_oox const& rSource) : DiagramHelper_svx(rSource) , mpDiagramPtr(rSource.mpDiagramPtr ? new SmartArtDiagram(*rSource.mpDiagramPtr) : nullptr) , mpDiagramThemePtr(rSource.mpDiagramThemePtr) - , maDiagramImportSize(rSource.maDiagramImportSize) , msNewNodeId() , msNewNodeText() { @@ -67,7 +64,6 @@ DiagramHelper_oox::DiagramHelper_oox(const boost::property_tree::ptree& rDiagram : DiagramHelper_svx() , mpDiagramPtr(new SmartArtDiagram(rDiagramModel)) , mpDiagramThemePtr() - , maDiagramImportSize() , msNewNodeId() , msNewNodeText() { @@ -115,11 +111,23 @@ void DiagramHelper_oox::reLayout() pTarget->TRGetBaseGeometry(aTransformation, aPolyPolygon); // create temporary oox::Shape as target. No longer needed is to keep/remember - // the original oox::Shape to do that. Use original Size and Pos from initial import - // to get the same layout(s) + // the original oox::Shape to do that. Use local model data from Diagram root + // shape to get the same layout(s) oox::drawingml::ShapePtr pShapePtr = std::make_shared("com.sun.star.drawing.GroupShape"); pShapePtr->setDiagramType(); - pShapePtr->setSize(maDiagramImportSize); + + // set the Size, this is important to let the layout mechanism work + // correctly. Since we use the XShape/SdrObject hierarchy as part of + // the model data, get size from there. + // Create bounding range using unit coordinates and the object + // transformation + const basegfx::B2DRange aRootRange(aTransformation * basegfx::B2DPoint(0, 0), // top-left + aTransformation * basegfx::B2DPoint(1, 1)); // bottom-right + + // also need to convert to Emu used by mso and thus in oox::Shape stuff + pShapePtr->setSize( + awt::Size(oox::drawingml::convertHmmToEmu(basegfx::fround(aRootRange.getWidth())), + oox::drawingml::convertHmmToEmu(basegfx::fround(aRootRange.getHeight())))); // remember existing DrawingLayerModelData. Do this before createShapeHierarchyFromModel // below, that will create a new BackgroundShapeModelID and the BGShape would diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 1e1a17c14299..ca999d8e440e 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -547,7 +547,7 @@ void CompositeAlg::applyConstraintToLayout(const Constraint& rConstraint, } } -void CompositeAlg::layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape, +void CompositeAlg::layoutShapeChildren(const SmartArtDiagram& rDgm, AlgAtom& rAlg, const ShapePtr& rShape, const std::vector& rConstraints) { LayoutPropertyMap aProperties; @@ -701,7 +701,7 @@ void CompositeAlg::layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape, nVertMax = std::max(aPos.Y + aSize.Height, nVertMax); NamedShapePairs& rDiagramFontHeights - = rAlg.getLayoutNode().getDiagram().getDiagramFontHeights(); + = const_cast(rDgm).getDiagramFontHeights(); auto it = rDiagramFontHeights.find(aCurrShape->getInternalName()); if (it != rDiagramFontHeights.end()) { @@ -785,11 +785,11 @@ void ForEachAtom::accept( LayoutAtomVisitor& rVisitor ) rVisitor.visit(*this); } -LayoutAtomPtr ForEachAtom::getRefAtom() +LayoutAtomPtr ForEachAtom::getRefAtom(const SmartArtDiagram& rDgm) { if (!msRef.isEmpty()) { - const LayoutAtomMap& rLayoutAtomMap = getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap(); + const LayoutAtomMap& rLayoutAtomMap = rDgm.getLayout()->getLayoutAtomMap(); LayoutAtomMap::const_iterator pRefAtom = rLayoutAtomMap.find(msRef); if (pRefAtom != rLayoutAtomMap.end()) return pRefAtom->second; @@ -834,10 +834,10 @@ namespace * Takes the connection list from rLayoutNode, navigates from rFrom on an edge * of type nType, using a direction determined by bSourceToDestination. */ -OUString navigate(LayoutNode& rLayoutNode, svx::diagram::TypeConstant nType, std::u16string_view rFrom, +OUString navigate(const SmartArtDiagram& rDgm, svx::diagram::TypeConstant nType, std::u16string_view rFrom, bool bSourceToDestination) { - for (const auto& rConnection : rLayoutNode.getDiagram().getData()->getConnections()) + for (const auto& rConnection : rDgm.getData()->getConnections()) { if (rConnection.mnXMLType != nType) continue; @@ -868,18 +868,18 @@ sal_Int32 calcMaxDepth(std::u16string_view rNodeName, const svx::diagram::Connec } } -sal_Int32 ConditionAtom::getNodeCount(const svx::diagram::Point* pPresPoint) const +sal_Int32 ConditionAtom::getNodeCount(const SmartArtDiagram& rDgm, const svx::diagram::Point* pPresPoint) const { sal_Int32 nCount = 0; OUString sNodeId = pPresPoint->msPresentationAssociationId; // HACK: special case - count children of first child if (maIter.maAxis.size() == 2 && maIter.maAxis[0] == XML_ch && maIter.maAxis[1] == XML_ch) - sNodeId = navigate(mrLayoutNode, svx::diagram::TypeConstant::XML_parOf, sNodeId, /*bSourceToDestination*/ true); + sNodeId = navigate(rDgm, svx::diagram::TypeConstant::XML_parOf, sNodeId, /*bSourceToDestination*/ true); if (!sNodeId.isEmpty()) { - for (const auto& aCxn : mrLayoutNode.getDiagram().getData()->getConnections()) + for (const auto& aCxn : rDgm.getData()->getConnections()) if (aCxn.mnXMLType == svx::diagram::TypeConstant::XML_parOf && aCxn.msSourceId == sNodeId) nCount++; } @@ -887,7 +887,7 @@ sal_Int32 ConditionAtom::getNodeCount(const svx::diagram::Point* pPresPoint) con return nCount; } -bool ConditionAtom::getDecision(const svx::diagram::Point* pPresPoint) const +bool ConditionAtom::getDecision(const SmartArtDiagram& rDgm, const svx::diagram::Point* pPresPoint) const { if (mIsElse) return true; @@ -907,9 +907,9 @@ bool ConditionAtom::getDecision(const svx::diagram::Point* pPresPoint) const { // If is missing in the current presentation // point, ask the parent. - OUString aParent = navigate(mrLayoutNode, svx::diagram::TypeConstant::XML_presParOf, pPresPoint->msModelId, + OUString aParent = navigate(rDgm, svx::diagram::TypeConstant::XML_presParOf, pPresPoint->msModelId, /*bSourceToDestination*/ false); - const svx::diagram::Point* it(mrLayoutNode.getDiagram().getData()->getPointByModelID(aParent)); + const svx::diagram::Point* it(rDgm.getData()->getPointByModelID(aParent)); if (nullptr != it) { const svx::diagram::Point* pParent = it; @@ -923,11 +923,11 @@ bool ConditionAtom::getDecision(const svx::diagram::Point* pPresPoint) const } case XML_cnt: - return compareResult(maCond.mnOp, getNodeCount(pPresPoint), maCond.msVal.toInt32()); + return compareResult(maCond.mnOp, getNodeCount(rDgm, pPresPoint), maCond.msVal.toInt32()); case XML_maxDepth: { - sal_Int32 nMaxDepth = calcMaxDepth(pPresPoint->msPresentationAssociationId, mrLayoutNode.getDiagram().getData()->getConnections()); + sal_Int32 nMaxDepth = calcMaxDepth(pPresPoint->msPresentationAssociationId, rDgm.getData()->getConnections()); return compareResult(maCond.mnOp, nMaxDepth, maCond.msVal.toInt32()); } @@ -1069,12 +1069,10 @@ sal_Int32 AlgAtom::getVerticalShapesCount(const ShapePtr& rShape) namespace { /// Does the first data node of this shape have customized text properties? -bool HasCustomText(const ShapePtr& rShape, LayoutNode& rLayoutNode) +bool HasCustomText(const SmartArtDiagram& rDgm, const ShapePtr& rShape) { - const PresPointShapeMap& rPresPointShapeMap - = rLayoutNode.getDiagram().getLayout()->getPresPointShapeMap(); - const DiagramData_oox::StringMap& rPresOfNameMap - = rLayoutNode.getDiagram().getData()->getPresOfNameMap(); + const PresPointShapeMap& rPresPointShapeMap = rDgm.getLayout()->getPresPointShapeMap(); + const DiagramData_oox::StringMap& rPresOfNameMap = rDgm.getData()->getPresOfNameMap(); // Get the first presentation node of the shape. const svx::diagram::Point* pPresNode = nullptr; for (const auto& rPair : rPresPointShapeMap) @@ -1095,7 +1093,7 @@ bool HasCustomText(const ShapePtr& rShape, LayoutNode& rLayoutNode) for (const auto& rPair : itPresToData->second) { const DiagramData_oox::SourceIdAndDepth& rItem = rPair.second; - const svx::diagram::Point* it(rLayoutNode.getDiagram().getData()->getPointByModelID(rItem.msSourceId)); + const svx::diagram::Point* it(rDgm.getData()->getPointByModelID(rItem.msSourceId)); if (nullptr != it) { pDataNode = it; @@ -1115,7 +1113,7 @@ bool HasCustomText(const ShapePtr& rShape, LayoutNode& rLayoutNode) } } -void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector& rConstraints, +void AlgAtom::layoutShape(const SmartArtDiagram& rDgm, const ShapePtr& rShape, const std::vector& rConstraints, const std::vector& rRules) { if (mnType != XML_lin) @@ -1133,7 +1131,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector& { case XML_composite: { - CompositeAlg::layoutShapeChildren(*this, rShape, rConstraints); + CompositeAlg::layoutShapeChildren(rDgm, *this, rShape, rConstraints); break; } @@ -1415,8 +1413,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector& if (rConstraint.mnType == XML_primFontSz && rConstraint.mnFor == XML_des && rConstraint.mnOperator == XML_equ) { - NamedShapePairs& rDiagramFontHeights - = getLayoutNode().getDiagram().getDiagramFontHeights(); + NamedShapePairs& rDiagramFontHeights = const_cast(rDgm).getDiagramFontHeights(); auto it = rDiagramFontHeights.find(rConstraint.msForName); if (it == rDiagramFontHeights.end()) { @@ -1723,7 +1720,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector& aRun->getTextCharacterProperties().moHeight = fFontSize * 100; } - if (!HasCustomText(rShape, getLayoutNode())) + if (!HasCustomText(rDgm, rShape)) { // No customized text properties: enable autofit. pTextBody->getTextProperties().maPropertyMap.setProperty( @@ -1855,12 +1852,18 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector& << rShape->getSize().Width << "," << rShape->getSize().Height << ")"); } +LayoutNode::LayoutNode() + : LayoutAtom(*this) + , mnChildOrder(0) +{ +} + void LayoutNode::accept( LayoutAtomVisitor& rVisitor ) { rVisitor.visit(*this); } -bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* pPresNode, sal_Int32 nCurrIdx ) const +bool LayoutNode::setupShape( const SmartArtDiagram& rDgm, const ShapePtr& rShape, const svx::diagram::Point* pPresNode, sal_Int32 nCurrIdx ) const { SAL_INFO( "oox.drawingml", @@ -1868,9 +1871,9 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* << "\", modelId \"" << pPresNode->msModelId << "\""); // have the presentation node - now, need the actual data node: - const DiagramData_oox::StringMap::const_iterator aNodeName = mrDgm.getData()->getPresOfNameMap().find( + const DiagramData_oox::StringMap::const_iterator aNodeName = rDgm.getData()->getPresOfNameMap().find( pPresNode->msModelId); - if( aNodeName != mrDgm.getData()->getPresOfNameMap().end() ) + if( aNodeName != rDgm.getData()->getPresOfNameMap().end() ) { // Calculate the depth of what is effectively the topmost element. sal_Int32 nMinDepth = std::numeric_limits::max(); @@ -1884,14 +1887,14 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* { const DiagramData_oox::SourceIdAndDepth& rItem = rPair.second; // pPresNode is the presentation node of the aDataNode2 data node. - const svx::diagram::Point* pDataNode2(mrDgm.getData()->getPointByModelID(rItem.msSourceId)); + const svx::diagram::Point* pDataNode2(rDgm.getData()->getPointByModelID(rItem.msSourceId)); if (nullptr == pDataNode2) { //busted, skip it continue; } - Shape* pDataNode2Shape(mrDgm.getData()->getOrCreateAssociatedShape(*pDataNode2)); + Shape* pDataNode2Shape(rDgm.getData()->getOrCreateAssociatedShape(*pDataNode2)); if (nullptr == pDataNode2Shape) { //busted, skip it @@ -1968,7 +1971,7 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* " processing shape type " << rShape->getCustomShapeProperties()->getShapePresetType() << " for layout node named \"" << msName << "\""); - Shape* pPresNodeShape(mrDgm.getData()->getOrCreateAssociatedShape(*pPresNode)); + Shape* pPresNodeShape(rDgm.getData()->getOrCreateAssociatedShape(*pPresNode)); if (nullptr != pPresNodeShape) rShape->getFillProperties().assignUsed(pPresNodeShape->getFillProperties()); } @@ -1982,8 +1985,8 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* aStyleLabel = msStyleLabel; if( !aStyleLabel.isEmpty() ) { - const DiagramQStyleMap::const_iterator aStyle = mrDgm.getStyles().find(aStyleLabel); - if( aStyle != mrDgm.getStyles().end() ) + const DiagramQStyleMap::const_iterator aStyle = rDgm.getStyles().find(aStyleLabel); + if( aStyle != rDgm.getStyles().end() ) { const DiagramStyle& rStyle = aStyle->second; rShape->getShapeStyleRefs()[XML_fillRef] = rStyle.maFillStyle; @@ -1996,8 +1999,8 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const svx::diagram::Point* SAL_WARN("oox.drawingml", "Style " << aStyleLabel << " not found"); } - const DiagramColorMap::const_iterator aColor = mrDgm.getColors().find(aStyleLabel); - if( aColor != mrDgm.getColors().end() ) + const DiagramColorMap::const_iterator aColor = rDgm.getColors().find(aStyleLabel); + if( aColor != rDgm.getColors().end() ) { // Take the nth color from the color list in case we are the nth shape in a // loop. diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index da20dff4cf98..d4586586a828 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -182,7 +182,7 @@ public: void addParam( sal_Int32 nType, sal_Int32 nVal ) { maMap[nType]=nVal; } sal_Int32 getVerticalShapesCount(const ShapePtr& rShape); - void layoutShape( const ShapePtr& rShape, + void layoutShape( const SmartArtDiagram& rDgm, const ShapePtr& rShape, const std::vector& rConstraints, const std::vector& rRules ); @@ -226,7 +226,7 @@ public: class CompositeAlg { public: - static void layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape, + static void layoutShapeChildren(const SmartArtDiagram& rDgm, AlgAtom& rAlg, const ShapePtr& rShape, const std::vector& rConstraints); private: @@ -261,7 +261,7 @@ public: const OUString& getRef() const { return msRef; } virtual void accept( LayoutAtomVisitor& ) override; - LayoutAtomPtr getRefAtom(); + LayoutAtomPtr getRefAtom(const SmartArtDiagram& rDgm); private: IteratorAttr maIter; @@ -276,11 +276,11 @@ class ConditionAtom public: explicit ConditionAtom(LayoutNode& rLayoutNode, bool isElse, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttributes); virtual void accept( LayoutAtomVisitor& ) override; - bool getDecision(const svx::diagram::Point* pPresPoint) const; + bool getDecision(const SmartArtDiagram& rDgm, const svx::diagram::Point* pPresPoint) const; private: static bool compareResult(sal_Int32 nOperator, sal_Int32 nFirst, sal_Int32 nSecond); - sal_Int32 getNodeCount(const svx::diagram::Point* pPresPoint) const; + sal_Int32 getNodeCount(const SmartArtDiagram& rDgm, const svx::diagram::Point* pPresPoint) const; bool mIsElse; IteratorAttr maIter; @@ -300,19 +300,40 @@ public: virtual void accept( LayoutAtomVisitor& ) override; }; +// I have cleaned LayoutNode from the member 'SmartArtDiagram& mrDgm' +// since LayoutNode is model data and with that in place it would have +// been necessary to deep-clone or re-import the complete DiagramLayout, +// just to make sure that those members of SmartArtDiagram& will +// reference the correct - newly created - SmartArtDiagram. +// That again would have been hard to keep under control due to +// LayoutNodes hosting a full hierarchy of LayoutNodes in it's base +// class LayoutAtom, so complicated deep-copy and need of virtual Clone +// method at LayoutAtom to do the right thing for all eight derivations +// of it. +// This is now no longer needed. It can just stay shared, thus the +// DiagramLayoutPtr gets just copied above. This reflects that the +// layout mechanism hosted by these atoms is not changed itself, but +// used (in some ForEach manner) to create the shapes, so does not +// need to be changed itself. +// It gets now just additionally referenced by the SmartArtDiagram copy +// costructor. That is for non-deep copy/paste where this copy operator +// is used. +// For deep copy the SmartArtDiagram constructor with import from +// boost::property_tree has to be used which will have to re-import +// the layout model data to mpLayout anyways. +// Instead of having SmartArtDiagram as member it now will be handed +// as needed to import contexts (LayoutNodeContext and derivatives). +// All those classes are used temporarily and are not part of the model. +// It also gets handed over for shape re-creation in LayoutAtomVisitorBase +// and it's derivates. Also those classes are used temporarily and are +// not part of the model. class LayoutNode : public LayoutAtom { public: typedef std::map VarMap; - LayoutNode(SmartArtDiagram& rDgm) - : LayoutAtom(*this) - , mrDgm(rDgm) - , mnChildOrder(0) - { - } - SmartArtDiagram& getDiagram() { return mrDgm; } + LayoutNode(); virtual void accept( LayoutAtomVisitor& ) override; VarMap & variables() { return mVariables; } @@ -332,14 +353,13 @@ public: void addNodeShape(const ShapePtr& pShape) { mpNodeShapes.push_back(pShape); } - bool setupShape( const ShapePtr& rShape, + bool setupShape( const SmartArtDiagram& rDgm, const ShapePtr& rShape, const svx::diagram::Point* pPresNode, sal_Int32 nCurrIdx ) const; const LayoutNode* getParentLayoutNode() const; private: - SmartArtDiagram& mrDgm; VarMap mVariables; OUString msMoveWith; OUString msStyleLabel; diff --git a/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx b/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx index ead3836379ea..cc76b8a2a06d 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx @@ -36,7 +36,7 @@ void LayoutAtomVisitorBase::visit(ChooseAtom& rAtom) for (const auto& pChild : rAtom.getChildren()) { const ConditionAtomPtr pCond = std::dynamic_pointer_cast(pChild); - if (pCond && pCond->getDecision(mpCurrentNode)) + if (pCond && pCond->getDecision(mrDgm, mpCurrentNode)) { SAL_INFO("oox.drawingml", "Entering if node: " << pCond->getName()); pCond->accept(*this); @@ -54,7 +54,7 @@ void LayoutAtomVisitorBase::visit(ForEachAtom& rAtom) { if (!rAtom.getRef().isEmpty()) { - if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom()) + if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom(mrDgm)) pRefAtom->accept(*this); return; } diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index 3fb520fca75b..43bf520ac951 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -79,7 +79,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) { // reuse existing shape ShapePtr pShape = rAtom.getExistingShape(); - if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx)) + if (rAtom.setupShape(mrDgm, pShape, pNewNode, mnCurrIdx)) { pShape->setInternalName(rAtom.getName()); rAtom.addNodeShape(pShape); @@ -98,7 +98,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) "processing shape type " << (pShape->getCustomShapeProperties()->getShapePresetType())); - if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx)) + if (rAtom.setupShape(mrDgm, pShape, pNewNode, mnCurrIdx)) { pShape->setInternalName(rAtom.getName()); xCurrParent->addChild(pShape); @@ -203,11 +203,10 @@ void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) { if (meLookFor == ALGORITHM) { - const PresPointShapeMap aMap - = rAtom.getLayoutNode().getDiagram().getLayout()->getPresPointShapeMap(); + const PresPointShapeMap aMap = mrDgm.getLayout()->getPresPointShapeMap(); auto pShape = aMap.find(mpCurrentNode); if (pShape != aMap.end()) - rAtom.layoutShape(pShape->second, maConstraints, maRules); + rAtom.layoutShape(mrDgm, pShape->second, maConstraints, maRules); } } diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx index d82dc881b844..fa3138190e5b 100644 --- a/oox/source/drawingml/diagram/layoutnodecontext.cxx +++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx @@ -40,10 +40,10 @@ class IfContext : public LayoutNodeContext { public: - IfContext( ContextHandler2Helper const & rParent, + IfContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ConditionAtomPtr& pAtom ) - : LayoutNodeContext( rParent, rAttribs, pAtom ) + : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom ) {} }; @@ -98,9 +98,10 @@ class ChooseContext : public ContextHandler2 { public: - ChooseContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, LayoutAtomPtr pNode ) + ChooseContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, LayoutAtomPtr pNode ) : ContextHandler2( rParent ) , mpNode(std::move( pNode )) + , mrDgm(rDgm) { msName = rAttribs.getStringDefaulted( XML_name ); } @@ -116,14 +117,14 @@ public: // CT_When ConditionAtomPtr pNode = std::make_shared(mpNode->getLayoutNode(), false, rAttribs.getFastAttributeList()); LayoutAtom::connect(mpNode, pNode); - return new IfContext( *this, rAttribs, pNode ); + return new IfContext( mrDgm, *this, rAttribs, pNode ); } case DGM_TOKEN( else ): { // CT_Otherwise ConditionAtomPtr pNode = std::make_shared(mpNode->getLayoutNode(), true, rAttribs.getFastAttributeList()); LayoutAtom::connect(mpNode, pNode); - return new IfContext( *this, rAttribs, pNode ); + return new IfContext( mrDgm, *this, rAttribs, pNode ); } default: break; @@ -134,19 +135,20 @@ public: private: OUString msName; LayoutAtomPtr mpNode; + SmartArtDiagram& mrDgm; }; class ForEachContext : public LayoutNodeContext { public: - ForEachContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom ) - : LayoutNodeContext( rParent, rAttribs, pAtom ) + ForEachContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom ) + : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom ) { pAtom->setRef(rAttribs.getStringDefaulted(XML_ref)); pAtom->iterator().loadFromXAttr( rAttribs.getFastAttributeList() ); - LayoutAtomMap& rLayoutAtomMap = pAtom->getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap(); + LayoutAtomMap& rLayoutAtomMap = getDiagram().getLayout()->getLayoutAtomMap(); rLayoutAtomMap[pAtom->getName()] = pAtom; } }; @@ -174,11 +176,12 @@ private: } // CT_LayoutNode -LayoutNodeContext::LayoutNodeContext( ContextHandler2Helper const & rParent, +LayoutNodeContext::LayoutNodeContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const LayoutAtomPtr& pAtom ) : ContextHandler2( rParent ) , mpNode( pAtom ) + , mrDgm(rDgm) { assert( pAtom && "Node must NOT be NULL" ); mpNode->setName( rAttribs.getStringDefaulted( XML_name ) ); @@ -196,7 +199,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement, { case DGM_TOKEN( layoutNode ): { - LayoutNodePtr pNode = std::make_shared(mpNode->getLayoutNode().getDiagram()); + LayoutNodePtr pNode = std::make_shared(); LayoutAtom::connect(mpNode, pNode); if (rAttribs.hasAttribute(XML_chOrder)) @@ -218,7 +221,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement, pNode->setMoveWith( rAttribs.getStringDefaulted( XML_moveWith ) ); pNode->setStyleLabel( rAttribs.getStringDefaulted( XML_styleLbl ) ); - return new LayoutNodeContext( *this, rAttribs, pNode ); + return new LayoutNodeContext( getDiagram(), *this, rAttribs, pNode ); } case DGM_TOKEN( shape ): { @@ -261,14 +264,14 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement, // CT_Choose LayoutAtomPtr pAtom = std::make_shared(mpNode->getLayoutNode()); LayoutAtom::connect(mpNode, pAtom); - return new ChooseContext( *this, rAttribs, std::move(pAtom) ); + return new ChooseContext( getDiagram(), *this, rAttribs, std::move(pAtom) ); } case DGM_TOKEN( forEach ): { // CT_ForEach ForEachAtomPtr pAtom = std::make_shared(mpNode->getLayoutNode(), rAttribs.getFastAttributeList()); LayoutAtom::connect(mpNode, pAtom); - return new ForEachContext( *this, rAttribs, pAtom ); + return new ForEachContext( getDiagram(), *this, rAttribs, pAtom ); } case DGM_TOKEN( constrLst ): // CT_Constraints diff --git a/oox/source/drawingml/diagram/layoutnodecontext.hxx b/oox/source/drawingml/diagram/layoutnodecontext.hxx index 3499f5704579..4b4bcff7e783 100644 --- a/oox/source/drawingml/diagram/layoutnodecontext.hxx +++ b/oox/source/drawingml/diagram/layoutnodecontext.hxx @@ -28,12 +28,14 @@ namespace oox::drawingml { class LayoutNodeContext : public ::oox::core::ContextHandler2 { public: - LayoutNodeContext( ::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttributes, const LayoutAtomPtr &pNode ); + LayoutNodeContext( SmartArtDiagram& rDgm, ::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttributes, const LayoutAtomPtr &pNode ); virtual ~LayoutNodeContext() override; virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) override; + SmartArtDiagram& getDiagram() { return mrDgm; } private: LayoutAtomPtr mpNode; + SmartArtDiagram& mrDgm; }; } diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index e34237c24eda..8298cbcca9c4 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -262,8 +262,7 @@ void Shape::prepareDiagramHelper( { mpDiagramHelper = new DiagramHelper_oox( rDiagramPtr, - rTheme, - getSize()); + rTheme); } } diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 34812da9b835..eac8888919d9 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -144,6 +144,7 @@ #include #include #include +#include #include #include @@ -2302,7 +2303,8 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) return; SfxBindings& rBindings = mrViewData.GetBindings(); - if (bEEMouse && mrViewData.HasEditView( eWhich )) + const bool bHasEditView(mrViewData.HasEditView( eWhich )); + if (bEEMouse && bHasEditView) { EditView* pEditView; SCCOL nEditCol; @@ -2343,6 +2345,42 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) return; } + if (!bHasEditView) + { + SdrView* pSdrView(mrViewData.GetView()->GetScDrawView()); + if (nullptr != pSdrView) + { + const Point aDocPos(PixelToLogic(aCurMousePos)); + SdrHdl* pHdl(pSdrView->PickHandle(aDocPos)); + + if (nullptr != pHdl) + { + SdrObject* pSingleObj(nullptr); + const SdrMarkList& rMarkList(pSdrView->GetMarkedObjectList()); + + if (1 == rMarkList.GetMarkCount()) + pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + + if (nullptr != pSingleObj) + { + // Check for click on svx::diagram::DiagramFrameHdl + // - if we hit a SdrHdl + // - if single object is selected + // - and it is a Diagram + if(pHdl && nullptr != pSingleObj && pSingleObj->isDiagram()) + { + svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast(pHdl)); + if(nullptr != pDiagramFrameHdl) + { + // let the DiagramFrameHdl decide what to do + svx::diagram::DiagramFrameHdl::clicked(aDocPos); + } + } + } + } + } + } + if (bDPMouse) { DPMouseButtonUp( rMEvt ); // resets bDPMouse diff --git a/sd/source/filter/xml/sdxmlwrp.cxx b/sd/source/filter/xml/sdxmlwrp.cxx index 3672dce210cf..22fe0626ee4f 100644 --- a/sd/source/filter/xml/sdxmlwrp.cxx +++ b/sd/source/filter/xml/sdxmlwrp.cxx @@ -461,6 +461,7 @@ bool SdXMLFilter::Import( ErrCode& nError ) pDoc->StopWorkStartupDelay(); mxModel->lockControllers(); + pDoc->incImportExport(); /** property map for import info set */ static PropertyMapEntry const aImportInfoMap[] = @@ -647,6 +648,7 @@ bool SdXMLFilter::Import( ErrCode& nError ) if( mxModel.is() ) mxModel->unlockControllers(); + pDoc->decImportExport(); if( nRet == ERRCODE_NONE ) pDoc->UpdateAllLinks(); @@ -768,9 +770,11 @@ bool SdXMLFilter::Export() } bool bLocked = mxModel->hasControllersLocked(); + SdDrawDocument* pDoc = mrDocShell.GetDoc(); try { + pDoc->incImportExport(); mxModel->lockControllers(); uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, uno::UNO_QUERY ); @@ -843,7 +847,7 @@ bool SdXMLFilter::Export() // create helper for graphic and ole export if we have a storage if( xStorage.is() ) { - xObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *mrDocShell.GetDoc()->GetPersist(), SvXMLEmbeddedObjectHelperMode::Write ); + xObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pDoc->GetPersist(), SvXMLEmbeddedObjectHelperMode::Write ); xObjectResolver = xObjectHelper.get(); xGraphicHelper = SvXMLGraphicHelper::Create( xStorage, SvXMLGraphicHelperMode::Write ); @@ -981,6 +985,7 @@ bool SdXMLFilter::Export() } if ( !bLocked ) mxModel->unlockControllers(); + pDoc->decImportExport(); if( xGraphicHelper ) xGraphicHelper->dispose(); diff --git a/svx/source/diagram/DiagramHelper_svx.cxx b/svx/source/diagram/DiagramHelper_svx.cxx index cdde569c7c63..185e6bf4c77e 100644 --- a/svx/source/diagram/DiagramHelper_svx.cxx +++ b/svx/source/diagram/DiagramHelper_svx.cxx @@ -453,7 +453,7 @@ void DiagramHelper_svx::connectToSdrObjGroup(css::uno::Reference< css::drawing:: rxRootShape = rTarget; pGroupObject = dynamic_cast(SdrObject::getSdrObjectFromXShape(rxRootShape)); if (nullptr != pGroupObject) - pGroupObject->mp_DiagramHelper.reset(this);; + pGroupObject->mp_DiagramHelper.reset(this); } void DiagramHelper_svx::AddAdditionalVisualization(const SdrObjGroup& rTarget, SdrHdlList& rHdlList) diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx index 048350ca0164..471f72e1c8f6 100644 --- a/svx/source/svdraw/svdmodel.cxx +++ b/svx/source/svdraw/svdmodel.cxx @@ -121,7 +121,8 @@ struct SdrModelImpl SdrModel::SdrModel(SfxItemPool* pPool, comphelper::IEmbeddedHelper* pEmbeddedHelper, bool bDisablePropertyFiles) - : m_eObjUnit(SdrEngineDefaults::GetMapUnit()) + : mnImExCnt(0) + , m_eObjUnit(SdrEngineDefaults::GetMapUnit()) , m_eUIUnit(FieldUnit::MM) , m_aUIScale(Fraction(1,1)) , m_nUIUnitDecimalMark(0) diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx index 782275f71dcf..de1fda977380 100644 --- a/svx/source/svdraw/svdogrp.cxx +++ b/svx/source/svdraw/svdogrp.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -763,6 +764,51 @@ rtl::Reference SdrObjGroup::DoConvertToPolyObj(bool bBezier, bool bAd return pGroup; } +bool SdrObjGroup::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const +{ + // has no geometry itself, so just use SnapRect to get from sub-content. + // note that this already *includes* possible offsets from Writer Anchor, + // so do not check for that and correct below + tools::Rectangle aRectangle(GetSnapRect()); + + // convert to transformation values + basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight()); + basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top()); + + // build matrix + rMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(aScale, aTranslate); + + return false; +} + +void SdrObjGroup::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/) +{ + // break up matrix + basegfx::B2DTuple aScale; + basegfx::B2DTuple aTranslate; + double fRotate, fShearX; + rMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings + // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly + if(aScale.getX() < 0.0 && aScale.getY() < 0.0) + { + aScale.setX(fabs(aScale.getX())); + aScale.setY(fabs(aScale.getY())); + } + + // build BaseRect + Point aPoint(basegfx::fround(aTranslate.getX()), + basegfx::fround(aTranslate.getY())); + tools::Rectangle aBaseRect(aPoint, Size(basegfx::fround(aScale.getX()), + basegfx::fround(aScale.getY()))); + + // set BaseRect: Call to SetSnapRect works relative to GetSnapRect() where + // possible offsets from Writer Anchor is already included, it then does a + // relative change to new SnapRect + SetSnapRect(aBaseRect); +} + void SdrObjGroup::SetDescription(const OUString& rStr) { static bool bActivateAdvancedDiagramFeatures(nullptr != std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES")); @@ -774,12 +820,10 @@ void SdrObjGroup::SetDescription(const OUString& rStr) OUString aOrigDescription(rStr); - if (!rStr.isEmpty() && getSdrModelFromSdrObject().isLocked()) + if (!rStr.isEmpty() && getSdrModelFromSdrObject().isInImportExport()) { // 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 @@ -819,12 +863,10 @@ OUString SdrObjGroup::GetDescription() const // call parent to get original description OUString aRetval(SdrObject::GetDescription()); - if (mp_DiagramHelper && getSdrModelFromSdrObject().isLocked()) + if (mp_DiagramHelper && getSdrModelFromSdrObject().isInImportExport()) { // 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 diff --git a/svx/source/xml/xmlexport.cxx b/svx/source/xml/xmlexport.cxx index 3ac3596e105c..984ef05275a1 100644 --- a/svx/source/xml/xmlexport.cxx +++ b/svx/source/xml/xmlexport.cxx @@ -66,6 +66,7 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const uno::Reference( xSourceDoc, UNO_QUERY ); if ( xSourceModel.is() ) xSourceModel->lockControllers(); + pModel->incImportExport(); const uno::Reference< uno::XComponentContext>& xContext( ::comphelper::getProcessComponentContext() ); @@ -131,6 +132,7 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const uno::ReferenceunlockControllers(); + pModel->decImportExport(); return bDocRet; } @@ -175,7 +177,7 @@ bool SvxDrawingLayerImport( SdrModel* pModel, const uno::ReferencelockControllers(); - + pModel->incImportExport(); xGraphicHelper = SvXMLGraphicHelper::Create( SvXMLGraphicHelperMode::Read ); xGraphicStorageHandler = xGraphicHelper.get(); @@ -236,6 +238,7 @@ bool SvxDrawingLayerImport( SdrModel* pModel, const uno::ReferenceunlockControllers(); + pModel->decImportExport(); return bRet; } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 90b8f5ebb73f..3dac31a29111 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -4763,6 +4764,37 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) rSh.GetView().GetViewFrame().GetBindings().InvalidateAll(false); return; // SdrView's event evaluated } + + const Point aDocPos(PixelToLogic(rMEvt.GetPosPixel())); + SdrHdl* pHdl(pSdrView->PickHandle(aDocPos)); + + if (nullptr != pHdl) + { + SdrObject* pSingleObj(nullptr); + const SdrMarkList& rMarkList(pSdrView->GetMarkedObjectList()); + + if (1 == rMarkList.GetMarkCount()) + pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + + if (nullptr != pSingleObj) + { + // Check for click on svx::diagram::DiagramFrameHdl + // - if we hit a SdrHdl + // - if single object is selected + // - and it is a Diagram + if(pHdl && nullptr != pSingleObj && pSingleObj->isDiagram()) + { + svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast(pHdl)); + if(nullptr != pDiagramFrameHdl) + { + // let the DiagramFrameHdl decide what to do + svx::diagram::DiagramFrameHdl::clicked(aDocPos); + } + } + } + } + + } // only process MouseButtonUp when the Down went to that windows as well. if ( !m_bMBPressed )