SmartArt: Move Information from GrabBag to DiagramHelper

Information about an imported Diagram was buffered at the
SdrObject in the GrabBag, mainly the original imported DomTrees.
This was done before a place like DiagramHelper existed and has
no practical background.
It is now held at the place where it belongs, at the
DiagramHelper associated with the SdrObjGroup. It makes it
easier to reset the no longer valid DomTrees when the Diagram
model data changes, also automatically that info is removed
when the SdrObjGroup is no Diagram anymore, together with the
DiagramHelper.
I also have and maybe will need UnitTests, so put this on
gerrit early.

ShapeContextHandler::getShape needed correction, it has to
1st migrate the DiagramHelper and then use it.

Had to correct testTextEditEmptyGrabBag. There are no
GrabBag Items anymore for the Diagram, but still from
OOX import, e.g. OOXRotationAngle. Not sure if these
will be needed in the future, but for now had to reset
GrabBag for changed attributes.

Need to secure access to uno::Sequence when accessing
xml::dom::XDocument in DrawingML::WriteDiagram to
avoid access to non existing index if not used.

I used the wrong name for the DiagramDataRels entries,
corrected these to "OOXDiagramDataRels".

Change-Id: I60b17e1211314ae50e7d1a9a43fd14a8b56c9d78
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195579
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This commit is contained in:
Armin Le Grand (collabora)
2025-12-17 15:26:44 +01:00
committed by Armin Le Grand
parent 28cd273a75
commit c60be14f9c
15 changed files with 162 additions and 181 deletions
+3 -6
View File
@@ -231,9 +231,9 @@ public:
SAL_DLLPRIVATE void setWps(bool bWps);
bool getWps() const { return mbWps;}
SAL_DLLPRIVATE void setTextBox(bool bTextBox);
const css::uno::Sequence<css::beans::PropertyValue> &
getDiagramDoms() const { return maDiagramDoms; }
void setDiagramDoms(const css::uno::Sequence<css::beans::PropertyValue>& rDiagramDoms) { maDiagramDoms = rDiagramDoms; }
// access to DiagramHelper
AdvancedDiagramHelper* getDiagramHelper() const { return mpDiagramHelper; }
SAL_DLLPRIVATE css::uno::Sequence< css::uno::Sequence< css::uno::Any > >resolveRelationshipsOfTypeFromOfficeDoc(
core::XmlFilterBase& rFilter, const OUString& sFragment, std::u16string_view sType );
void setLinkedTxbxAttributes(const LinkedTxbxAttr& rhs){ maLinkedTxbxAttr = rhs; };
@@ -310,7 +310,6 @@ protected:
ShapeIdMap* pShapeMap,
const basegfx::B2DHomMatrix& aTransformation );
SAL_DLLPRIVATE void keepDiagramCompatibilityInfo();
SAL_DLLPRIVATE void convertSmartArtToMetafile( ::oox::core::XmlFilterBase const& rFilterBase );
SAL_DLLPRIVATE css::uno::Reference< css::drawing::XShape >
@@ -430,8 +429,6 @@ private:
bool mbHasLinkedTxbx; // this text box has linked text box ?
bool mbHasCustomPrompt; // indicates that it's not a generic placeholder
css::uno::Sequence<css::beans::PropertyValue> maDiagramDoms;
/// Z-Order.
sal_Int32 mnZOrder = 0;
+3
View File
@@ -136,6 +136,9 @@ public:
virtual void TextInformationChange(const OUString& rDiagramDataModelID, SdrOutliner& rOutl) = 0;
static void AddAdditionalVisualization(const SdrObjGroup& rTarget, SdrHdlList& rHdlList);
// access to PropertyValues
virtual css::beans::PropertyValue getDomPropertyValue(const OUString& rName) const = 0;
};
}} // end of namespace
+22 -26
View File
@@ -149,30 +149,14 @@ Diagram::Diagram()
{
}
uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
beans::PropertyValue Diagram::getDomPropertyValue(const OUString& rName) const
{
sal_Int32 length = maMainDomMap.size();
const DiagramPRDomMap::const_iterator aHit = maDiagramPRDomMap.find(rName);
if (maDataRelsMap.hasElements())
++length;
if (aHit != maDiagramPRDomMap.end())
return aHit->second;
uno::Sequence<beans::PropertyValue> aValue(length);
beans::PropertyValue* pValue = aValue.getArray();
for (auto const& mainDom : maMainDomMap)
{
pValue->Name = mainDom.first;
pValue->Value <<= mainDom.second;
++pValue;
}
if (maDataRelsMap.hasElements())
{
pValue->Name = "OOXDiagramDataRels";
pValue->Value <<= maDataRelsMap;
++pValue;
}
return aValue;
return beans::PropertyValue();
}
using ShapePairs
@@ -226,6 +210,12 @@ void Diagram::syncDiagramFontHeights()
maDiagramFontHeights.clear();
}
void Diagram::addDomPropertyValue(beans::PropertyValue& aValue)
{
if (!aValue.Name.isEmpty())
maDiagramPRDomMap[aValue.Name] = aValue;
}
static uno::Reference<xml::dom::XDocument> loadFragment(
core::XmlFilterBase& rFilter,
const OUString& rFragmentPath )
@@ -248,8 +238,10 @@ static void importFragment( core::XmlFilterBase& rFilter,
const DiagramPtr& pDiagram,
const rtl::Reference< core::FragmentHandler >& rxHandler )
{
DiagramDomMap& rMainDomMap = pDiagram->getDomMap();
rMainDomMap[rDocName] = rXDom;
beans::PropertyValue aValue;
aValue.Name = rDocName;
aValue.Value <<= rXDom;
pDiagram->addDomPropertyValue(aValue);
uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(
rXDom, uno::UNO_QUERY_THROW);
@@ -335,8 +327,13 @@ void loadDiagram( ShapePtr const & pShape,
pDiagram,
xRefDataModel);
pDiagram->getDataRelsMap() = pShape->resolveRelationshipsOfTypeFromOfficeDoc( rFilter,
xRefDataModel->getFragmentPath(), u"image" );
uno::Sequence< uno::Sequence< uno::Any > > aDataRelsMap(
pShape->resolveRelationshipsOfTypeFromOfficeDoc( rFilter, xRefDataModel->getFragmentPath(), u"image" ));
beans::PropertyValue aValue;
aValue.Name = "OOXDiagramDataRels";
aValue.Value <<= aDataRelsMap;
pDiagram->addDomPropertyValue(aValue);
// Pass the info to pShape
for (auto const& extDrawing : pData->getExtDrawings())
@@ -431,7 +428,6 @@ void loadDiagram( ShapePtr const & pShape,
// up
const bool bCreate(pShape->getExtDrawings().empty());
pDiagram->addTo(pShape, bCreate);
pShape->setDiagramDoms(pDiagram->getDomsAsPropertyValues());
// Get the oox::Theme definition and - if available - move/secure the
// original ImportData directly to the Diagram ModelData
+7 -6
View File
@@ -40,7 +40,6 @@ class LayoutNode;
typedef std::shared_ptr< LayoutNode > LayoutNodePtr;
class LayoutAtom;
typedef std::shared_ptr< LayoutAtom > LayoutAtomPtr;
typedef std::map< OUString, css::uno::Reference<css::xml::dom::XDocument> > DiagramDomMap;
typedef std::map< OUString, LayoutAtomPtr > LayoutAtomMap;
typedef std::map< const svx::diagram::Point*, ShapePtr > PresPointShapeMap;
@@ -124,6 +123,7 @@ struct DiagramColor
};
typedef std::map<OUString,DiagramColor> DiagramColorMap;
typedef std::map<OUString,css::beans::PropertyValue> DiagramPRDomMap;
class Diagram
{
@@ -142,14 +142,16 @@ public:
const DiagramQStyleMap& getStyles() const { return maStyles; }
DiagramColorMap& getColors() { return maColors; }
const DiagramColorMap& getColors() const { return maColors; }
DiagramDomMap & getDomMap() { return maMainDomMap; }
css::uno::Sequence< css::uno::Sequence< css::uno::Any > > & getDataRelsMap() { return maDataRelsMap; }
DiagramPRDomMap & getRPDomMap() { return maDiagramPRDomMap; }
void addTo( const ShapePtr & pShape, bool bCreate );
css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() const;
oox::core::NamedShapePairs& getDiagramFontHeights() { return maDiagramFontHeights; }
void syncDiagramFontHeights();
void addDomPropertyValue(css::beans::PropertyValue& aValue);
css::beans::PropertyValue getDomPropertyValue(const OUString& rName) const;
void resetDomPropertyValues() { maDiagramPRDomMap.clear(); }
private:
// This contains groups of shapes: automatic font size is the same in each group.
oox::core::NamedShapePairs maDiagramFontHeights;
@@ -158,8 +160,7 @@ private:
DiagramLayoutPtr mpLayout;
DiagramQStyleMap maStyles;
DiagramColorMap maColors;
DiagramDomMap maMainDomMap;
css::uno::Sequence< css::uno::Sequence< css::uno::Any > > maDataRelsMap;
DiagramPRDomMap maDiagramPRDomMap;
};
typedef std::shared_ptr< Diagram > DiagramPtr;
+20 -2
View File
@@ -244,9 +244,13 @@ void AdvancedDiagramHelper::TextInformationChange(const OUString& rDiagramDataMo
// try text change for model part in DiagramData
const bool bChanged(mpDiagramPtr->getData()->TextInformationChange(rDiagramDataModelID, rOutl));
if(bChanged && nullptr != mpAssociatedSdrObjGroup)
if(bChanged)
{
// if change was done, reset GrabBagItem to delete buffered DiagramData which is no longer valid
// reset Dom properties at DiagramData
mpDiagramPtr->resetDomPropertyValues();
// still reset GrabBag at Associated SdrObjGroup object. There are no "OOX.*"
// entries anymore, but others like "mso-rotation-angle" and others
mpAssociatedSdrObjGroup->SetGrabBagItem(uno::Any(uno::Sequence<beans::PropertyValue>()));
// also set self to modified to get correct exports
@@ -302,6 +306,20 @@ const std::shared_ptr< ::oox::drawingml::Theme >& AdvancedDiagramHelper::getOrCr
return mpThemePtr;
}
void AdvancedDiagramHelper::addDomPropertyValue(beans::PropertyValue& aValue)
{
if (mpDiagramPtr)
mpDiagramPtr->addDomPropertyValue(aValue);
}
beans::PropertyValue AdvancedDiagramHelper::getDomPropertyValue(const OUString& rName) const
{
if (mpDiagramPtr)
return mpDiagramPtr->getDomPropertyValue(rName);
return beans::PropertyValue();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -85,6 +85,10 @@ public:
// react on changes to objects identified by DiagramDataModelID, returns true if a change was done
virtual void TextInformationChange(const OUString& rDiagramDataModelID, SdrOutliner& rOutl) override;
// access to get/set PropertyValues
void addDomPropertyValue(css::beans::PropertyValue& aValue);
css::beans::PropertyValue getDomPropertyValue(const OUString& rName) const override;
};
}
+9 -43
View File
@@ -161,7 +161,6 @@ Shape::Shape()
, mbTextBox( false )
, mbHasLinkedTxbx( false )
, mbHasCustomPrompt( false )
, maDiagramDoms( 0 )
, mpDiagramHelper( nullptr )
{
setDefaults(/*bDefaultHeight*/true);
@@ -195,7 +194,6 @@ Shape::Shape( const OUString& rServiceName, bool bDefaultHeight )
, mbTextBox( false )
, mbHasLinkedTxbx( false )
, mbHasCustomPrompt( false )
, maDiagramDoms( 0 )
, mpDiagramHelper( nullptr )
{
msServiceName = rServiceName;
@@ -240,7 +238,6 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mbTextBox( pSourceShape->mbTextBox )
, mbHasLinkedTxbx(false)
, mbHasCustomPrompt( pSourceShape->mbHasCustomPrompt )
, maDiagramDoms( pSourceShape->maDiagramDoms )
, mnZOrder(pSourceShape->mnZOrder)
, mnZOrderOff(pSourceShape->mnZOrderOff)
, mnDataNodeType(pSourceShape->mnDataNodeType)
@@ -492,8 +489,6 @@ void Shape::addShape(
if( meFrameType == FRAMETYPE_DIAGRAM )
{
keepDiagramCompatibilityInfo();
// set DiagramHelper at SdrObjGroup
propagateDiagramHelper();
@@ -2412,9 +2407,9 @@ Reference< XShape > const & Shape::createAndInsert(
void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& rFragmentPath)
{
sal_Int32 length = maDiagramDoms.getLength();
maDiagramDoms.realloc(length + 1);
AdvancedDiagramHelper* pAdvancedDiagramHelper(getDiagramHelper());
if (nullptr == pAdvancedDiagramHelper)
return;
// drawingValue[0] => dom, drawingValue[1] => Sequence of associated relationships
uno::Sequence<uno::Any> diagramDrawing{
@@ -2422,40 +2417,10 @@ void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& rFrag
uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, rFragmentPath, u"image"))
};
beans::PropertyValue* pValue = maDiagramDoms.getArray();
pValue[length].Name = "OOXDrawing";
pValue[length].Value <<= diagramDrawing;
}
void Shape::keepDiagramCompatibilityInfo()
{
try
{
if( !maDiagramDoms.hasElements() )
return;
Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
if ( !xSetInfo.is() )
return;
const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
return;
Sequence < PropertyValue > aGrabBag;
xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
// We keep the previous items, if present
if ( aGrabBag.hasElements() )
xSet->setPropertyValue( aGrabBagPropName, Any( comphelper::concatSequences(aGrabBag, maDiagramDoms) ) );
else
xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
}
catch( const Exception& )
{
TOOLS_WARN_EXCEPTION( "oox.drawingml", "Shape::keepDiagramCompatibilityInfo" );
}
beans::PropertyValue aValue;
aValue.Name = "OOXDrawing";
aValue.Value <<= diagramDrawing;
pAdvancedDiagramHelper->addDomPropertyValue(aValue);
}
void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
@@ -2494,7 +2459,8 @@ Reference < XShape > Shape::renderDiagramToGraphic( XmlFilterBase const & rFilte
try
{
if( !maDiagramDoms.hasElements() )
if( nullptr != getDiagramHelper() )
// if( !maDiagramDoms.hasElements() )
return xShape;
// Stream in which to place the rendered shape
+16 -19
View File
@@ -139,6 +139,7 @@
#include <drawingml/presetgeometrynames.hxx>
#include <docmodel/uno/UnoGradientTools.hxx>
#include <svx/svdpage.hxx>
#include <svx/diagram/IDiagramHelper.hxx>
using namespace ::css;
using namespace ::css::beans;
@@ -6680,28 +6681,24 @@ void DrawingML::WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rX
uno::Sequence<uno::Sequence<uno::Any>> xDataRelSeq;
uno::Sequence<uno::Any> diagramDrawing;
// retrieve the doms from the GrabBag
uno::Sequence<beans::PropertyValue> propList;
xPropSet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= propList;
for (const auto& rProp : propList)
SdrObject* pObj = SdrObject::getSdrObjectFromXShape(rXShape);
if (nullptr != pObj && pObj->isDiagram())
{
OUString propName = rProp.Name;
if (propName == "OOXData")
rProp.Value >>= dataDom;
else if (propName == "OOXLayout")
rProp.Value >>= layoutDom;
else if (propName == "OOXStyle")
rProp.Value >>= styleDom;
else if (propName == "OOXColor")
rProp.Value >>= colorDom;
else if (propName == "OOXDrawing")
const std::shared_ptr< svx::diagram::IDiagramHelper >& rIDiagramHelper(pObj->getDiagramHelper());
if (rIDiagramHelper)
{
rProp.Value >>= diagramDrawing;
diagramDrawing[0]
>>= drawingDom; // if there is OOXDrawing property then set drawingDom here only.
rIDiagramHelper->getDomPropertyValue("OOXData").Value >>= dataDom;
rIDiagramHelper->getDomPropertyValue("OOXLayout").Value >>= layoutDom;
rIDiagramHelper->getDomPropertyValue("OOXStyle").Value >>= styleDom;
rIDiagramHelper->getDomPropertyValue("OOXColor").Value >>= colorDom;
rIDiagramHelper->getDomPropertyValue("OOXDrawing").Value >>= diagramDrawing;
if (diagramDrawing.hasElements())
// if there is OOXDrawing property then set drawingDom here only.
diagramDrawing[0] >>= drawingDom;
rIDiagramHelper->getDomPropertyValue("OOXDiagramDataRels").Value >>= xDataRelSeq;
}
else if (propName == "OOXDiagramDataRels")
rProp.Value >>= xDataRelSeq;
}
// check that we have the 4 mandatory XDocuments
-5
View File
@@ -603,11 +603,6 @@ void PPTShape::addShape(
}
}
if (meFrameType == FRAMETYPE_DIAGRAM)
{
keepDiagramCompatibilityInfo();
}
// Support advanced DiagramHelper
if (FRAMETYPE_DIAGRAM == meFrameType)
{
+3 -2
View File
@@ -474,8 +474,6 @@ ShapeContextHandler::getShape()
oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
pShapePtr->setDiagramType();
mxShapeFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxShapeFilterBase, aFragmentPath, pShapePtr));
pShapePtr->setDiagramDoms(mpShape->getDiagramDoms());
pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, aFragmentPath);
if (mpShape->getFontRefColorForNodes().isUsed())
applyFontRefColor(pShapePtr, mpShape->getFontRefColorForNodes());
@@ -484,6 +482,9 @@ ShapeContextHandler::getShape()
// to pShapePtr where the geometry is now constructed)
mpShape->migrateDiagramHelperToNewShape(pShapePtr);
// use now migrated AdvancedDiagramHelper
pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, aFragmentPath);
if (!mpShape->getChildren().empty())
{
// first child is diagram background - we want to keep it, as drawingML fallback doesn't contain it
+6 -2
View File
@@ -318,9 +318,13 @@ void DrawingFragment::onEndElement()
// initial diagram import produces a background shape with zero size and no
// diagram shapes at all. Here the size has been determined from the anchor and
// thus repeating the import of diagram.xml gives the diagram shapes.
if (mxShape->getDiagramDoms().getLength() > 0
//
// I have checked that mpDiagramHelper at mxShape is *not* resetted here
// which is crucial to keep that stuff working. Also added a isDiagram
// method to avoid indirect test for Diagram using former getDiagramDoms()
if (nullptr != mxShape->getDiagramHelper()
&& mxShape->getChildren().size() == 1
&& mxShape->getExtDrawings().size() == 1)
&& mxShape->getExtDrawings().size() != 0)
{
mxShape->getChildren()[0]->setSize(mxShape->getSize());
OUString sFragmentPath(
+14 -9
View File
@@ -22,6 +22,7 @@
#include <svx/svdogrp.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <svx/diagram/IDiagramHelper.hxx>
using namespace ::com::sun::star;
@@ -1062,15 +1063,19 @@ CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testInteropGrabBag)
uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), uno::UNO_QUERY);
CPPUNIT_ASSERT(xGroup.is());
uno::Reference<beans::XPropertySet> xPropertySet(xGroup, uno::UNO_QUERY_THROW);
uno::Sequence<beans::PropertyValue> aGrabBagSeq;
xPropertySet->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBagSeq;
comphelper::SequenceAsHashMap aGrabBag(aGrabBagSeq);
CPPUNIT_ASSERT(aGrabBag.find(u"OOXData"_ustr) != aGrabBag.end());
CPPUNIT_ASSERT(aGrabBag.find(u"OOXLayout"_ustr) != aGrabBag.end());
CPPUNIT_ASSERT(aGrabBag.find(u"OOXStyle"_ustr) != aGrabBag.end());
CPPUNIT_ASSERT(aGrabBag.find(u"OOXColor"_ustr) != aGrabBag.end());
CPPUNIT_ASSERT(aGrabBag.find(u"OOXDrawing"_ustr) != aGrabBag.end());
SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xGroup);
CPPUNIT_ASSERT(nullptr != pObj);
CPPUNIT_ASSERT(pObj->isDiagram());
const std::shared_ptr<svx::diagram::IDiagramHelper>& rIDiagramHelper(pObj->getDiagramHelper());
// const AdvancedDiagramHelper* pHelper(dynamic_cast<AdvancedDiagramHelper*>(rIDiagramHelper.get()));
CPPUNIT_ASSERT(rIDiagramHelper);
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXData").Value.hasValue());
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXLayout").Value.hasValue());
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXStyle").Value.hasValue());
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXColor").Value.hasValue());
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXDrawing").Value.hasValue());
}
CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBackground)
+18 -9
View File
@@ -34,6 +34,7 @@
#include <svx/svdview.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlnstwit.hxx>
#include <svx/svdogrp.hxx>
#include <comphelper/propertyvalue.hxx>
#include <sfx2/viewsh.hxx>
#include <svl/itempool.hxx>
@@ -257,11 +258,20 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTextEditEmptyGrabBag)
uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY);
// get the GrabBag. After import is *has* to be set, check that
// get the GrabBag. After import there may be values, but none anymore
// starting with 'OOX.*', these are now at the DiagramHelper
uno::Sequence<beans::PropertyValue> aGrabBag;
uno::Reference<beans::XPropertySet> xGroupProps(xGroupShape, uno::UNO_QUERY);
xGroupProps->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
CPPUNIT_ASSERT(aGrabBag.hasElements());
if (aGrabBag.hasElements())
{
for (sal_Int32 i = 0; i < aGrabBag.getLength(); ++i)
{
if (aGrabBag[i].Name.startsWith("OOX"))
CPPUNIT_ASSERT(false);
}
}
// get the 1st text shape (containing 'A'). There is a BGShape and an Arrow
// in indices before
@@ -277,15 +287,14 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTextEditEmptyGrabBag)
rEditView.InsertText(u"X"_ustr);
pSdrView->SdrEndTextEdit();
// Then make sure that grab-bag is empty to avoid losing the new text.
// make sure the grab-bag is empty after change
xGroupProps->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
// Without the accompanying fix in place, this test would have failed with:
// assertion failed
// - Expression: !aGrabBag.hasElements()
// i.e. the grab-bag was still around after modifying the shape, and that grab-bag contained the
// old text.
CPPUNIT_ASSERT(!aGrabBag.hasElements());
// get SdrObjGroup and check, it should still be a Diagram
SdrObjGroup* pGroup = dynamic_cast<SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(xShape));
CPPUNIT_ASSERT(nullptr != pGroup);
CPPUNIT_ASSERT(pGroup->isDiagram());
}
CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObject)
-2
View File
@@ -421,8 +421,6 @@ void IDiagramHelper::disconnectFromSdrObjGroup()
{
if (nullptr != mpAssociatedSdrObjGroup)
{
// if change was done, reset GrabBagItem to delete buffered DiagramData which is no longer valid
mpAssociatedSdrObjGroup->SetGrabBagItem(uno::Any(uno::Sequence<beans::PropertyValue>()));
auto const p = mpAssociatedSdrObjGroup;
mpAssociatedSdrObjGroup = nullptr;
p->mp_DiagramHelper.reset();
+37 -50
View File
@@ -23,6 +23,8 @@
#include <ftninfo.hxx>
#include <docsh.hxx>
#include <unotxdoc.hxx>
#include <svx/svdobj.hxx>
#include <svx/diagram/IDiagramHelper.hxx>
class Test : public SwModelTestBase
{
@@ -466,57 +468,42 @@ DECLARE_OOXMLEXPORT_TEST(testSmartart, "smartart.docx")
uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xGroup->getCount()); // 1 rendered bitmap from the original shapes
uno::Reference<beans::XPropertySet> xGroupPropertySet(getShape(1), uno::UNO_QUERY);
xGroupPropertySet->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xGroup);
CPPUNIT_ASSERT(nullptr != pObj);
CPPUNIT_ASSERT(pObj->isDiagram());
bool bData = false, bLayout = false, bQStyle = false, bColor = false, bDrawing = false;
for (beans::PropertyValue const& prop : aGrabBag)
{
if (prop.Name == "OOXData")
{
bData = true;
uno::Reference<xml::dom::XDocument> aDataDom;
CPPUNIT_ASSERT(prop.Value >>= aDataDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aDataDom); // Reference not empty
}
else if (prop.Name == "OOXLayout")
{
bLayout = true;
uno::Reference<xml::dom::XDocument> aLayoutDom;
CPPUNIT_ASSERT(prop.Value >>= aLayoutDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aLayoutDom); // Reference not empty
}
else if (prop.Name == "OOXStyle")
{
bQStyle = true;
uno::Reference<xml::dom::XDocument> aStyleDom;
CPPUNIT_ASSERT(prop.Value >>= aStyleDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aStyleDom); // Reference not empty
}
else if (prop.Name == "OOXColor")
{
bColor = true;
uno::Reference<xml::dom::XDocument> aColorDom;
CPPUNIT_ASSERT(prop.Value >>= aColorDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aColorDom); // Reference not empty
}
else if (prop.Name == "OOXDrawing")
{
bDrawing = true;
uno::Sequence< uno::Any > diagramDrawing;
uno::Reference<xml::dom::XDocument> aDrawingDom;
CPPUNIT_ASSERT(prop.Value >>= diagramDrawing);
CPPUNIT_ASSERT(diagramDrawing[0] >>= aDrawingDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aDrawingDom); // Reference not empty
}
}
// Grab Bag has all the expected elements:
CPPUNIT_ASSERT(bData);
CPPUNIT_ASSERT(bLayout);
CPPUNIT_ASSERT(bQStyle);
CPPUNIT_ASSERT(bColor);
CPPUNIT_ASSERT(bDrawing);
const std::shared_ptr< svx::diagram::IDiagramHelper >& rIDiagramHelper(pObj->getDiagramHelper());
CPPUNIT_ASSERT(rIDiagramHelper);
beans::PropertyValue aPropVal;
uno::Reference<xml::dom::XDocument> aDomTree;
aPropVal = rIDiagramHelper->getDomPropertyValue("OOXData");
CPPUNIT_ASSERT(aPropVal.Value.hasValue());
CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper type
CPPUNIT_ASSERT(aDomTree); // Reference not empty
aPropVal = rIDiagramHelper->getDomPropertyValue("OOXLayout");
CPPUNIT_ASSERT(aPropVal.Value.hasValue());
CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper type
CPPUNIT_ASSERT(aDomTree); // Reference not empty
aPropVal = rIDiagramHelper->getDomPropertyValue("OOXStyle");
CPPUNIT_ASSERT(aPropVal.Value.hasValue());
CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper type
CPPUNIT_ASSERT(aDomTree); // Reference not empty
aPropVal = rIDiagramHelper->getDomPropertyValue("OOXColor");
CPPUNIT_ASSERT(aPropVal.Value.hasValue());
CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper type
CPPUNIT_ASSERT(aDomTree); // Reference not empty
aPropVal = rIDiagramHelper->getDomPropertyValue("OOXDrawing");
CPPUNIT_ASSERT(aPropVal.Value.hasValue());
uno::Sequence< uno::Any > diagramDrawing;
CPPUNIT_ASSERT(aPropVal.Value >>= diagramDrawing);
CPPUNIT_ASSERT(diagramDrawing[0] >>= aDomTree); // PropertyValue of proper type
CPPUNIT_ASSERT(aDomTree); // Reference not empty
uno::Reference<beans::XPropertySet> xPropertySet(xGroup->getByIndex(0), uno::UNO_QUERY);
OUString nValue;