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

Generated by: LCOV version 1.11