merge the formfield patch from ooo-build
[ooovba.git] / oox / source / drawingml / diagram / diagram.cxx
blobb65195a1151e97d43e2cb7b56be3f24342008cea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: diagram.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #include <functional>
33 #include <boost/bind.hpp>
35 #include <com/sun/star/awt/Point.hpp>
36 #include <com/sun/star/awt/Size.hpp>
37 #include "oox/drawingml/diagram/diagram.hxx"
38 #include "oox/drawingml/fillproperties.hxx"
39 #include "oox/core/namespaces.hxx"
40 #include "tokens.hxx"
42 using rtl::OUString;
43 using namespace ::com::sun::star;
45 namespace oox { namespace drawingml {
47 namespace dgm {
50 void Connection::dump()
52 OSL_TRACE("dgm: cnx modelId %s, srcId %s, dstId %s",
53 OUSTRING_TO_CSTR( msModelId ),
54 OUSTRING_TO_CSTR( msSourceId ),
55 OUSTRING_TO_CSTR( msDestId ) );
58 Point::Point()
59 : mpShape( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) )
60 , mnType( 0 )
64 void Point::dump()
66 OSL_TRACE( "dgm: pt cnxId %s, modelId %s",
67 OUSTRING_TO_CSTR( msCnxId ),
68 OUSTRING_TO_CSTR( msModelId ) );
71 void Point::setModelId( const ::rtl::OUString & sModelId )
73 msModelId = sModelId;
74 mpShape->setName( msModelId );
78 bool PointsTree::addChild( const PointsTreePtr & pChild )
80 bool added = false;
82 OSL_ENSURE( pChild->mpParent.expired(), "can't add, has already a parent" );
83 OSL_ENSURE( mpNode, "has no node" );
84 if( mpNode && pChild->mpParent.expired() )
86 pChild->mpParent = shared_from_this();
87 maChildrens.push_back( pChild );
88 added = true;
91 return added;
94 PointsTreePtr PointsTree::getParent() const
96 if( !mpParent.expired() )
98 return mpParent.lock() ;
100 return PointsTreePtr();
104 } // dgm namespace
106 DiagramData::DiagramData()
107 : mpFillProperties( new FillProperties )
111 void DiagramData::dump()
113 OSL_TRACE("Dgm: DiagramData # of cnx: %d", maConnections.size() );
114 std::for_each( maConnections.begin(), maConnections.end(),
115 boost::bind( &dgm::Connection::dump, _1 ) );
116 OSL_TRACE("Dgm: DiagramData # of pt: %d", maPoints.size() );
117 std::for_each( maPoints.begin(), maPoints.end(),
118 boost::bind( &dgm::Point::dump, _1 ) );
121 static void setPosition( const dgm::PointPtr & pPoint, const awt::Point & pt )
123 ShapePtr pShape = pPoint->getShape();
124 awt::Size sz;
125 sz.Width = 50;
126 sz.Height = 50;
127 pShape->setPosition( pt );
128 pShape->setSize( sz );
131 void DiagramLayout::layout( const dgm::PointsTreePtr & pTree, const awt::Point & pt )
133 setPosition( pTree->getPoint(), pt );
134 awt::Point nextPt = pt;
135 nextPt.Y += 50;
136 dgm::PointsTree::Childrens::const_iterator iter;
137 for( iter = pTree->beginChild(); iter != pTree->endChild(); iter++ )
139 layout( *iter, nextPt );
140 nextPt.X += 50;
144 void Diagram::setData( const DiagramDataPtr & pData)
146 mpData = pData;
150 void Diagram::setLayout( const DiagramLayoutPtr & pLayout)
152 mpLayout = pLayout;
155 void Diagram::setQStyles( const DiagramQStylesPtr & pStyles)
157 mpQStyles = pStyles;
161 void Diagram::setColors( const DiagramColorsPtr & pColors)
163 mpColors = pColors;
166 void Diagram::build( )
168 OSL_TRACE( "building diagram" );
169 typedef std::map< OUString, dgm::PointPtr > PointsMap;
170 PointsMap aPointsMap;
171 dgm::Points::iterator aPointsIter( mpData->getPoints( ).begin() );
172 for( ; aPointsIter != mpData->getPoints( ).end() ; aPointsIter++ )
174 const OUString & sName((*aPointsIter)->getModelId());
175 if( sName.getLength() > 0 )
177 aPointsMap[ sName ] = *aPointsIter;
181 typedef std::map< OUString, dgm::PointsTreePtr > PointsTreeMap;
182 PointsTreeMap aTreeMap;
183 PointsTreeMap aRoots;
185 dgm::Connections & aConnections(mpData->getConnections( ) );
186 dgm::Connections::iterator aCnxIter;
187 for( aCnxIter = aConnections.begin(); aCnxIter != aConnections.end(); ++aCnxIter )
189 OSL_ENSURE( *aCnxIter, "NULL connection found" );
190 if( (*aCnxIter)->mnType != XML_parOf )
192 // OSL_TRACE( "ignoring relation %s", OUSTRING_TO_CSTR( (*aCnxIter)->msModelId ) );
193 continue;
195 dgm::PointPtr pDest;
196 dgm::PointsTreePtr pSource;
197 PointsMap::iterator iterP;
198 OUString & srcId( (*aCnxIter)->msSourceId );
199 OUString & dstId( (*aCnxIter)->msDestId );
200 OSL_TRACE( "connexion %s -> %s", OUSTRING_TO_CSTR( srcId ),
201 OUSTRING_TO_CSTR( dstId ) );
203 PointsTreeMap::iterator iterT = aTreeMap.find( srcId );
204 if( iterT != aTreeMap.end() )
206 pSource = iterT->second;
208 else
210 // this tree node is not found. create it with the source
211 // and make it the root node.
212 iterP = aPointsMap.find( srcId );
213 if( iterP != aPointsMap.end() )
215 pSource.reset( new dgm::PointsTree( iterP->second ) );
216 aRoots[ srcId ] = pSource;
217 aTreeMap[ srcId ] = pSource;
219 else
221 OSL_TRACE("parent node not found !");
224 iterP = aPointsMap.find( dstId );
225 if( iterP != aPointsMap.end() )
227 pDest = iterP->second;
229 OSL_ENSURE( pDest, "destination not found" );
230 OSL_ENSURE( pSource, "source not found" );
231 if(pDest && pSource)
233 dgm::PointsTreePtr pNode( new dgm::PointsTree( pDest ) );
234 bool added = pSource->addChild( pNode );
235 (void)added;
236 aRoots.erase( dstId );
237 OSL_ENSURE( added, "add child failed" );
238 aTreeMap[ dstId ] = pNode;
241 // check bounds
242 OSL_ENSURE( aRoots.size() == 1, "more than one root" );
243 // #i92239# roots may be empty
244 if( !aRoots.empty() )
246 mpRoot = aRoots.begin()->second;
247 OSL_TRACE( "root is %s", OUSTRING_TO_CSTR( mpRoot->getPoint()->getModelId() ) );
248 for( PointsTreeMap::iterator iter = aTreeMap.begin();
249 iter != aTreeMap.end(); iter++ )
251 if(! iter->second->getParent() )
253 OSL_TRACE("node without parent %s", OUSTRING_TO_CSTR( iter->first ) );
260 void Diagram::addTo( const ShapePtr & pParentShape )
262 dgm::Points & aPoints( mpData->getPoints( ) );
263 dgm::Points::iterator aPointsIter;
264 build( );
265 if( mpRoot.get() )
266 mpLayout->layout( mpRoot, awt::Point( 0, 0 ) );
268 for( aPointsIter = aPoints.begin(); aPointsIter != aPoints.end(); ++aPointsIter )
270 if( ( *aPointsIter )->getType() != XML_node )
272 continue;
274 ShapePtr pShape = ( *aPointsIter )->getShape( );
275 if( pShape->getName( ).getLength() > 0 )
277 maShapeMap[ pShape->getName( ) ] = pShape;
278 OSL_TRACE( "Dgm: added shape %s to map", OUSTRING_TO_CSTR( pShape->getName() ) );
280 pParentShape->addChild( pShape );
283 OSL_TRACE( "Dgm: addTo() # of childs %d", pParentShape->getChildren().size() );
284 for( std::vector< ShapePtr >::iterator iter = pParentShape->getChildren().begin();
285 iter != pParentShape->getChildren().end(); ++iter)
287 OSL_TRACE( "Dgm: shape name %s", OUSTRING_TO_CSTR( (*iter)->getName() ) );
291 OUString Diagram::getLayoutId() const
293 OUString sLayoutId;
294 if( mpLayout )
296 sLayoutId = mpLayout->getUniqueId();
298 return sLayoutId;