oox: Smart-Art DOMs stored in the InteropGrabBag

The XDocuments representing the DOM documents of a
DrawingML diagram (Smart-Art) are now stored as
the PropertyValues "OOXData", "OOXLayout",
"OOXStyle",  "OOXColor" and "OOXDrawing" into the
"InteropGraBag" property of the parent
SvxGroupShape created from such diagram.

Modified the oox::drawingml::dgm::Diagram class to
be able to hold the map storing the XDocuments and
its names. Added the getDomMap() method to obtain
the map directly and the getDomsAsPropertyValues
method to get the map as a sequence of Property
Values.

Modified the methods for importing and loading the
Smart-Art into the Diagram so they add
automatically the DOM documents to it.

Modified the oox::drawingml::Shape class to be
able to hold the sequence of PropertyValues
storing the XDocuments and its names coming from
the oox::drawingml::dgm::Diagram class. Added the
getDiagramDoms() and setDiagramDoms() methods.

Enhanced the
oox::shape::ShapeContextHandler::getShape() method
to add the extended drawing document to the
oox::drawingml::Shape class.

Modified the
oox::drawingml::Shape::createAndInsert() method to
store the sequence of XDocuments in the
"InteropGrabBag" property of the GroupShape
service SvxGroupShape implementation representing
a Smart-Art.

Change-Id: I7d0b9dfbfc9d5299ddd25fab394e5e9a422d1dd1
Reviewed-on: https://gerrit.libreoffice.org/5849
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
This commit is contained in:
Andres Gomez
2013-09-03 11:13:22 +03:00
committed by Miklos Vajna
parent fca4b8d48b
commit ab0998c77c
6 changed files with 176 additions and 40 deletions

View File

@@ -174,6 +174,9 @@ public:
void addExtDrawingRelId( const OUString &rRelId ) { maExtDrawings.push_back( rRelId ); } void addExtDrawingRelId( const OUString &rRelId ) { maExtDrawings.push_back( rRelId ); }
void setLockedCanvas(bool bLockedCanvas); void setLockedCanvas(bool bLockedCanvas);
bool getLockedCanvas(); bool getLockedCanvas();
const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> &
getDiagramDoms() { return maDiagramDoms; }
void setDiagramDoms(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rDiagramDoms) { maDiagramDoms = rDiagramDoms; }
protected: protected:
@@ -265,6 +268,8 @@ private:
// we need separate flag because we don't want // we need separate flag because we don't want
// to propagate it when applying reference shape // to propagate it when applying reference shape
bool mbLockedCanvas; ///< Is this shape part of a locked canvas? bool mbLockedCanvas; ///< Is this shape part of a locked canvas?
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> maDiagramDoms;
}; };
// ============================================================================ // ============================================================================

View File

@@ -26,6 +26,7 @@
#include <com/sun/star/xml/dom/XDocument.hpp> #include <com/sun/star/xml/dom/XDocument.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp> #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
#include <rtl/ustrbuf.hxx> #include <rtl/ustrbuf.hxx>
#include <editeng/unoprnms.hxx>
#include "oox/drawingml/textbody.hxx" #include "oox/drawingml/textbody.hxx"
#include "oox/drawingml/textparagraph.hxx" #include "oox/drawingml/textparagraph.hxx"
#include "oox/drawingml/textrun.hxx" #include "oox/drawingml/textrun.hxx"
@@ -329,23 +330,53 @@ void Diagram::addTo( const ShapePtr & pParentShape )
ShapeCreationVisitor aCreationVisitor(pParentShape, *this); ShapeCreationVisitor aCreationVisitor(pParentShape, *this);
if( mpLayout->getNode() ) if( mpLayout->getNode() )
mpLayout->getNode()->accept( aCreationVisitor ); mpLayout->getNode()->accept( aCreationVisitor );
pParentShape->setDiagramDoms( getDomsAsPropertyValues() );
}
uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
{
sal_Int32 length = maMainDomMap.size();
uno::Sequence<beans::PropertyValue> aValue(length);
beans::PropertyValue* pValue = aValue.getArray();
for (DiagramDomMap::const_iterator i = maMainDomMap.begin();
i != maMainDomMap.end();
++i)
{
pValue[0].Name = i->first;
pValue[0].Value = uno::makeAny(i->second);
++pValue;
}
return aValue;
}
uno::Reference<xml::dom::XDocument> loadFragment(
core::XmlFilterBase& rFilter,
const OUString& rFragmentPath )
{
// load diagramming fragments into DOM representation, that later
// gets serialized back to SAX events and parsed
return rFilter.importFragment( rFragmentPath );
} }
uno::Reference<xml::dom::XDocument> loadFragment( uno::Reference<xml::dom::XDocument> loadFragment(
core::XmlFilterBase& rFilter, core::XmlFilterBase& rFilter,
const rtl::Reference< core::FragmentHandler >& rxHandler ) const rtl::Reference< core::FragmentHandler >& rxHandler )
{ {
// load diagramming fragments into DOM representation, that later return loadFragment( rFilter, rxHandler->getFragmentPath() );
// gets serialized back to SAX events and parsed
return rFilter.importFragment( rxHandler->getFragmentPath() );
} }
void importFragment( core::XmlFilterBase& rFilter, void importFragment( core::XmlFilterBase& rFilter,
const uno::Reference<xml::dom::XDocument>& rXDom, const uno::Reference<xml::dom::XDocument>& rXDom,
const char* /*pPropName*/, const char* pDocName,
const ShapePtr& /*pShape*/, const DiagramPtr& pDiagram,
const rtl::Reference< core::FragmentHandler >& rxHandler ) const rtl::Reference< core::FragmentHandler >& rxHandler )
{ {
DiagramDomMap& rMainDomMap = pDiagram->getDomMap();
rMainDomMap[OUString::createFromAscii(pDocName)] = rXDom;
uno::Reference<xml::sax::XFastSAXSerializable> xSerializer( uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(
rXDom, uno::UNO_QUERY_THROW); rXDom, uno::UNO_QUERY_THROW);
@@ -371,14 +402,14 @@ void loadDiagram( ShapePtr& pShape,
// data // data
if( !rDataModelPath.isEmpty() ) if( !rDataModelPath.isEmpty() )
{ {
rtl::Reference< core::FragmentHandler > xRef( rtl::Reference< core::FragmentHandler > xRefDataModel(
new DiagramDataFragmentHandler( rFilter, rDataModelPath, pData )); new DiagramDataFragmentHandler( rFilter, rDataModelPath, pData ));
importFragment(rFilter, importFragment(rFilter,
loadFragment(rFilter,xRef), loadFragment(rFilter,xRefDataModel),
"DiagramData", "OOXData",
pShape, pDiagram,
xRef); xRefDataModel);
// Pass the info to pShape // Pass the info to pShape
for( ::std::vector<OUString>::const_iterator aIt = pData->getExtDrawings().begin(), aEnd = pData->getExtDrawings().end(); for( ::std::vector<OUString>::const_iterator aIt = pData->getExtDrawings().begin(), aEnd = pData->getExtDrawings().end();
aIt != aEnd; ++aIt ) aIt != aEnd; ++aIt )
@@ -391,38 +422,47 @@ void loadDiagram( ShapePtr& pShape,
// layout // layout
if( !rLayoutPath.isEmpty() ) if( !rLayoutPath.isEmpty() )
{ {
rtl::Reference< core::FragmentHandler > xRef( rtl::Reference< core::FragmentHandler > xRefLayout(
new DiagramLayoutFragmentHandler( rFilter, rLayoutPath, pLayout )); new DiagramLayoutFragmentHandler( rFilter, rLayoutPath, pLayout ));
importFragment(rFilter, importFragment(rFilter,
loadFragment(rFilter,xRef), loadFragment(rFilter,xRefLayout),
"DiagramLayout", "OOXLayout",
pShape, pDiagram,
xRef); xRefLayout);
} }
// style // style
if( !rQStylePath.isEmpty() ) if( !rQStylePath.isEmpty() )
{ {
rtl::Reference< core::FragmentHandler > xRef( rtl::Reference< core::FragmentHandler > xRefQStyle(
new DiagramQStylesFragmentHandler( rFilter, rQStylePath, pDiagram->getStyles() )); new DiagramQStylesFragmentHandler( rFilter, rQStylePath, pDiagram->getStyles() ));
importFragment(rFilter, importFragment(rFilter,
loadFragment(rFilter,xRef), loadFragment(rFilter,xRefQStyle),
"DiagramQStyle", "OOXStyle",
pShape, pDiagram,
xRef); xRefQStyle);
} }
// colors // colors
if( !rColorStylePath.isEmpty() ) if( !rColorStylePath.isEmpty() )
{ {
rtl::Reference< core::FragmentHandler > xRef( rtl::Reference< core::FragmentHandler > xRefColorStyle(
new ColorFragmentHandler( rFilter, rColorStylePath, pDiagram->getColors() )); new ColorFragmentHandler( rFilter, rColorStylePath, pDiagram->getColors() ));
importFragment(rFilter, importFragment(rFilter,
loadFragment(rFilter,xRef), loadFragment(rFilter,xRefColorStyle),
"DiagramColorStyle", "OOXColor",
pShape, pDiagram,
xRef); xRefColorStyle);
} }
} else {
// We still want to add the XDocuments to the DiagramDomMap
DiagramDomMap& rMainDomMap = pDiagram->getDomMap();
rMainDomMap[OUString::createFromAscii("OOXLayout")] = loadFragment(rFilter,rLayoutPath);
rMainDomMap[OUString::createFromAscii("OOXStyle")] = loadFragment(rFilter,rQStylePath);
rMainDomMap[OUString::createFromAscii("OOXColor")] = loadFragment(rFilter,rColorStylePath);
} }
// diagram loaded. now lump together & attach to shape // diagram loaded. now lump together & attach to shape
@@ -450,32 +490,32 @@ void loadDiagram( const ShapePtr& pShape,
if( rXDataModelDom.is() ) if( rXDataModelDom.is() )
importFragment(rFilter, importFragment(rFilter,
rXDataModelDom, rXDataModelDom,
"DiagramData", "OOXData",
pShape, pDiagram,
new DiagramDataFragmentHandler( rFilter, aEmpty, pData )); new DiagramDataFragmentHandler( rFilter, aEmpty, pData ));
// layout // layout
if( rXLayoutDom.is() ) if( rXLayoutDom.is() )
importFragment(rFilter, importFragment(rFilter,
rXLayoutDom, rXLayoutDom,
"DiagramLayout", "OOXLayout",
pShape, pDiagram,
new DiagramLayoutFragmentHandler( rFilter, aEmpty, pLayout )); new DiagramLayoutFragmentHandler( rFilter, aEmpty, pLayout ));
// style // style
if( rXQStyleDom.is() ) if( rXQStyleDom.is() )
importFragment(rFilter, importFragment(rFilter,
rXQStyleDom, rXQStyleDom,
"DiagramQStyle", "OOXStyle",
pShape, pDiagram,
new DiagramQStylesFragmentHandler( rFilter, aEmpty, pDiagram->getStyles() )); new DiagramQStylesFragmentHandler( rFilter, aEmpty, pDiagram->getStyles() ));
// colors // colors
if( rXColorStyleDom.is() ) if( rXColorStyleDom.is() )
importFragment(rFilter, importFragment(rFilter,
rXColorStyleDom, rXColorStyleDom,
"DiagramColorStyle", "OOXColor",
pShape, pDiagram,
new ColorFragmentHandler( rFilter, aEmpty, pDiagram->getColors() )); new ColorFragmentHandler( rFilter, aEmpty, pDiagram->getColors() ));
// diagram loaded. now lump together & attach to shape // diagram loaded. now lump together & attach to shape

View File

@@ -35,6 +35,8 @@ namespace com { namespace sun { namespace star {
namespace xml { namespace dom { class XDocument; } } namespace xml { namespace dom { class XDocument; } }
} } } } } }
using namespace ::com::sun::star;
namespace oox { namespace drawingml { namespace oox { namespace drawingml {
namespace dgm { namespace dgm {
@@ -154,6 +156,10 @@ typedef boost::shared_ptr< LayoutNode > LayoutNodePtr;
//////////////////// ////////////////////
typedef std::map< OUString, uno::Reference<xml::dom::XDocument> > DiagramDomMap;
////////////////////
class DiagramData class DiagramData
{ {
public: public:
@@ -289,15 +295,19 @@ public:
const DiagramQStyleMap& getStyles() const { return maStyles; } const DiagramQStyleMap& getStyles() const { return maStyles; }
DiagramColorMap& getColors() { return maColors; } DiagramColorMap& getColors() { return maColors; }
const DiagramColorMap& getColors() const { return maColors; } const DiagramColorMap& getColors() const { return maColors; }
DiagramDomMap & getDomMap() { return maMainDomMap; }
void addTo( const ShapePtr & pShape ); void addTo( const ShapePtr & pShape );
uno::Sequence<beans::PropertyValue> getDomsAsPropertyValues() const;
private: private:
void build( ); void build( );
DiagramDataPtr mpData; DiagramDataPtr mpData;
DiagramLayoutPtr mpLayout; DiagramLayoutPtr mpLayout;
DiagramQStyleMap maStyles; DiagramQStyleMap maStyles;
DiagramColorMap maColors; DiagramColorMap maColors;
std::map< OUString, ShapePtr > maShapeMap; std::map< OUString, ShapePtr > maShapeMap;
DiagramDomMap maMainDomMap;
}; };

View File

@@ -37,6 +37,7 @@
#include "oox/helper/propertyset.hxx" #include "oox/helper/propertyset.hxx"
#include <tools/solar.h> // for the F_PI180 define #include <tools/solar.h> // for the F_PI180 define
#include <editeng/unoprnms.hxx>
#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/container/XNameContainer.hpp>
@@ -83,6 +84,7 @@ Shape::Shape( const sal_Char* pServiceName )
, mbHidden( false ) , mbHidden( false )
, mbHiddenMasterShape( false ) , mbHiddenMasterShape( false )
, mbLockedCanvas( false ) , mbLockedCanvas( false )
, maDiagramDoms( 0 )
{ {
if ( pServiceName ) if ( pServiceName )
msServiceName = OUString::createFromAscii( pServiceName ); msServiceName = OUString::createFromAscii( pServiceName );
@@ -118,6 +120,7 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mbHidden( pSourceShape->mbHidden ) , mbHidden( pSourceShape->mbHidden )
, mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape ) , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
, mbLockedCanvas( pSourceShape->mbLockedCanvas ) , mbLockedCanvas( pSourceShape->mbLockedCanvas )
, maDiagramDoms( pSourceShape->maDiagramDoms )
{} {}
@@ -571,7 +574,8 @@ Reference< XShape > Shape::createAndInsert(
if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) ) if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
xSet->setPropertyValue( rPropName, Any( false ) ); xSet->setPropertyValue( rPropName, Any( false ) );
// do not set properties at a group shape (this causes assertions from svx) // do not set properties at a group shape (this causes
// assertions from svx) ...
if( aServiceName != "com.sun.star.drawing.GroupShape" ) if( aServiceName != "com.sun.star.drawing.GroupShape" )
{ {
PropertySet( xSet ).setProperties( aShapeProps ); PropertySet( xSet ).setProperties( aShapeProps );
@@ -583,6 +587,27 @@ Reference< XShape > Shape::createAndInsert(
} }
} }
// ... but for the InteropGrabBag property
const OUString& aGrabBagPropName = OUString::createFromAscii(UNO_NAME_MISC_OBJ_INTEROPGRABBAG);
if( maDiagramDoms.hasElements() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
{
Sequence<PropertyValue> aGrabBag;
xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
// we keep the previous items, if present
if (aGrabBag.hasElements())
{
sal_Int32 length = aGrabBag.getLength();
aGrabBag.realloc(length+maDiagramDoms.getLength());
for(sal_Int32 i = 0; i < maDiagramDoms.getLength(); ++i)
aGrabBag[length+i] = maDiagramDoms[i];
xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
} else
xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
}
if( bIsCustomShape ) if( bIsCustomShape )
{ {
if ( mbFlipH ) if ( mbFlipH )

View File

@@ -326,6 +326,15 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException)
OUString aFragmentPath(pDiagramGraphicDataContext->getFragmentPathFromRelId(*aIt)); OUString aFragmentPath(pDiagramGraphicDataContext->getFragmentPathFromRelId(*aIt));
oox::drawingml::ShapePtr pShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) ); oox::drawingml::ShapePtr pShapePtr( new Shape( "com.sun.star.drawing.GroupShape" ) );
mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr)); mxFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxFilterBase, aFragmentPath, pShapePtr));
uno::Sequence<beans::PropertyValue> aValue(mpShape->getDiagramDoms());
sal_Int32 length = aValue.getLength();
aValue.realloc(length+1);
beans::PropertyValue* pValue = aValue.getArray();
pValue[length].Name = OUString::createFromAscii("OOXDrawing");
pValue[length].Value = uno::makeAny( mxFilterBase->importFragment( aFragmentPath ) );
pShapePtr->setDiagramDoms( aValue );
pShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() ); pShapePtr->addShape( *mxFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() );
xResult = pShapePtr->getXShape(); xResult = pShapePtr->getXShape();
} }

View File

@@ -36,6 +36,7 @@
#include <com/sun/star/table/BorderLine2.hpp> #include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/table/TableBorder2.hpp> #include <com/sun/star/table/TableBorder2.hpp>
#include <com/sun/star/text/SizeType.hpp> #include <com/sun/star/text/SizeType.hpp>
#include <com/sun/star/xml/dom/XDocument.hpp>
#include <vcl/svapp.hxx> #include <vcl/svapp.hxx>
@@ -542,6 +543,52 @@ void Test::testSmartart()
uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xGroup->getCount()); // 3 rectangles and an arrow in the group CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xGroup->getCount()); // 3 rectangles and an arrow in the group
uno::Reference<beans::XPropertySet> xGroupPropertySet(getShape(1), uno::UNO_QUERY);
uno::Sequence<beans::PropertyValue> aGrabBag(0);
xGroupPropertySet->getPropertyValue(OUString::createFromAscii("InteropGrabBag")) >>= aGrabBag;
CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
sal_Bool bData, bLayout, bQStyle, bColor, bDrawing = sal_False;
for(int i = 0; i < aGrabBag.getLength(); ++i)
{
if (aGrabBag[i].Name == OUString::createFromAscii("OOXData"))
{
bData = sal_True;
uno::Reference<xml::dom::XDocument> aDataDom;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aDataDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aDataDom.get()); // Reference not empty
}
else if (aGrabBag[i].Name == OUString::createFromAscii("OOXLayout"))
{
bLayout = sal_True;
uno::Reference<xml::dom::XDocument> aLayoutDom;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aLayoutDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aLayoutDom.get()); // Reference not empty
}
else if (aGrabBag[i].Name == OUString::createFromAscii("OOXStyle"))
{
bQStyle = sal_True;
uno::Reference<xml::dom::XDocument> aStyleDom;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aStyleDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aStyleDom.get()); // Reference not empty
}
else if (aGrabBag[i].Name == OUString::createFromAscii("OOXColor"))
{
bColor = sal_True;
uno::Reference<xml::dom::XDocument> aColorDom;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aColorDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aColorDom.get()); // Reference not empty
}
else if (aGrabBag[i].Name == OUString::createFromAscii("OOXDrawing"))
{
bDrawing = sal_True;
uno::Reference<xml::dom::XDocument> aDrawingDom;
CPPUNIT_ASSERT(aGrabBag[i].Value >>= aDrawingDom); // PropertyValue of proper type
CPPUNIT_ASSERT(aDrawingDom.get()); // Reference not empty
}
}
CPPUNIT_ASSERT(bData && bLayout && bQStyle && bColor && bDrawing); // Grab Bag has all the expected elements
uno::Reference<beans::XPropertySet> xPropertySet(xGroup->getByIndex(1), uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xPropertySet(xGroup->getByIndex(1), uno::UNO_QUERY);
sal_Int32 nValue(0); sal_Int32 nValue(0);
xPropertySet->getPropertyValue("FillColor") >>= nValue; xPropertySet->getPropertyValue("FillColor") >>= nValue;