summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <Armin.Le.Grand@me.com>2022-03-04 16:51:07 +0100
committerArmin Le Grand <Armin.Le.Grand@me.com>2022-03-04 22:10:10 +0100
commit9c526b557e264280cb0c9da704245494f5ec5af3 (patch)
tree2ea8393b8ea5a7e24088b116320fb9bfaeb1f136 /oox
parent35428625b70829ba56da99fafe205b24b0018ace (diff)
Advanced Diagram support: Allow reLayout without keeping oox::Shape
Goal is to minimize dependencies on oox classes. For that pupose I redesigned the Diagram class to work without remembering an oox::Shape at all. For reLayout, a new temporary one is created and used. That was a bit tricky, I needed to find out what data at the oox::Shape is needed to sucessfully do that with the not-originally-imported one. Another necessary change was to move the DiagramFontHeights adapting mechanism away from oox::Shape, too. It fits better to Diagram class. That way it can also be used for reLayout and the oox::Shape gets a little bit smaller, too. This opens the path to move needed Mode-Data Diagam core claasses to other libs where changing/im/exPorting them will be possible. Change-Id: I40bc4b190d2abc797f5c56f9e476d22155d21422 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131004 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx54
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx10
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.cxx87
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.hxx9
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx4
-rw-r--r--oox/source/drawingml/shape.cxx44
-rw-r--r--oox/source/ppt/pptshape.cxx21
7 files changed, 106 insertions, 123 deletions
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 6c6578ae4067..481e56adec3c 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -137,8 +137,8 @@ void Diagram::addTo( const ShapePtr & pParentShape )
aChildren.insert(aChildren.begin(), pBackground);
}
-Diagram::Diagram(const ShapePtr& pShape)
- : mpShape(pShape)
+Diagram::Diagram()
+: maDiagramFontHeights()
{
}
@@ -168,9 +168,48 @@ uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
return aValue;
}
-void Diagram::newTargetShape(ShapePtr& pTarget)
+using ShapePairs
+ = std::map<std::shared_ptr<drawingml::Shape>, css::uno::Reference<css::drawing::XShape>>;
+
+void Diagram::syncDiagramFontHeights()
{
- mpShape = pTarget;
+ // Each name represents a group of shapes, for which the font height should have the same
+ // scaling.
+ for (const auto& rNameAndPairs : maDiagramFontHeights)
+ {
+ // Find out the minimum scale within this group.
+ const ShapePairs& rShapePairs = rNameAndPairs.second;
+ sal_Int16 nMinScale = 100;
+ for (const auto& rShapePair : rShapePairs)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ sal_Int16 nTextFitToSizeScale = 0;
+ xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale;
+ if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale)
+ {
+ nMinScale = nTextFitToSizeScale;
+ }
+ }
+ }
+
+ // Set that minimum scale for all members of the group.
+ if (nMinScale < 100)
+ {
+ for (const auto& rShapePair : rShapePairs)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ xPropertySet->setPropertyValue("TextFitToSizeScale", uno::makeAny(nMinScale));
+ }
+ }
+ }
+ }
+
+ // no longer needed after processing
+ maDiagramFontHeights.clear();
}
static uno::Reference<xml::dom::XDocument> loadFragment(
@@ -257,7 +296,7 @@ void loadDiagram( ShapePtr const & pShape,
const OUString& rColorStylePath,
const oox::core::Relations& rRelations )
{
- DiagramPtr pDiagram = std::make_shared<Diagram>(pShape);
+ DiagramPtr pDiagram = std::make_shared<Diagram>();
DiagramDataPtr pData = std::make_shared<DiagramData>();
pDiagram->setData( pData );
@@ -265,6 +304,9 @@ void loadDiagram( ShapePtr const & pShape,
DiagramLayoutPtr pLayout = std::make_shared<DiagramLayout>(*pDiagram);
pDiagram->setLayout( pLayout );
+ // set DiagramFontHeights at filter
+ rFilter.setDiagramFontHeights(&pDiagram->getDiagramFontHeights());
+
// data
if( !rDataModelPath.isEmpty() )
{
@@ -379,7 +421,7 @@ void loadDiagram(ShapePtr const& pShape,
const uno::Reference<xml::dom::XDocument>& colorDom,
core::XmlFilterBase& rFilter)
{
- DiagramPtr pDiagram = std::make_shared<Diagram>(pShape);
+ DiagramPtr pDiagram = std::make_shared<Diagram>();
pDiagram->setData(pDiagramData);
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index 3b42a834951a..1897a8ccfd01 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -130,7 +130,7 @@ typedef std::map<OUString,DiagramColor> DiagramColorMap;
class Diagram
{
public:
- explicit Diagram(const ShapePtr& pShape);
+ explicit Diagram();
void setData( const DiagramDataPtr & pData )
{ mpData = pData; }
const DiagramDataPtr& getData() const
@@ -149,11 +149,13 @@ public:
void addTo( const ShapePtr & pShape );
css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() const;
- ShapePtr getShape() const { return mpShape.lock(); }
- void newTargetShape(ShapePtr& pTarget);
+ oox::core::NamedShapePairs& getDiagramFontHeights() { return maDiagramFontHeights; }
+ void syncDiagramFontHeights();
private:
- WeakShapePtr mpShape;
+ // This contains groups of shapes: automatic font size is the same in each group.
+ oox::core::NamedShapePairs maDiagramFontHeights;
+
DiagramDataPtr mpData;
DiagramLayoutPtr mpLayout;
DiagramQStyleMap maStyles;
diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx b/oox/source/drawingml/diagram/diagramhelper.cxx
index d67d67b13064..8b54ff4e8a0f 100644
--- a/oox/source/drawingml/diagram/diagramhelper.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper.cxx
@@ -23,6 +23,7 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <oox/shape/ShapeFilterBase.hxx>
#include <oox/ppt/pptimport.hxx>
+#include <drawingml/fillproperties.hxx>
#include <svx/svdmodel.hxx>
#include <comphelper/processfactory.hxx>
@@ -37,10 +38,13 @@ bool AdvancedDiagramHelper::hasDiagramData() const
AdvancedDiagramHelper::AdvancedDiagramHelper(
const std::shared_ptr< Diagram >& rDiagramPtr,
- const std::shared_ptr<::oox::drawingml::Theme>& rTheme)
+ const std::shared_ptr<::oox::drawingml::Theme>& rTheme,
+ Shape& rSourceShape)
: IDiagramHelper()
, mpDiagramPtr(rDiagramPtr)
, mpThemePtr(rTheme)
+, maImportSize(rSourceShape.getSize())
+, maImportPosition(rSourceShape.getPosition())
{
}
@@ -48,44 +52,32 @@ AdvancedDiagramHelper::~AdvancedDiagramHelper()
{
}
-void AdvancedDiagramHelper::reLayout()
+void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
{
if(!mpDiagramPtr)
{
return;
}
- // Get the oox::Shape that represents the Diagram GraphicObject
- const ShapePtr & pParentShape = mpDiagramPtr->getShape();
-
- if(!pParentShape)
- {
- return;
- }
-
- // Remove it's children which represent the oox::Shapes created by
- // the layout process as preparation to re-creation. These should
- // already be cleared, but make sure.
- pParentShape->getChildren().clear();
-
- // Re-create the oox::Shapes for the diagram content
- mpDiagramPtr->addTo(pParentShape);
-
- // Access the GroupObject representing the SmartArt in DrawingLayer
- SdrObjGroup* pAnchorObj(dynamic_cast<SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(pParentShape->getXShape())));
- if(!pAnchorObj)
- {
- SAL_WARN("oox", "missing SdrObjGroup");
- return;
- }
-
// Rescue/remember geometric transformation of existing Diagram
basegfx::B2DHomMatrix aTransformation;
basegfx::B2DPolyPolygon aPolyPolygon;
- pAnchorObj->TRGetBaseGeometry(aTransformation, aPolyPolygon);
+ rTarget.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 frrom initial import
+ // to get the same layout(s)
+ oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
+ pShapePtr->setDiagramType();
+ pShapePtr->setSize(maImportSize);
+ pShapePtr->setPosition(maImportPosition);
+ pShapePtr->getFillProperties() = *mpDiagramPtr->getData()->getFillProperties();
+
+ // Re-create the oox::Shapes for the diagram content
+ mpDiagramPtr->addTo(pShapePtr);
// Delete all existing shapes in that group to prepare re-creation
- pAnchorObj->getChildrenOfSdrObject()->ClearSdrObjList();
+ rTarget.getChildrenOfSdrObject()->ClearSdrObjList();
// For re-creation we need to use ::addShape functionality from the
// oox import filter since currently Shape import is very tightly
@@ -105,7 +97,7 @@ void AdvancedDiagramHelper::reLayout()
// NOTE: The incarnation of import filter (ShapeFilterBase) is only
// used for XShape creation, no xml snippets/data gets imported
// here. XShape creation may be isolated in the future.
- SdrModel& rModel(pAnchorObj->getSdrModelFromSdrObject());
+ SdrModel& rModel(rTarget.getSdrModelFromSdrObject());
uno::Reference< uno::XInterface > const & rUnoModel(rModel.getUnoModel());
css::uno::Reference<css::uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
rtl::Reference<oox::shape::ShapeFilterBase> xFilter(new oox::shape::ShapeFilterBase(xContext));
@@ -113,10 +105,13 @@ void AdvancedDiagramHelper::reLayout()
css::uno::Reference< css::lang::XComponent > aComponentModel( rUnoModel, uno::UNO_QUERY );
xFilter->setTargetDocument(aComponentModel);
+ // set DiagramFontHeights
+ xFilter->setDiagramFontHeights(&mpDiagramPtr->getDiagramFontHeights());
+
// Prepare the target for the to-be-created XShapes
- uno::Reference<drawing::XShapes> xShapes(pParentShape->getXShape(), uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShapes> xShapes(rTarget.getUnoShape(), uno::UNO_QUERY_THROW);
- for (auto const& child : pParentShape->getChildren())
+ for (auto const& child : pShapePtr->getChildren())
{
// Create all sub-shapes. This will recursively create needed geometry using
// filter-internal ::createShapes
@@ -125,17 +120,14 @@ void AdvancedDiagramHelper::reLayout()
xFilter->getCurrentTheme(),
xShapes,
aTransformation,
- pParentShape->getFillProperties());
+ pShapePtr->getFillProperties());
}
// Re-apply remembered geometry
- pAnchorObj->TRSetBaseGeometry(aTransformation, aPolyPolygon);
+ rTarget.TRSetBaseGeometry(aTransformation, aPolyPolygon);
- // Delete oox::Shapes that represented the content of the
- // diagram. These were needed for creating the XShapes/SdrObjects
- // (created by ::addTo above) but are no longer needed, so free
- // the memory
- pParentShape->getChildren().clear();
+ // sync FontHeights
+ mpDiagramPtr->syncDiagramFontHeights();
}
OUString AdvancedDiagramHelper::getString() const
@@ -185,28 +177,11 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
return;
}
- const ShapePtr& pParentShape(mpDiagramPtr->getShape());
-
- if(pParentShape)
- {
- // The oox::Shapes children are not needed for holding the original data,
- // free that memory
- pParentShape->getChildren().clear();
- }
+ mpDiagramPtr->syncDiagramFontHeights();
anchorToSdrObjGroup(rTarget);
}
-void AdvancedDiagramHelper::newTargetShape(ShapePtr& pTarget)
-{
- if(!mpDiagramPtr)
- {
- return;
- }
-
- mpDiagramPtr->newTargetShape(pTarget);
-}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx b/oox/source/drawingml/diagram/diagramhelper.hxx
index 9c4d4cfadb37..5f5632c3338a 100644
--- a/oox/source/drawingml/diagram/diagramhelper.hxx
+++ b/oox/source/drawingml/diagram/diagramhelper.hxx
@@ -46,16 +46,20 @@ class AdvancedDiagramHelper final : public IDiagramHelper
const std::shared_ptr< Diagram > mpDiagramPtr;
const std::shared_ptr<::oox::drawingml::Theme> mpThemePtr;
+ css::awt::Size maImportSize;
+ css::awt::Point maImportPosition;
+
bool hasDiagramData() const;
public:
AdvancedDiagramHelper(
const std::shared_ptr< Diagram >& rDiagramPtr,
- const std::shared_ptr<::oox::drawingml::Theme>& rTheme);
+ const std::shared_ptr<::oox::drawingml::Theme>& rTheme,
+ Shape& rSourceShape);
virtual ~AdvancedDiagramHelper();
// re-create XShapes
- virtual void reLayout() override;
+ virtual void reLayout(SdrObjGroup& rTarget) override;
// get text representation of data tree
virtual OUString getString() const override;
@@ -70,7 +74,6 @@ public:
virtual bool removeNode(const OUString& rNodeId) override;
void doAnchor(SdrObjGroup& rTarget);
- void newTargetShape(ShapePtr& pTarget);
};
}
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index f5191b54408a..a91925b32376 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -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().getShape()->getDiagramFontHeights();
+ = rAlg.getLayoutNode().getDiagram().getDiagramFontHeights();
auto it = rDiagramFontHeights.find(aCurrShape->getInternalName());
if (it != rDiagramFontHeights.end())
{
@@ -1421,7 +1421,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
&& rConstraint.mnOperator == XML_equ)
{
NamedShapePairs& rDiagramFontHeights
- = getLayoutNode().getDiagram().getShape()->getDiagramFontHeights();
+ = getLayoutNode().getDiagram().getDiagramFontHeights();
auto it = rDiagramFontHeights.find(rConstraint.msForName);
if (it == rDiagramFontHeights.end())
{
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 243a172e6e75..d0ab82501c71 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -191,7 +191,6 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mnDataNodeType(pSourceShape->mnDataNodeType)
, mfAspectRatio(pSourceShape->mfAspectRatio)
, mbUseBgFill(pSourceShape->mbUseBgFill)
-, maDiagramFontHeights(pSourceShape->maDiagramFontHeights)
, mpDiagramHelper( nullptr )
{}
@@ -209,7 +208,7 @@ void Shape::prepareDiagramHelper(
// Prepare Diagam data collecting for this Shape
if( nullptr == mpDiagramHelper && FRAMETYPE_DIAGRAM == meFrameType )
{
- mpDiagramHelper = new AdvancedDiagramHelper(rDiagramPtr, rTheme);
+ mpDiagramHelper = new AdvancedDiagramHelper(rDiagramPtr, rTheme, *this);
}
}
@@ -259,9 +258,6 @@ void Shape::migrateDiagramHelperToNewShape(ShapePtr& pTarget)
pTarget->mpDiagramHelper = nullptr;
}
- // DiagramHelper has references to this, these need to be replaced
- static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->newTargetShape(pTarget);
-
// exchange and reset to nullptr
pTarget->mpDiagramHelper = mpDiagramHelper;
mpDiagramHelper = nullptr;
@@ -1857,44 +1853,6 @@ void Shape::keepDiagramCompatibilityInfo()
}
}
-void Shape::syncDiagramFontHeights()
-{
- // Each name represents a group of shapes, for which the font height should have the same
- // scaling.
- for (const auto& rNameAndPairs : maDiagramFontHeights)
- {
- // Find out the minimum scale within this group.
- const ShapePairs& rShapePairs = rNameAndPairs.second;
- sal_Int16 nMinScale = 100;
- for (const auto& rShapePair : rShapePairs)
- {
- uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
- if (xPropertySet.is())
- {
- sal_Int16 nTextFitToSizeScale = 0;
- xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale;
- if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale)
- {
- nMinScale = nTextFitToSizeScale;
- }
- }
- }
-
- // Set that minimum scale for all members of the group.
- if (nMinScale < 100)
- {
- for (const auto& rShapePair : rShapePairs)
- {
- uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY);
- if (xPropertySet.is())
- {
- xPropertySet->setPropertyValue("TextFitToSizeScale", uno::makeAny(nMinScale));
- }
- }
- }
- }
-}
-
void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
{
try
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index d8ab4dfef7ca..581b85db0e0a 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -538,15 +538,19 @@ void PPTShape::addShape(
Reference<XShapes> xShapes(xShape, UNO_QUERY);
if (xShapes.is())
{
- if (meFrameType == FRAMETYPE_DIAGRAM)
- {
- rFilterBase.setDiagramFontHeights(&getDiagramFontHeights());
- }
- addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation );
- if (meFrameType == FRAMETYPE_DIAGRAM)
- {
+ // tempoarily remember setting
+ NamedShapePairs* pDiagramFontHeights(rFilterBase.getDiagramFontHeights());
+
+ // for shapes unequal to FRAMETYPE_DIAGRAM do
+ // disable DiagramFontHeights recording
+ if (meFrameType != FRAMETYPE_DIAGRAM)
rFilterBase.setDiagramFontHeights(nullptr);
- }
+
+ addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation );
+
+ // restore remembered setting
+ rFilterBase.setDiagramFontHeights(pDiagramFontHeights);
+
for (size_t i = 0; i < this->getChildren().size(); i++)
{
this->getChildren()[i]->getShapeProperties().getProperty(PROP_URL) >>= sURL;
@@ -561,7 +565,6 @@ void PPTShape::addShape(
if (meFrameType == FRAMETYPE_DIAGRAM)
{
keepDiagramCompatibilityInfo();
- syncDiagramFontHeights();
}
// Support advanced DiagramHelper