LCOV - code coverage report
Current view: top level - libreoffice/oox/source/drawingml/diagram - diagramlayoutatoms.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 312 0.3 %
Date: 2012-12-27 Functions: 2 47 4.3 %
Legend: Lines: hit not hit

          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 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             :     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 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          51 : } }
     758             : 
     759             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10