/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include #include #include #include #include "oox/drawingml/diagram/diagram.hxx" #include "oox/drawingml/fillproperties.hxx" using rtl::OUString; using namespace ::com::sun::star; namespace oox { namespace drawingml { namespace dgm { void Connection::dump() { OSL_TRACE("dgm: cnx modelId %s, srcId %s, dstId %s", OUSTRING_TO_CSTR( msModelId ), OUSTRING_TO_CSTR( msSourceId ), OUSTRING_TO_CSTR( msDestId ) ); } Point::Point() : mpShape( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ) , mnType( 0 ) { } void Point::dump() { OSL_TRACE( "dgm: pt cnxId %s, modelId %s", OUSTRING_TO_CSTR( msCnxId ), 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 ) { } void DiagramData::dump() { OSL_TRACE("Dgm: DiagramData # of cnx: %d", maConnections.size() ); std::for_each( maConnections.begin(), maConnections.end(), boost::bind( &dgm::Connection::dump, _1 ) ); OSL_TRACE("Dgm: DiagramData # of pt: %d", maPoints.size() ); std::for_each( maPoints.begin(), maPoints.end(), 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) { mpData = pData; } void Diagram::setLayout( const DiagramLayoutPtr & pLayout) { mpLayout = pLayout; } void Diagram::setQStyles( const DiagramQStylesPtr & pStyles) { mpQStyles = pStyles; } 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; } } 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" ); // #i92239# roots may be empty if( !aRoots.empty() ) { 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( ) ); dgm::Points::iterator aPointsIter; build( ); if( mpRoot.get() ) mpLayout->layout( mpRoot, awt::Point( 0, 0 ) ); 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->getChildren().size() ); for( std::vector< ShapePtr >::iterator iter = pParentShape->getChildren().begin(); iter != pParentShape->getChildren().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; } } }