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 $
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 ************************************************************************/
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"
43 using namespace ::com::sun::star
;
45 namespace oox
{ namespace drawingml
{
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
) );
59 : mpShape( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) )
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
)
74 mpShape
->setName( msModelId
);
78 bool PointsTree::addChild( const PointsTreePtr
& pChild
)
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
);
94 PointsTreePtr
PointsTree::getParent() const
96 if( !mpParent
.expired() )
98 return mpParent
.lock() ;
100 return PointsTreePtr();
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();
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
;
136 dgm::PointsTree::Childrens::const_iterator iter
;
137 for( iter
= pTree
->beginChild(); iter
!= pTree
->endChild(); iter
++ )
139 layout( *iter
, nextPt
);
144 void Diagram::setData( const DiagramDataPtr
& pData
)
150 void Diagram::setLayout( const DiagramLayoutPtr
& pLayout
)
155 void Diagram::setQStyles( const DiagramQStylesPtr
& pStyles
)
161 void Diagram::setColors( const DiagramColorsPtr
& 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 ) );
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
;
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
;
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" );
233 dgm::PointsTreePtr
pNode( new dgm::PointsTree( pDest
) );
234 bool added
= pSource
->addChild( pNode
);
236 aRoots
.erase( dstId
);
237 OSL_ENSURE( added
, "add child failed" );
238 aTreeMap
[ dstId
] = pNode
;
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
;
266 mpLayout
->layout( mpRoot
, awt::Point( 0, 0 ) );
268 for( aPointsIter
= aPoints
.begin(); aPointsIter
!= aPoints
.end(); ++aPointsIter
)
270 if( ( *aPointsIter
)->getType() != XML_node
)
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
296 sLayoutId
= mpLayout
->getUniqueId();