Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "diagramlayoutatoms.hxx"
21 : :
22 : : #include <functional>
23 : : #include <boost/bind.hpp>
24 : :
25 : : #include <basegfx/numeric/ftools.hxx>
26 : :
27 : : #include "oox/helper/attributelist.hxx"
28 : : #include "oox/drawingml/fillproperties.hxx"
29 : : #include "oox/drawingml/lineproperties.hxx"
30 : : #include "oox/drawingml/textbody.hxx"
31 : : #include "oox/drawingml/textparagraph.hxx"
32 : : #include "oox/drawingml/textrun.hxx"
33 : : #include "oox/drawingml/customshapeproperties.hxx"
34 : : #include "diagramlayoutatoms.hxx"
35 : : #include "layoutnodecontext.hxx"
36 : :
37 : : using namespace ::com::sun::star;
38 : : using namespace ::com::sun::star::uno;
39 : : using namespace ::com::sun::star::xml::sax;
40 : : using namespace ::oox::core;
41 : :
42 : : namespace oox { namespace drawingml {
43 : :
44 : :
45 : 0 : IteratorAttr::IteratorAttr( )
46 : : : mnAxis( 0 )
47 : : , mnCnt( -1 )
48 : : , mbHideLastTrans( false )
49 : : , mnPtType( 0 )
50 : : , mnSt( 0 )
51 : 0 : , mnStep( 1 )
52 : : {
53 : 0 : }
54 : :
55 : 0 : void IteratorAttr::loadFromXAttr( const Reference< XFastAttributeList >& xAttr )
56 : : {
57 [ # # ]: 0 : AttributeList attr( xAttr );
58 [ # # ][ # # ]: 0 : mnAxis = xAttr->getOptionalValueToken( XML_axis, 0 );
59 [ # # ]: 0 : mnCnt = attr.getInteger( XML_cnt, -1 );
60 [ # # ]: 0 : mbHideLastTrans = attr.getBool( XML_hideLastTrans, false );
61 [ # # ][ # # ]: 0 : mnPtType = xAttr->getOptionalValueToken( XML_ptType, 0 );
62 [ # # ]: 0 : mnSt = attr.getInteger( XML_st, 0 );
63 [ # # ][ # # ]: 0 : mnStep = attr.getInteger( XML_step, 1 );
64 : 0 : }
65 : :
66 : :
67 : :
68 : 0 : ConditionAttr::ConditionAttr()
69 : : : mnFunc( 0 )
70 : : , mnArg( 0 )
71 : 0 : , mnOp( 0 )
72 : : {
73 : :
74 : 0 : }
75 : :
76 : :
77 : 0 : void ConditionAttr::loadFromXAttr( const Reference< XFastAttributeList >& xAttr )
78 : : {
79 : 0 : mnFunc = xAttr->getOptionalValueToken( XML_func, 0 );
80 : : // mnArg will be -1 for "none" or any other unknown value
81 : 0 : mnArg = LayoutNodeContext::tagToVarIdx( xAttr->getOptionalValueToken( XML_arg, XML_none ) );
82 : 0 : mnOp = xAttr->getOptionalValueToken( XML_op, 0 );
83 : 0 : msVal = xAttr->getOptionalValue( XML_val );
84 : 0 : }
85 : :
86 : :
87 : 0 : void LayoutAtom::dump(int level)
88 : : {
89 : : OSL_TRACE( "level = %d - %s of type %s", level,
90 : : OUSTRING_TO_CSTR( msName ),
91 : : typeid(*this).name() );
92 : 0 : const std::vector<LayoutAtomPtr>& pChildren=getChildren();
93 : : std::for_each( pChildren.begin(), pChildren.end(),
94 : 0 : boost::bind( &LayoutAtom::dump, _1, level + 1 ) );
95 : 0 : }
96 : :
97 : :
98 : 0 : ForEachAtom::ForEachAtom(const Reference< XFastAttributeList >& xAttributes)
99 : : {
100 [ # # ]: 0 : maIter.loadFromXAttr(xAttributes);
101 : 0 : }
102 : :
103 : 0 : void ForEachAtom::accept( LayoutAtomVisitor& rVisitor )
104 : : {
105 : 0 : rVisitor.visit(*this);
106 : 0 : }
107 : :
108 : 0 : void ChooseAtom::accept( LayoutAtomVisitor& rVisitor )
109 : : {
110 : 0 : rVisitor.visit(*this);
111 : 0 : }
112 : :
113 : 0 : ConditionAtom::ConditionAtom(const Reference< XFastAttributeList >& xAttributes) :
114 [ # # ]: 0 : mbElse( false )
115 : : {
116 [ # # ]: 0 : maIter.loadFromXAttr( xAttributes );
117 [ # # ]: 0 : maCond.loadFromXAttr( xAttributes );
118 : 0 : }
119 : :
120 : 0 : const std::vector<LayoutAtomPtr>& ConditionAtom::getChildren() const
121 : : {
122 : 0 : bool bDecisionVar=true;
123 : : // HACK
124 [ # # ][ # # ]: 0 : if( maCond.mnFunc == XML_var && maCond.mnArg == XML_dir && maCond.mnOp == XML_equ && maCond.msVal != "norm" )
[ # # ][ # # ]
[ # # ]
125 : 0 : bDecisionVar=false;
126 : :
127 [ # # ]: 0 : if( bDecisionVar )
128 : 0 : return mpChildNodes;
129 : : else
130 : 0 : return mpElseChildNodes;
131 : : }
132 : :
133 : 0 : void ConditionAtom::accept( LayoutAtomVisitor& rVisitor )
134 : : {
135 : 0 : rVisitor.visit(*this);
136 : 0 : }
137 : :
138 : 0 : void ConditionAtom::addChild( const LayoutAtomPtr & pNode )
139 : : {
140 [ # # ]: 0 : if( mbElse )
141 : 0 : mpElseChildNodes.push_back( pNode );
142 : : else
143 : 0 : mpChildNodes.push_back( pNode );
144 : 0 : }
145 : :
146 : 0 : void ConstraintAtom::accept( LayoutAtomVisitor& rVisitor )
147 : : {
148 : 0 : rVisitor.visit(*this);
149 : 0 : }
150 : :
151 : 0 : void AlgAtom::accept( LayoutAtomVisitor& rVisitor )
152 : : {
153 : 0 : rVisitor.visit(*this);
154 : 0 : }
155 : :
156 : 0 : void AlgAtom::layoutShape( const ShapePtr& rShape,
157 : : const Diagram& /*rDgm*/,
158 : : const rtl::OUString& rName ) const
159 : : {
160 [ # # # # : 0 : switch(mnType)
# # # #
# ]
161 : : {
162 : : case XML_composite:
163 : : {
164 [ # # ]: 0 : if( rShape->getChildren().empty() )
165 : : {
166 : 0 : rShape->setSize(awt::Size(50,50));
167 : : break;
168 : : }
169 : :
170 : : // just put stuff below each other
171 : 0 : const sal_Int32 nIncX=0;
172 : 0 : const sal_Int32 nIncY=1;
173 : :
174 [ # # ]: 0 : std::vector<ShapePtr>::const_iterator aCurrShape=rShape->getChildren().begin();
175 [ # # ]: 0 : const std::vector<ShapePtr>::const_iterator aLastShape=rShape->getChildren().end();
176 : :
177 : : // find biggest shape
178 : 0 : awt::Size aMaxSize;
179 [ # # ][ # # ]: 0 : while( aCurrShape != aLastShape )
180 : : {
181 : 0 : const awt::Size& sz=(*aCurrShape)->getSize();
182 : :
183 : : aMaxSize.Width = std::max(
184 : : aMaxSize.Width,
185 [ # # ]: 0 : sz.Width);
186 : : aMaxSize.Height = std::max(
187 : : aMaxSize.Height,
188 [ # # ]: 0 : sz.Height);
189 : :
190 : 0 : ++aCurrShape;
191 : : }
192 : :
193 [ # # ]: 0 : aCurrShape=rShape->getChildren().begin();
194 : 0 : const awt::Point aStartPos=(*aCurrShape)->getPosition();
195 : 0 : awt::Point aCurrPos=aStartPos;
196 : 0 : awt::Size aTotalSize;
197 : 0 : aTotalSize.Width = aMaxSize.Width;
198 [ # # ][ # # ]: 0 : while( aCurrShape != aLastShape )
199 : : {
200 : 0 : const awt::Size& sz=(*aCurrShape)->getSize();
201 : 0 : (*aCurrShape)->setPosition(aCurrPos);
202 : 0 : (*aCurrShape)->setSize(
203 : : awt::Size(aMaxSize.Width,
204 : 0 : sz.Height));
205 : :
206 : : aTotalSize.Height = std::max(
207 : : aTotalSize.Height,
208 [ # # ]: 0 : aCurrPos.Y + sz.Height);
209 : :
210 : 0 : aCurrPos.X += nIncX*sz.Width;
211 : 0 : aCurrPos.Y += nIncY*sz.Height;
212 : :
213 : 0 : ++aCurrShape;
214 : : }
215 : :
216 : 0 : rShape->setSize(aTotalSize);
217 : : break;
218 : : }
219 : :
220 : : case XML_conn:
221 : 0 : break;
222 : :
223 : : case XML_cycle:
224 : : {
225 [ # # ]: 0 : if( rShape->getChildren().empty() )
226 : : {
227 : 0 : rShape->setSize(awt::Size(50,50));
228 : : break;
229 : : }
230 : :
231 [ # # ][ # # ]: 0 : const sal_Int32 nStartAngle=maMap.count(XML_stAng) ? maMap.find(XML_stAng)->second : 0;
[ # # ][ # # ]
[ # # ][ # # ]
232 [ # # ][ # # ]: 0 : const sal_Int32 nSpanAngle=maMap.count(XML_spanAng) ? maMap.find(XML_spanAng)->second : 360;
[ # # ][ # # ]
[ # # ][ # # ]
233 : :
234 [ # # ]: 0 : std::vector<ShapePtr>::const_iterator aCurrShape=rShape->getChildren().begin();
235 [ # # ]: 0 : const std::vector<ShapePtr>::const_iterator aLastShape=rShape->getChildren().end();
236 [ # # ]: 0 : const sal_Int32 nShapes=aLastShape-aCurrShape;
237 : :
238 : : // find biggest shape
239 : 0 : awt::Size aMaxSize;
240 [ # # ][ # # ]: 0 : while( aCurrShape != aLastShape )
241 : : {
242 : 0 : const awt::Size& sz=(*aCurrShape)->getSize();
243 : :
244 : : aMaxSize.Width = std::max(
245 : : aMaxSize.Width,
246 [ # # ]: 0 : sz.Width);
247 : : aMaxSize.Height = std::max(
248 : : aMaxSize.Height,
249 [ # # ]: 0 : sz.Height);
250 : :
251 : 0 : ++aCurrShape;
252 : : }
253 : :
254 : : // layout shapes
255 [ # # ]: 0 : const sal_Int32 nMaxDim=std::max(aMaxSize.Width,aMaxSize.Height);
256 : 0 : awt::Size aTotalSize;
257 [ # # ]: 0 : aCurrShape=rShape->getChildren().begin();
258 [ # # ]: 0 : for( sal_Int32 i=0; i<nShapes; ++i, ++aCurrShape )
259 : : {
260 : 0 : const awt::Size& sz=(*aCurrShape)->getSize();
261 : :
262 : 0 : const double r=nShapes*nMaxDim/F_2PI * 360.0/nSpanAngle;
263 : : const awt::Point aCurrPos(
264 : 0 : r + r*sin( (double(i)*nSpanAngle/nShapes + nStartAngle)*F_PI180 ),
265 : 0 : r - r*cos( (double(i)*nSpanAngle/nShapes + nStartAngle)*F_PI180 ) );
266 : 0 : (*aCurrShape)->setPosition(aCurrPos);
267 : :
268 : : aTotalSize.Width = std::max(
269 : : aTotalSize.Width,
270 [ # # ]: 0 : aCurrPos.X + sz.Width);
271 : : aTotalSize.Height = std::max(
272 : : aTotalSize.Height,
273 [ # # ]: 0 : aCurrPos.Y + sz.Height);
274 : : }
275 : :
276 : 0 : rShape->setSize(aTotalSize);
277 : : break;
278 : : }
279 : :
280 : : case XML_hierChild:
281 : : case XML_hierRoot:
282 : 0 : break;
283 : :
284 : : case XML_lin:
285 : : {
286 [ # # ]: 0 : if( rShape->getChildren().empty() )
287 : : {
288 : 0 : rShape->setSize(awt::Size(50,50));
289 : : break;
290 : : }
291 : :
292 [ # # ][ # # ]: 0 : const sal_Int32 nDir=maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromL;
[ # # ][ # # ]
[ # # ][ # # ]
293 [ # # ][ # # ]: 0 : const sal_Int32 nIncX=nDir==XML_fromL ? 1 : (nDir==XML_fromR ? -1 : 0);
294 [ # # ][ # # ]: 0 : const sal_Int32 nIncY=nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0);
295 : :
296 [ # # ]: 0 : std::vector<ShapePtr>::const_iterator aCurrShape=rShape->getChildren().begin();
297 [ # # ]: 0 : const std::vector<ShapePtr>::const_iterator aLastShape=rShape->getChildren().end();
298 : 0 : const awt::Point aStartPos=(*aCurrShape)->getPosition();
299 : 0 : awt::Point aCurrPos=aStartPos;
300 : 0 : awt::Size aTotalSize;
301 [ # # ][ # # ]: 0 : while( aCurrShape != aLastShape )
302 : : {
303 : 0 : const awt::Size& sz=(*aCurrShape)->getSize();
304 : 0 : (*aCurrShape)->setPosition(aCurrPos);
305 : :
306 : : aTotalSize.Width = std::max(
307 : : aTotalSize.Width,
308 [ # # ]: 0 : aCurrPos.X + sz.Width);
309 : : aTotalSize.Height = std::max(
310 : : aTotalSize.Height,
311 [ # # ]: 0 : aCurrPos.Y + sz.Height);
312 : :
313 : : // HACK: the spacing is arbitrary
314 : 0 : aCurrPos.X += nIncX*(sz.Width+5);
315 : 0 : aCurrPos.Y += nIncY*(sz.Height+5);
316 : :
317 : 0 : ++aCurrShape;
318 : : }
319 : :
320 : 0 : rShape->setSize(aTotalSize);
321 : : break;
322 : : }
323 : :
324 : : case XML_pyra:
325 : : case XML_snake:
326 : 0 : break;
327 : :
328 : : case XML_sp:
329 : : // HACK. Handled one level higher. Or rather, planned to
330 : 0 : break;
331 : :
332 : : case XML_tx:
333 : : {
334 [ # # ]: 0 : TextBodyPtr pTextBody=rShape->getTextBody();
335 [ # # # # : 0 : if( !pTextBody ||
# # ][ # # ]
336 : 0 : pTextBody->getParagraphs().empty() ||
337 [ # # ]: 0 : pTextBody->getParagraphs().front()->getRuns().empty() )
338 : : {
339 : 0 : rShape->setSize(awt::Size(5,5));
340 : : break;
341 : : }
342 : :
343 : : // HACK - count chars & paragraphs to come up with *some*
344 : : // notion of necessary size
345 : 0 : const sal_Int32 nHackyFontHeight=50;
346 : 0 : const sal_Int32 nHackyFontWidth=20;
347 : 0 : awt::Size aTotalSize;
348 [ # # ]: 0 : for( sal_uInt32 nPara=0; nPara<pTextBody->getParagraphs().size(); ++nPara )
349 : : {
350 : 0 : aTotalSize.Height += nHackyFontHeight;
351 : :
352 : 0 : sal_Int32 nLocalWidth=0;
353 [ # # ][ # # ]: 0 : for( sal_uInt32 nRun=0; nRun<pTextBody->getParagraphs().at(nPara)->getRuns().size(); ++nRun )
354 : : nLocalWidth +=
355 [ # # ][ # # ]: 0 : pTextBody->getParagraphs().at(nPara)->getRuns().at(nRun)->getText().getLength()
356 : 0 : * nHackyFontWidth;
357 : :
358 : : aTotalSize.Width = std::max(
359 : : aTotalSize.Width,
360 [ # # ]: 0 : nLocalWidth);
361 : : }
362 : :
363 [ # # ][ # # ]: 0 : rShape->setSize(aTotalSize);
364 : : }
365 : :
366 : : default:
367 : 0 : break;
368 : : }
369 : :
370 : : OSL_TRACE("Layouting shape %s: (%d,%d,%d,%d)",
371 : : OUSTRING_TO_CSTR( rName ),
372 : : rShape->getPosition().X,
373 : : rShape->getPosition().Y,
374 : : rShape->getSize().Width,
375 : : rShape->getSize().Height);
376 : 0 : }
377 : :
378 : 0 : void LayoutNode::accept( LayoutAtomVisitor& rVisitor )
379 : : {
380 : 0 : rVisitor.visit(*this);
381 : 0 : }
382 : :
383 : 0 : bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uInt32 nIdx ) const
384 : : {
385 : : // find the data node to grab text from
386 [ # # ][ # # ]: 0 : DiagramData::PointsNameMap::const_iterator aDataNode=rDgm.getData()->getPointsPresNameMap().find(msName);
[ # # ]
387 [ # # ]: 0 : if( aDataNode != rDgm.getData()->getPointsPresNameMap().end() &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
388 : 0 : aDataNode->second.size() > nIdx )
389 : : {
390 : : OSL_TRACE( "Filling content from %d th layout node named \"%s\", modelId \"%s\"",
391 : : nIdx,
392 : : OUSTRING_TO_CSTR( msName ),
393 : : OUSTRING_TO_CSTR( aDataNode->second.at(nIdx)->msModelId ) );
394 : :
395 : : // got the presentation node - now, need the actual data node:
396 [ # # ][ # # ]: 0 : const DiagramData::StringMap::const_iterator aNodeName=rDgm.getData()->getPresOfNameMap().find(
397 [ # # # # ]: 0 : aDataNode->second.at(nIdx)->msModelId);
398 [ # # ][ # # ]: 0 : if( aNodeName != rDgm.getData()->getPresOfNameMap().end() )
[ # # ]
399 : : {
400 : 0 : DiagramData::StringMap::value_type::second_type::const_iterator aVecIter=aNodeName->second.begin();
401 : 0 : const DiagramData::StringMap::value_type::second_type::const_iterator aVecEnd=aNodeName->second.end();
402 [ # # ][ # # ]: 0 : while( aVecIter != aVecEnd )
403 : : {
404 [ # # ][ # # ]: 0 : DiagramData::PointNameMap::const_iterator aDataNode2=rDgm.getData()->getPointNameMap().find(aVecIter->first);
[ # # ]
405 [ # # ]: 0 : if( aVecIter->second == 0 )
406 : : {
407 : : // grab shape attr from topmost element(s)
408 [ # # ]: 0 : rShape->getShapeProperties() = aDataNode2->second->mpShape->getShapeProperties();
409 [ # # ][ # # ]: 0 : rShape->getLineProperties() = aDataNode2->second->mpShape->getLineProperties();
[ # # ]
410 [ # # ][ # # ]: 0 : rShape->getFillProperties() = aDataNode2->second->mpShape->getFillProperties();
[ # # ]
411 [ # # ][ # # ]: 0 : rShape->getCustomShapeProperties() = aDataNode2->second->mpShape->getCustomShapeProperties();
[ # # ][ # # ]
[ # # ]
412 [ # # ][ # # ]: 0 : rShape->setMasterTextListStyle( aDataNode2->second->mpShape->getMasterTextListStyle() );
[ # # ]
413 : :
414 : : OSL_TRACE( "Custom shape with preset type %d added for layout node named \"%s\"",
415 : : rShape->getCustomShapeProperties()->getShapePresetType(),
416 : : OUSTRING_TO_CSTR( msName ) );
417 : : }
418 : :
419 : : // append text with right outline level
420 [ # # # # : 0 : if( aDataNode2->second->mpShape->getTextBody() &&
# # ][ # # ]
421 [ # # ][ # # ]: 0 : !aDataNode2->second->mpShape->getTextBody()->getParagraphs().empty() &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
422 [ # # ][ # # ]: 0 : !aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getRuns().empty() )
[ # # ][ # # ]
[ # # ]
423 : : {
424 [ # # ]: 0 : TextBodyPtr pTextBody=rShape->getTextBody();
425 [ # # ]: 0 : if( !pTextBody )
426 : : {
427 [ # # ][ # # ]: 0 : pTextBody.reset( new TextBody() );
[ # # ]
428 : :
429 : : // also copy text attrs
430 : 0 : pTextBody->getTextListStyle() =
431 [ # # ][ # # ]: 0 : aDataNode2->second->mpShape->getTextBody()->getTextListStyle();
[ # # ]
432 : 0 : pTextBody->getTextProperties() =
433 [ # # ][ # # ]: 0 : aDataNode2->second->mpShape->getTextBody()->getTextProperties();
[ # # ]
434 : :
435 [ # # ]: 0 : rShape->setTextBody(pTextBody);
436 : : }
437 : :
438 [ # # ]: 0 : TextParagraph& rPara=pTextBody->addParagraph();
439 [ # # ]: 0 : if( aVecIter->second != -1 )
440 : 0 : rPara.getProperties().setLevel(aVecIter->second);
441 : :
442 : : rPara.addRun(
443 [ # # ][ # # ]: 0 : aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getRuns().front());
[ # # ][ # # ]
[ # # ]
444 : 0 : rPara.getProperties().apply(
445 [ # # ][ # # ]: 0 : aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getProperties());
[ # # ][ # # ]
[ # # ]
446 : : }
447 : :
448 : 0 : ++aVecIter;
449 : : }
450 : : }
451 : : else
452 : : {
453 : : OSL_TRACE("ShapeCreationVisitor::visit: no data node name found while processing shape type %d for layout node named \"%s\"",
454 : : rShape->getCustomShapeProperties()->getShapePresetType(),
455 : : OUSTRING_TO_CSTR( msName ) );
456 : : }
457 : :
458 : : // TODO(Q1): apply styling & coloring - taking
459 : : // layout node's styleLbl for both style & color
460 : : // now, but docs are a bit unclear on this
461 [ # # ]: 0 : if( !msStyleLabel.isEmpty() )
462 : : {
463 : : OSL_TRACE("setting style with label %s",
464 : : OUSTRING_TO_CSTR( msStyleLabel ) );
465 : :
466 [ # # ]: 0 : const DiagramQStyleMap::const_iterator aStyle=rDgm.getStyles().find(msStyleLabel);
467 [ # # ]: 0 : if( aStyle != rDgm.getStyles().end() )
468 : : {
469 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_fillRef] = aStyle->second.maFillStyle;
470 : : OSL_TRACE("added fill style with id %d", aStyle->second.maFillStyle.mnThemedIdx);
471 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_lnRef] = aStyle->second.maLineStyle;
472 : : OSL_TRACE("added line style with id %d", aStyle->second.maLineStyle.mnThemedIdx);
473 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_effectRef] = aStyle->second.maEffectStyle;
474 : : OSL_TRACE("added effect style with id %d", aStyle->second.maEffectStyle.mnThemedIdx);
475 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_fontRef] = aStyle->second.maTextStyle;
476 : : OSL_TRACE("added fontref style with id %d", aStyle->second.maTextStyle.mnThemedIdx);
477 [ # # ]: 0 : Color aColor=aStyle->second.maTextStyle.maPhClr;
478 [ # # ]: 0 : OSL_TRACE("added fontref color with alpha %d", aColor.getTransparency() );
479 : : }
480 : :
481 [ # # ]: 0 : const DiagramColorMap::const_iterator aColor=rDgm.getColors().find(msStyleLabel);
482 [ # # ]: 0 : if( aColor != rDgm.getColors().end() )
483 : : {
484 : 0 : const DiagramColor& rColor=aColor->second;
485 [ # # ]: 0 : if( rColor.maFillColor.isUsed() )
486 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_fillRef].maPhClr = rColor.maFillColor;
487 [ # # ]: 0 : if( rColor.maLineColor.isUsed() )
488 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_lnRef].maPhClr = rColor.maLineColor;
489 [ # # ]: 0 : if( rColor.maEffectColor.isUsed() )
490 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_effectRef].maPhClr = rColor.maEffectColor;
491 [ # # ]: 0 : if( rColor.maTextFillColor.isUsed() )
492 [ # # ][ # # ]: 0 : rShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rColor.maTextFillColor;
493 : : }
494 : : }
495 : :
496 : : // even if no data node found, successful anyway. it's
497 : : // contained at the layoutnode
498 : 0 : return true;
499 : : }
500 : : else
501 : : {
502 : : OSL_TRACE("ShapeCreationVisitor::visit: no text found while processing shape type %d for layout node named \"%s\"",
503 : : rShape->getCustomShapeProperties()->getShapePresetType(),
504 : : OUSTRING_TO_CSTR( msName ) );
505 : : }
506 : :
507 : 0 : return false;
508 : : }
509 : :
510 : : ///////////////////////////////////////////////////////////////////////
511 : : //
512 : : // Visitation
513 : : //
514 : :
515 [ # # ][ # # ]: 0 : class ShapeLayoutingVisitor : public LayoutAtomVisitor
516 : : {
517 : : ShapePtr mpParentShape;
518 : : const Diagram& mrDgm;
519 : : rtl::OUString maName;
520 : :
521 : : virtual void visit(ConstraintAtom& rAtom);
522 : : virtual void visit(AlgAtom& rAtom);
523 : : virtual void visit(ForEachAtom& rAtom);
524 : : virtual void visit(ConditionAtom& rAtom);
525 : : virtual void visit(ChooseAtom& rAtom);
526 : : virtual void visit(LayoutNode& rAtom);
527 : :
528 : : public:
529 : 0 : ShapeLayoutingVisitor(const ShapePtr& rParentShape,
530 : : const Diagram& rDgm,
531 : : const rtl::OUString& rName) :
532 : : mpParentShape(rParentShape),
533 : : mrDgm(rDgm),
534 [ # # ]: 0 : maName(rName)
535 : 0 : {}
536 : :
537 : : void defaultVisit(LayoutAtom& rAtom);
538 : : };
539 : :
540 [ # # ]: 0 : class ShallowPresNameVisitor : public LayoutAtomVisitor
541 : : {
542 : : const Diagram& mrDgm;
543 : : size_t mnCnt;
544 : :
545 : : void defaultVisit(LayoutAtom& rAtom);
546 : : virtual void visit(ConstraintAtom& rAtom);
547 : : virtual void visit(AlgAtom& rAtom);
548 : : virtual void visit(ForEachAtom& rAtom);
549 : : virtual void visit(ConditionAtom& rAtom);
550 : : virtual void visit(ChooseAtom& rAtom);
551 : : virtual void visit(LayoutNode& rAtom);
552 : :
553 : : public:
554 : 0 : ShallowPresNameVisitor(const Diagram& rDgm) :
555 : : mrDgm(rDgm),
556 : 0 : mnCnt(0)
557 : 0 : {}
558 : :
559 : 0 : size_t getCount() const
560 : 0 : { return mnCnt; }
561 : : };
562 : :
563 : 0 : void ShapeCreationVisitor::defaultVisit(LayoutAtom& rAtom)
564 : : {
565 : 0 : const std::vector<LayoutAtomPtr>& pChildren=rAtom.getChildren();
566 : : std::for_each( pChildren.begin(), pChildren.end(),
567 : : boost::bind( &LayoutAtom::accept,
568 : : _1,
569 : 0 : boost::ref(*this)) );
570 : 0 : }
571 : :
572 : 0 : void ShapeCreationVisitor::visit(ConstraintAtom& /*rAtom*/)
573 : : {
574 : : // TODO: eval the constraints
575 : 0 : }
576 : :
577 : 0 : void ShapeCreationVisitor::visit(AlgAtom& rAtom)
578 : : {
579 : 0 : defaultVisit(rAtom);
580 : 0 : }
581 : :
582 : 0 : void ShapeCreationVisitor::visit(ForEachAtom& rAtom)
583 : : {
584 [ # # ]: 0 : const std::vector<LayoutAtomPtr>& pChildren=rAtom.getChildren();
585 : :
586 : 0 : sal_Int32 nChildren=1;
587 [ # # ]: 0 : if( rAtom.iterator().mnPtType == XML_node )
588 : : {
589 : : // cound child data nodes - check all child Atoms for "name"
590 : : // attribute that is contained in diagram's
591 : : // getPointsPresNameMap()
592 : 0 : ShallowPresNameVisitor aVisitor(mrDgm);
593 : : std::for_each( pChildren.begin(), pChildren.end(),
594 : : boost::bind( &LayoutAtom::accept,
595 : : _1,
596 [ # # ][ # # ]: 0 : boost::ref(aVisitor)) );
[ # # ]
597 : 0 : nChildren = aVisitor.getCount();
598 : : }
599 : :
600 : : const sal_Int32 nCnt = std::min(
601 : : nChildren,
602 [ # # ][ # # ]: 0 : rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt);
603 : :
604 : 0 : const sal_Int32 nOldIdx=mnCurrIdx;
605 : 0 : const sal_Int32 nStep=rAtom.iterator().mnStep;
606 [ # # ][ # # ]: 0 : for( mnCurrIdx=0; mnCurrIdx<nCnt && nStep>0; mnCurrIdx+=nStep )
[ # # ]
607 : : {
608 : : // TODO there is likely some conditions
609 : : std::for_each( pChildren.begin(), pChildren.end(),
610 : : boost::bind( &LayoutAtom::accept,
611 : : _1,
612 [ # # ][ # # ]: 0 : boost::ref(*this)) );
[ # # ]
613 : : }
614 : :
615 : : // and restore idx
616 : 0 : mnCurrIdx = nOldIdx;
617 : 0 : }
618 : :
619 : 0 : void ShapeCreationVisitor::visit(ConditionAtom& rAtom)
620 : : {
621 : 0 : defaultVisit(rAtom);
622 : 0 : }
623 : :
624 : 0 : void ShapeCreationVisitor::visit(ChooseAtom& rAtom)
625 : : {
626 : 0 : defaultVisit(rAtom);
627 : 0 : }
628 : :
629 : 0 : void ShapeCreationVisitor::visit(LayoutNode& rAtom)
630 : : {
631 [ # # ]: 0 : ShapePtr pCurrParent(mpParentShape);
632 [ # # ]: 0 : ShapePtr pCurrShape(rAtom.getShape());
633 [ # # ]: 0 : if( pCurrShape )
634 : : {
635 : : OSL_TRACE("ShapeCreationVisitor::visit: processing shape type %d",
636 : : pCurrShape->getCustomShapeProperties()->getShapePresetType() );
637 : :
638 : : // TODO(F3): cloned shape shares all properties by reference,
639 : : // don't change them!
640 : : ShapePtr pClonedShape(
641 [ # # ][ # # ]: 0 : new Shape( pCurrShape ));
[ # # ]
642 : :
643 [ # # ][ # # ]: 0 : if( rAtom.setupShape(pClonedShape, mrDgm, mnCurrIdx) )
644 : : {
645 [ # # ][ # # ]: 0 : pCurrParent->addChild(pClonedShape);
[ # # ]
646 [ # # ]: 0 : pCurrParent = pClonedShape;
647 [ # # ]: 0 : }
648 : : }
649 : : else
650 : : {
651 : : OSL_TRACE("ShapeCreationVisitor::visit: no shape set while processing layoutnode named %s",
652 : : OUSTRING_TO_CSTR( rAtom.getName() ) );
653 : : }
654 : :
655 : : // set new parent for children
656 [ # # ]: 0 : ShapePtr pPreviousParent(mpParentShape);
657 [ # # ]: 0 : mpParentShape=pCurrParent;
658 : :
659 : : // process children
660 [ # # ]: 0 : defaultVisit(rAtom);
661 : :
662 : : // restore parent
663 [ # # ]: 0 : mpParentShape=pPreviousParent;
664 : :
665 : : // layout shapes - now all child shapes are created
666 : : ShapeLayoutingVisitor aLayoutingVisitor(pCurrParent,
667 : : mrDgm,
668 [ # # ]: 0 : rAtom.getName());
669 [ # # ][ # # ]: 0 : aLayoutingVisitor.defaultVisit(rAtom);
[ # # ][ # # ]
[ # # ]
670 : 0 : }
671 : :
672 : 0 : void ShapeLayoutingVisitor::defaultVisit(LayoutAtom& rAtom)
673 : : {
674 : : // visit all children, one of them need to be the layout algoritm
675 : 0 : const std::vector<LayoutAtomPtr>& pChildren=rAtom.getChildren();
676 : : std::for_each( pChildren.begin(), pChildren.end(),
677 : : boost::bind( &LayoutAtom::accept,
678 : : _1,
679 : 0 : boost::ref(*this)) );
680 : 0 : }
681 : :
682 : 0 : void ShapeLayoutingVisitor::visit(ConstraintAtom& /*rAtom*/)
683 : : {
684 : : // stop processing
685 : 0 : }
686 : :
687 : 0 : void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
688 : : {
689 : 0 : rAtom.layoutShape(mpParentShape,mrDgm,maName);
690 : 0 : }
691 : :
692 : 0 : void ShapeLayoutingVisitor::visit(ForEachAtom& /*rAtom*/)
693 : : {
694 : : // stop processing
695 : 0 : }
696 : :
697 : 0 : void ShapeLayoutingVisitor::visit(ConditionAtom& rAtom)
698 : : {
699 : 0 : defaultVisit(rAtom);
700 : 0 : }
701 : :
702 : 0 : void ShapeLayoutingVisitor::visit(ChooseAtom& rAtom)
703 : : {
704 : 0 : defaultVisit(rAtom);
705 : 0 : }
706 : :
707 : 0 : void ShapeLayoutingVisitor::visit(LayoutNode& /*rAtom*/)
708 : : {
709 : : // stop processing - only traverse Condition/Choose atoms
710 : 0 : }
711 : :
712 : 0 : void ShallowPresNameVisitor::defaultVisit(LayoutAtom& rAtom)
713 : : {
714 : : // visit all children, at least one of them needs to have proper
715 : : // name set
716 : 0 : const std::vector<LayoutAtomPtr>& pChildren=rAtom.getChildren();
717 : : std::for_each( pChildren.begin(), pChildren.end(),
718 : : boost::bind( &LayoutAtom::accept,
719 : : _1,
720 : 0 : boost::ref(*this)) );
721 : 0 : }
722 : :
723 : 0 : void ShallowPresNameVisitor::visit(ConstraintAtom& /*rAtom*/)
724 : : {
725 : : // stop processing
726 : 0 : }
727 : :
728 : 0 : void ShallowPresNameVisitor::visit(AlgAtom& /*rAtom*/)
729 : : {
730 : : // stop processing
731 : 0 : }
732 : :
733 : 0 : void ShallowPresNameVisitor::visit(ForEachAtom& rAtom)
734 : : {
735 : 0 : defaultVisit(rAtom);
736 : 0 : }
737 : :
738 : 0 : void ShallowPresNameVisitor::visit(ConditionAtom& rAtom)
739 : : {
740 : 0 : defaultVisit(rAtom);
741 : 0 : }
742 : :
743 : 0 : void ShallowPresNameVisitor::visit(ChooseAtom& rAtom)
744 : : {
745 : 0 : defaultVisit(rAtom);
746 : 0 : }
747 : :
748 : 0 : void ShallowPresNameVisitor::visit(LayoutNode& rAtom)
749 : : {
750 : : DiagramData::PointsNameMap::const_iterator aDataNode=
751 [ # # ][ # # ]: 0 : mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
[ # # ]
752 [ # # ][ # # ]: 0 : if( aDataNode != mrDgm.getData()->getPointsPresNameMap().end() )
[ # # ]
753 : : mnCnt = std::max(mnCnt,
754 [ # # ]: 0 : aDataNode->second.size());
755 : 0 : }
756 : :
757 [ + - ][ + - ]: 285 : } }
758 : :
759 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|