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

Generated by: LCOV version 1.10