diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index 04394b331f4b..08cf27caaa8b 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -4,9 +4,9 @@ * * $RCSfile: diagram.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: rt $ $Date: 2008-01-17 08:05:57 $ + * last change: $Author: kz $ $Date: 2008-03-05 18:37:58 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -37,10 +37,14 @@ #include #include +#include +#include #include "oox/drawingml/diagram/diagram.hxx" #include "oox/core/namespaces.hxx" #include "tokens.hxx" +using rtl::OUString; +using namespace ::com::sun::star; namespace oox { namespace drawingml { @@ -56,7 +60,7 @@ void Connection::dump() } Point::Point() - : mpShape( new Shape( "com.sun.star.drawing.GroupShape" ) ) + : mpShape( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ) , mnType( 0 ) { } @@ -68,10 +72,41 @@ void Point::dump() OUSTRING_TO_CSTR( msModelId ) ); } - +void Point::setModelId( const ::rtl::OUString & sModelId ) +{ + msModelId = sModelId; + mpShape->setName( msModelId ); } +bool PointsTree::addChild( const PointsTreePtr & pChild ) +{ + bool added = false; + + OSL_ENSURE( pChild->mpParent.expired(), "can't add, has already a parent" ); + OSL_ENSURE( mpNode, "has no node" ); + if( mpNode && pChild->mpParent.expired() ) + { + pChild->mpParent = shared_from_this(); + maChildrens.push_back( pChild ); + added = true; + } + + return added; +} + +PointsTreePtr PointsTree::getParent() const +{ + if( !mpParent.expired() ) + { + return mpParent.lock() ; + } + return PointsTreePtr(); +} + + +} // dgm namespace + DiagramData::DiagramData() : mpFillProperties( new FillProperties( ) ) { @@ -87,6 +122,28 @@ void DiagramData::dump() boost::bind( &dgm::Point::dump, _1 ) ); } +static void setPosition( const dgm::PointPtr & pPoint, const awt::Point & pt ) +{ + ShapePtr pShape = pPoint->getShape(); + awt::Size sz; + sz.Width = 50; + sz.Height = 50; + pShape->setPosition( pt ); + pShape->setSize( sz ); +} + +void DiagramLayout::layout( const dgm::PointsTreePtr & pTree, const awt::Point & pt ) +{ + setPosition( pTree->getPoint(), pt ); + awt::Point nextPt = pt; + nextPt.Y += 50; + dgm::PointsTree::Childrens::const_iterator iter; + for( iter = pTree->beginChild(); iter != pTree->endChild(); iter++ ) + { + layout( *iter, nextPt ); + nextPt.X += 50; + } +} void Diagram::setData( const DiagramDataPtr & pData) { @@ -110,21 +167,135 @@ void Diagram::setColors( const DiagramColorsPtr & pColors) mpColors = pColors; } +void Diagram::build( ) +{ + OSL_TRACE( "building diagram" ); + typedef std::map< OUString, dgm::PointPtr > PointsMap; + PointsMap aPointsMap; + dgm::Points::iterator aPointsIter( mpData->getPoints( ).begin() ); + for( ; aPointsIter != mpData->getPoints( ).end() ; aPointsIter++ ) + { + const OUString & sName((*aPointsIter)->getModelId()); + if( sName.getLength() > 0 ) + { + aPointsMap[ sName ] = *aPointsIter; + } + } -void Diagram::addTo( const ShapePtr & pShape ) + typedef std::map< OUString, dgm::PointsTreePtr > PointsTreeMap; + PointsTreeMap aTreeMap; + PointsTreeMap aRoots; + + dgm::Connections & aConnections(mpData->getConnections( ) ); + dgm::Connections::iterator aCnxIter; + for( aCnxIter = aConnections.begin(); aCnxIter != aConnections.end(); ++aCnxIter ) + { + OSL_ENSURE( *aCnxIter, "NULL connection found" ); + if( (*aCnxIter)->mnType != XML_parOf ) + { +// OSL_TRACE( "ignoring relation %s", OUSTRING_TO_CSTR( (*aCnxIter)->msModelId ) ); + continue; + } + dgm::PointPtr pDest; + dgm::PointsTreePtr pSource; + PointsMap::iterator iterP; + OUString & srcId( (*aCnxIter)->msSourceId ); + OUString & dstId( (*aCnxIter)->msDestId ); + OSL_TRACE( "connexion %s -> %s", OUSTRING_TO_CSTR( srcId ), + OUSTRING_TO_CSTR( dstId ) ); + + PointsTreeMap::iterator iterT = aTreeMap.find( srcId ); + if( iterT != aTreeMap.end() ) + { + pSource = iterT->second; + } + else + { + // this tree node is not found. create it with the source + // and make it the root node. + iterP = aPointsMap.find( srcId ); + if( iterP != aPointsMap.end() ) + { + pSource.reset( new dgm::PointsTree( iterP->second ) ); + aRoots[ srcId ] = pSource; + aTreeMap[ srcId ] = pSource; + } + else + { + OSL_TRACE("parent node not found !"); + } + } + iterP = aPointsMap.find( dstId ); + if( iterP != aPointsMap.end() ) + { + pDest = iterP->second; + } + OSL_ENSURE( pDest, "destination not found" ); + OSL_ENSURE( pSource, "source not found" ); + if(pDest && pSource) + { + dgm::PointsTreePtr pNode( new dgm::PointsTree( pDest ) ); + bool added = pSource->addChild( pNode ); + (void)added; + aRoots.erase( dstId ); + OSL_ENSURE( added, "add child failed" ); + aTreeMap[ dstId ] = pNode; + } + } + // check bounds + OSL_ENSURE( aRoots.size() == 1, "more than one root" ); + mpRoot = aRoots.begin()->second; + OSL_TRACE( "root is %s", OUSTRING_TO_CSTR( mpRoot->getPoint()->getModelId() ) ); + for( PointsTreeMap::iterator iter = aTreeMap.begin(); + iter != aTreeMap.end(); iter++ ) + { + if(! iter->second->getParent() ) + { + OSL_TRACE("node without parent %s", OUSTRING_TO_CSTR( iter->first ) ); + } + } +} + + +void Diagram::addTo( const ShapePtr & pParentShape ) { dgm::Points & aPoints( mpData->getPoints( ) ); - std::for_each( aPoints.begin(), aPoints.end(), - boost::bind( &Shape::addChild, boost::ref( pShape ), - boost::bind( &dgm::Point::getShape, _1 ) ) ); + dgm::Points::iterator aPointsIter; + build( ); + mpLayout->layout( mpRoot, awt::Point( 0, 0 ) ); - OSL_TRACE( "Dgm: addTo() # of childs %d", pShape->getChilds().size() ); - for( std::vector< ShapePtr >::iterator iter = pShape->getChilds().begin(); - iter != pShape->getChilds().end(); ++iter) + for( aPointsIter = aPoints.begin(); aPointsIter != aPoints.end(); ++aPointsIter ) + { + if( ( *aPointsIter )->getType() != XML_node ) + { + continue; + } + ShapePtr pShape = ( *aPointsIter )->getShape( ); + if( pShape->getName( ).getLength() > 0 ) + { + maShapeMap[ pShape->getName( ) ] = pShape; + OSL_TRACE( "Dgm: added shape %s to map", OUSTRING_TO_CSTR( pShape->getName() ) ); + } + pParentShape->addChild( pShape ); + } + + OSL_TRACE( "Dgm: addTo() # of childs %d", pParentShape->getChilds().size() ); + for( std::vector< ShapePtr >::iterator iter = pParentShape->getChilds().begin(); + iter != pParentShape->getChilds().end(); ++iter) { OSL_TRACE( "Dgm: shape name %s", OUSTRING_TO_CSTR( (*iter)->getName() ) ); } } +OUString Diagram::getLayoutId() const +{ + OUString sLayoutId; + if( mpLayout ) + { + sLayoutId = mpLayout->getUniqueId(); + } + return sLayoutId; +} + } }