LCOV - code coverage report
Current view: top level - chart2/source/view/diagram - VDiagram.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 362 0.0 %
Date: 2014-04-14 Functions: 0 18 0.0 %
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 "VDiagram.hxx"
      21             : #include "PropertyMapper.hxx"
      22             : #include "ViewDefines.hxx"
      23             : #include "Stripe.hxx"
      24             : #include "macros.hxx"
      25             : #include "ObjectIdentifier.hxx"
      26             : #include "DiagramHelper.hxx"
      27             : #include "BaseGFXHelper.hxx"
      28             : #include "CommonConverters.hxx"
      29             : #include "ChartTypeHelper.hxx"
      30             : #include "ThreeDHelper.hxx"
      31             : #include "defines.hxx"
      32             : #include <editeng/unoprnms.hxx>
      33             : #include <com/sun/star/drawing/FillStyle.hpp>
      34             : #include <com/sun/star/drawing/LineStyle.hpp>
      35             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      36             : #include <com/sun/star/drawing/ShadeMode.hpp>
      37             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      38             : #include <com/sun/star/lang/XTypeProvider.hpp>
      39             : // header for class SvxShape
      40             : #include <svx/unoshape.hxx>
      41             : // header for class E3dScene
      42             : #include <svx/scene3d.hxx>
      43             : #include <svx/e3dsceneupdater.hxx>
      44             : 
      45             : namespace chart
      46             : {
      47             : using namespace ::com::sun::star;
      48             : using namespace ::com::sun::star::chart2;
      49             : 
      50           0 : VDiagram::VDiagram(
      51             :     const uno::Reference<XDiagram> & xDiagram, const drawing::Direction3D& rPreferredAspectRatio,
      52             :     sal_Int32 nDimension )
      53             :     : m_xTarget(NULL)
      54             :     , m_xShapeFactory(NULL)
      55             :     , m_pShapeFactory(NULL)
      56             :     , m_xOuterGroupShape(NULL)
      57             :     , m_xCoordinateRegionShape(NULL)
      58             :     , m_xWall2D(NULL)
      59             :     , m_nDimensionCount(nDimension)
      60             :     , m_xDiagram(xDiagram)
      61             :     , m_aPreferredAspectRatio(rPreferredAspectRatio)
      62             :     , m_xAspectRatio3D()
      63             :     , m_fXAnglePi(0)
      64             :     , m_fYAnglePi(0)
      65             :     , m_fZAnglePi(0)
      66           0 :     , m_bRightAngledAxes(false)
      67             : {
      68           0 :     if( m_nDimensionCount == 3)
      69             :     {
      70           0 :         uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY );
      71           0 :         ThreeDHelper::getRotationAngleFromDiagram( xSourceProp, m_fXAnglePi, m_fYAnglePi, m_fZAnglePi );
      72           0 :         if( ChartTypeHelper::isSupportingRightAngledAxes(
      73           0 :                 DiagramHelper::getChartTypeByIndex( m_xDiagram, 0 ) ) )
      74             :         {
      75           0 :             if(xSourceProp.is())
      76           0 :                 xSourceProp->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes;
      77           0 :             if( m_bRightAngledAxes )
      78             :             {
      79           0 :                 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi, m_fYAnglePi );
      80           0 :                 m_fZAnglePi=0.0;
      81             :             }
      82           0 :         }
      83             :     }
      84           0 : }
      85             : 
      86           0 : VDiagram::~VDiagram()
      87             : {
      88           0 : }
      89             : 
      90           0 : void VDiagram::init(
      91             :     const uno::Reference< drawing::XShapes >& xTarget, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
      92             : {
      93             :     OSL_PRECOND(xFactory.is(), "no proper initialization parameters");
      94             : 
      95           0 :     m_xTarget  = xTarget;
      96           0 :     m_xShapeFactory = xFactory;
      97           0 :     m_pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(xFactory);
      98           0 : }
      99             : 
     100           0 : void VDiagram::createShapes( const awt::Point& rPos, const awt::Size& rSize )
     101             : {
     102           0 :     m_aAvailablePosIncludingAxes = rPos;
     103           0 :     m_aAvailableSizeIncludingAxes = rSize;
     104             : 
     105           0 :     if( m_nDimensionCount == 3 )
     106           0 :         createShapes_3d();
     107             :     else
     108           0 :         createShapes_2d();
     109           0 : }
     110             : 
     111           0 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize( const awt::Point& rPos, const awt::Size& rSize )
     112             : {
     113           0 :     ::basegfx::B2IRectangle aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
     114           0 :     ::basegfx::B2IRectangle aNewInnerRect( BaseGFXHelper::makeRectangle(rPos,rSize) );
     115           0 :     aNewInnerRect.intersect( aAllowedRect );
     116             : 
     117           0 :     if( m_nDimensionCount == 3 )
     118           0 :         aNewInnerRect = adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
     119             :     else
     120           0 :         aNewInnerRect = adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
     121             : 
     122           0 :     return aNewInnerRect;
     123             : }
     124             : 
     125           0 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_2d( const awt::Point& rPos, const awt::Size& rAvailableSize )
     126             : {
     127           0 :     m_aCurrentPosWithoutAxes = rPos;
     128           0 :     m_aCurrentSizeWithoutAxes = rAvailableSize;
     129           0 :     if( m_aPreferredAspectRatio.DirectionX > 0 && m_aPreferredAspectRatio.DirectionY > 0)
     130             :     {
     131             :         //do not change aspect ratio
     132           0 :         awt::Size  aAspectRatio( static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME),
     133           0 :                                  static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME ));
     134             :         m_aCurrentSizeWithoutAxes = awt::Size( AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
     135           0 :                         rAvailableSize, aAspectRatio ) );
     136             :         //center diagram position
     137             :         m_aCurrentPosWithoutAxes = awt::Point( AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
     138           0 :             rPos, rAvailableSize, m_aCurrentSizeWithoutAxes ) );
     139             : 
     140             :     }
     141             : 
     142           0 :     if( m_xWall2D.is() )
     143             :     {
     144           0 :         m_xWall2D->setSize( m_aCurrentSizeWithoutAxes);
     145           0 :         m_xWall2D->setPosition(m_aCurrentPosWithoutAxes);
     146             :     }
     147             : 
     148           0 :     return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
     149             : }
     150             : 
     151           0 : void VDiagram::createShapes_2d()
     152             : {
     153             :     OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
     154           0 :     if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
     155           0 :         return;
     156             : 
     157             :     //create group shape
     158           0 :     uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xTarget);
     159           0 :     m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY );
     160             : 
     161           0 :     uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"PlotAreaExcludingAxes") );
     162             : 
     163             :     //create independent group shape as container for datapoints and such things
     164             :     {
     165           0 :         uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID");
     166           0 :         m_xCoordinateRegionShape = uno::Reference<drawing::XShape>( xShapes, uno::UNO_QUERY );
     167             :     }
     168             : 
     169           0 :     bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
     170             : 
     171             :     //add back wall
     172             :     {
     173           0 :         AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
     174           0 :         m_xWall2D = pShapeFactory->createRectangle(
     175           0 :                 xGroupForWall );
     176             : 
     177           0 :         uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY );
     178           0 :         if( xProp.is())
     179             :         {
     180             :             try
     181             :             {
     182             :                 OSL_ENSURE( m_xDiagram.is(), "Invalid Diagram model" );
     183           0 :                 if( m_xDiagram.is() )
     184             :                 {
     185           0 :                     uno::Reference< beans::XPropertySet > xWallProp( m_xDiagram->getWall());
     186           0 :                     if( xWallProp.is())
     187           0 :                         PropertyMapper::setMappedProperties( xProp, xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
     188             :                 }
     189           0 :                 if( !bAddFloorAndWall )
     190             :                 {
     191             :                     //we always need this object as dummy object for correct scene dimensions
     192             :                     //but it should not be visible in this case:
     193           0 :                     AbstractShapeFactory::makeShapeInvisible( m_xWall2D );
     194             :                 }
     195             :                 else
     196             :                 {
     197             :                     //CID for selection handling
     198           0 :                     OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
     199           0 :                     xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME, uno::makeAny( aWallCID ) );
     200             :                 }
     201             :             }
     202           0 :             catch( const uno::Exception& e )
     203             :             {
     204             :                 ASSERT_EXCEPTION( e );
     205             :             }
     206           0 :         }
     207             : 
     208             :     }
     209             : 
     210             :     //position and size for diagram
     211           0 :     adjustPosAndSize_2d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
     212             : }
     213             : 
     214           0 : E3dScene* lcl_getE3dScene( const uno::Reference< drawing::XShape >& xShape )
     215             : {
     216           0 :     E3dScene* pRet=NULL;
     217           0 :     uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
     218           0 :     uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
     219           0 :     if(xUnoTunnel.is()&&xTypeProvider.is())
     220             :     {
     221           0 :         SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
     222           0 :         if(pSvxShape)
     223             :         {
     224           0 :             SdrObject* pObj = pSvxShape->GetSdrObject();
     225           0 :             if( pObj && pObj->ISA(E3dScene) )
     226           0 :                 pRet = (E3dScene*)pObj;
     227             :         }
     228             :     }
     229           0 :     return pRet;
     230             : }
     231             : 
     232           0 : void lcl_setLightSources(
     233             :     const uno::Reference< beans::XPropertySet > & xSource,
     234             :     const uno::Reference< beans::XPropertySet > & xDest )
     235             : {
     236           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1,
     237           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1));
     238           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2,
     239           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2));
     240           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3,
     241           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3));
     242           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4,
     243           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4));
     244           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5,
     245           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5));
     246           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6,
     247           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6));
     248           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7,
     249           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7));
     250           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8,
     251           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8));
     252             : 
     253           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1,
     254           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1));
     255           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2,
     256           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2));
     257           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3,
     258           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3));
     259           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4,
     260           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4));
     261           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5,
     262           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5));
     263           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6,
     264           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6));
     265           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7,
     266           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7));
     267           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8,
     268           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8));
     269             : 
     270           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1,
     271           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1));
     272           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2,
     273           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2));
     274           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3,
     275           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3));
     276           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4,
     277           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4));
     278           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5,
     279           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5));
     280           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6,
     281           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6));
     282           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7,
     283           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7));
     284           0 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8,
     285           0 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8));
     286           0 : }
     287             : 
     288             : namespace
     289             : {
     290             : 
     291           0 : void lcl_ensureScaleValue( double& rfScale )
     292             : {
     293             :     OSL_ENSURE(rfScale>0, "calculation error for automatic 3D height in chart");
     294           0 :     if( rfScale<0 )
     295           0 :         rfScale = 1.0;
     296           0 :     else if( rfScale<0.2 )
     297           0 :         rfScale = 0.2;
     298           0 :     else if( rfScale>5.0 )
     299           0 :         rfScale = 5.0;
     300           0 : }
     301             : 
     302             : }
     303             : 
     304           0 : void VDiagram::adjustAspectRatio3d( const awt::Size& rAvailableSize )
     305             : {
     306             :     OSL_PRECOND(m_xAspectRatio3D.is(), "created shape offers no XPropertySet");
     307           0 :     if( m_xAspectRatio3D.is())
     308             :     {
     309             :         try
     310             :         {
     311           0 :             double fScaleX = m_aPreferredAspectRatio.DirectionX;
     312           0 :             double fScaleY = m_aPreferredAspectRatio.DirectionY;
     313           0 :             double fScaleZ = m_aPreferredAspectRatio.DirectionZ;
     314             : 
     315             :             //normalize scale factors
     316             :             {
     317           0 :                 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
     318           0 :                 fScaleX/=fMax;
     319           0 :                 fScaleY/=fMax;
     320           0 :                 fScaleZ/=fMax;
     321             :             }
     322             : 
     323           0 :             if( fScaleX<0 || fScaleY<0 || fScaleZ<0 )
     324             :             {
     325             :                 //calculate automatic 3D aspect ratio that fits good into the given 2D area
     326           0 :                 double fW = rAvailableSize.Width;
     327           0 :                 double fH = rAvailableSize.Height;
     328             : 
     329           0 :                 double sx = fabs(sin(m_fXAnglePi));
     330           0 :                 double sy = fabs(sin(m_fYAnglePi));
     331           0 :                 double cz = fabs(cos(m_fZAnglePi));
     332           0 :                 double sz = fabs(sin(m_fZAnglePi));
     333             : 
     334           0 :                 if(m_bRightAngledAxes)
     335             :                 {
     336             :                     //base equations:
     337             :                     //fH*zoomfactor == sx*fScaleZ + fScaleY;
     338             :                     //fW*zoomfactor == sy*fScaleZ + fScaleX;
     339             : 
     340           0 :                     if( fScaleX>0 && fScaleZ>0 )
     341             :                     {
     342             :                         //calculate fScaleY:
     343           0 :                         if( !::basegfx::fTools::equalZero(fW) )
     344             :                         {
     345           0 :                             fScaleY = (fH/fW)*(sy*fScaleZ+fScaleX)-(sx*fScaleZ);
     346           0 :                             lcl_ensureScaleValue( fScaleY );
     347             :                         }
     348             :                         else
     349           0 :                             fScaleY = 1.0;//looking from top or bottom the height is irrelevant
     350             :                     }
     351           0 :                     else if( fScaleY>0 && fScaleZ>0 )
     352             :                     {
     353             :                         //calculate fScaleX:
     354           0 :                         if( !::basegfx::fTools::equalZero(fH) )
     355             :                         {
     356           0 :                             fScaleX = (fW/fH)*(sx*fScaleZ+fScaleY)-(sy*fScaleZ);
     357           0 :                             lcl_ensureScaleValue(fScaleX);
     358             :                         }
     359             :                         else
     360           0 :                             fScaleX = 1.0;//looking from top or bottom hieght is irrelevant
     361             :                     }
     362             :                     else
     363             :                     {
     364             :                         //todo
     365             :                         OSL_FAIL("not implemented yet");
     366             : 
     367           0 :                         if( fScaleX<0 )
     368           0 :                             fScaleX = 1.0;
     369           0 :                         if( fScaleY<0 )
     370           0 :                             fScaleY = 1.0;
     371           0 :                         if( fScaleZ<0 )
     372           0 :                             fScaleZ = 1.0;
     373             :                     }
     374             :                 }
     375             :                 else
     376             :                 {
     377             :                     //base equations:
     378             :                     //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
     379             :                     //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
     380             :                     //==>  fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
     381           0 :                     if( fScaleX>0 && fScaleZ>0 )
     382             :                     {
     383             :                         //calculate fScaleY:
     384           0 :                         double fDivide = fH*sz-fW*cz;
     385           0 :                         if( !::basegfx::fTools::equalZero(fDivide) )
     386             :                         {
     387           0 :                             fScaleY = fScaleX*(fW*sz-fH*cz) / fDivide;
     388           0 :                             lcl_ensureScaleValue(fScaleY);
     389             :                         }
     390             :                         else
     391           0 :                             fScaleY = 1.0;//looking from top or bottom the height is irrelevant
     392             : 
     393             :                     }
     394           0 :                     else if( fScaleY>0 && fScaleZ>0 )
     395             :                     {
     396             :                         //calculate fScaleX:
     397           0 :                         double fDivide = fW*sz-fH*cz;
     398           0 :                         if( !::basegfx::fTools::equalZero(fDivide) )
     399             :                         {
     400           0 :                             fScaleX = fScaleY*(fH*sz-fW*cz) / fDivide;
     401           0 :                             lcl_ensureScaleValue(fScaleX);
     402             :                         }
     403             :                         else
     404           0 :                             fScaleX = 1.0;//looking from top or bottom hieght is irrelevant
     405             :                     }
     406             :                     else
     407             :                     {
     408             :                         //todo
     409             :                         OSL_FAIL("not implemented yet");
     410             : 
     411           0 :                         if( fScaleX<0 )
     412           0 :                             fScaleX = 1.0;
     413           0 :                         if( fScaleY<0 )
     414           0 :                             fScaleY = 1.0;
     415           0 :                         if( fScaleZ<0 )
     416           0 :                             fScaleZ = 1.0;
     417             :                     }
     418             :                 }
     419             :             }
     420             : 
     421             :             //normalize scale factors
     422             :             {
     423           0 :                 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
     424           0 :                 fScaleX/=fMax;
     425           0 :                 fScaleY/=fMax;
     426           0 :                 fScaleZ/=fMax;
     427             :             }
     428             : 
     429             :             // identity matrix
     430           0 :             ::basegfx::B3DHomMatrix aResult;
     431             :             aResult.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     432             :                             -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     433           0 :                             -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
     434           0 :             aResult.scale( fScaleX, fScaleY, fScaleZ );
     435             :             aResult.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     436             :                             FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     437           0 :                             FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
     438             : 
     439             :             // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
     440             :             // 3D content changes here. The tooling class remembers the current 3D transformation stack
     441             :             // and in its destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
     442           0 :             E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     443             : 
     444           0 :             m_xAspectRatio3D->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
     445           0 :                 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult )) );
     446             :         }
     447           0 :         catch( const uno::Exception& e )
     448             :         {
     449             :             ASSERT_EXCEPTION( e );
     450             :         }
     451             :     }
     452           0 : }
     453             : 
     454           0 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_3d( const awt::Point& rPos, const awt::Size& rAvailableSize )
     455             : {
     456           0 :     adjustAspectRatio3d( rAvailableSize );
     457             : 
     458             :     //do not change aspect ratio of 3D scene with 2D bound rect
     459             :     m_aCurrentSizeWithoutAxes = AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
     460           0 :                     rAvailableSize, m_xOuterGroupShape->getSize() );
     461           0 :     m_xOuterGroupShape->setSize( m_aCurrentSizeWithoutAxes );
     462             : 
     463             :     //center diagram position
     464             :     m_aCurrentPosWithoutAxes= AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
     465           0 :          rPos, rAvailableSize, m_aCurrentSizeWithoutAxes );
     466           0 :     m_xOuterGroupShape->setPosition(m_aCurrentPosWithoutAxes);
     467             : 
     468           0 :     return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
     469             : }
     470             : 
     471           0 : void VDiagram::createShapes_3d()
     472             : {
     473             :     OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
     474           0 :     if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
     475           0 :         return;
     476             : 
     477             :     //create shape
     478           0 :     m_xOuterGroupShape = uno::Reference< drawing::XShape >(
     479           0 :             m_pShapeFactory->createGroup3D( m_xTarget, "PlotAreaExcludingAxes" ), uno::UNO_QUERY);
     480             : 
     481             :     uno::Reference< drawing::XShapes > xOuterGroup_Shapes =
     482           0 :             uno::Reference<drawing::XShapes>( m_xOuterGroupShape, uno::UNO_QUERY );
     483             : 
     484             :     //create additional group to manipulate the aspect ratio of the whole diagram:
     485           0 :     xOuterGroup_Shapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, OUString() );
     486             : 
     487           0 :     m_xAspectRatio3D = uno::Reference< beans::XPropertySet >( xOuterGroup_Shapes, uno::UNO_QUERY );
     488             : 
     489           0 :     bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
     490             : 
     491           0 :     const bool bDoubleSided = false;
     492           0 :     const bool bFlatNormals = true;
     493             : 
     494             :     //add walls
     495             :     {
     496           0 :         uno::Reference< beans::XPropertySet > xWallProp( NULL );
     497           0 :         if( m_xDiagram.is() )
     498           0 :             xWallProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getWall());
     499             : 
     500           0 :         OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
     501           0 :         if( !bAddFloorAndWall )
     502           0 :             aWallCID = OUString();
     503           0 :         uno::Reference< drawing::XShapes > xWallGroup_Shapes( m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, aWallCID ) );
     504             : 
     505           0 :         CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     506           0 :         CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     507             : 
     508             :         //add left wall
     509             :         {
     510           0 :             short nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 3 : 1;
     511           0 :             double xPos = 0.0;
     512           0 :             if( CuboidPlanePosition_Right==eLeftWallPos )
     513           0 :                 xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
     514             :             Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     515             :                 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
     516           0 :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
     517           0 :             if( CuboidPlanePosition_Right==eLeftWallPos )
     518             :             {
     519           0 :                 nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 2 : 0;
     520             :                 aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     521             :                     , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     522           0 :                     , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
     523             :             }
     524           0 :             aStripe.InvertNormal(true);
     525             : 
     526             :             uno::Reference< drawing::XShape > xShape =
     527             :                 m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe
     528           0 :                     , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
     529           0 :             if( !bAddFloorAndWall )
     530             :             {
     531             :                 //we always need this object as dummy object for correct scene dimensions
     532             :                 //but it should not be visible in this case:
     533           0 :                 AbstractShapeFactory::makeShapeInvisible( xShape );
     534           0 :             }
     535             :         }
     536             :         //add back wall
     537             :         {
     538           0 :             short nRotatedTexture = 0;
     539           0 :             double zPos = 0.0;
     540           0 :             if( CuboidPlanePosition_Front==eBackWallPos )
     541           0 :                     zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
     542             :             Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
     543             :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     544           0 :                 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
     545           0 :             if( CuboidPlanePosition_Front==eBackWallPos )
     546             :             {
     547             :                 aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
     548             :                 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
     549           0 :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
     550           0 :                 nRotatedTexture = 3;
     551             :             }
     552           0 :             aStripe.InvertNormal(true);
     553             : 
     554             :             uno::Reference< drawing::XShape > xShape =
     555             :                 m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe
     556           0 :                     , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
     557           0 :             if( !bAddFloorAndWall )
     558             :             {
     559             :                 //we always need this object as dummy object for correct scene dimensions
     560             :                 //but it should not be visible in this case:
     561           0 :                 AbstractShapeFactory::makeShapeInvisible( xShape );
     562           0 :             }
     563           0 :         }
     564             :     }
     565             : 
     566             :     try
     567             :     {
     568           0 :         uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY_THROW );
     569           0 :         uno::Reference< beans::XPropertySet > xDestProp( m_xOuterGroupShape, uno::UNO_QUERY_THROW );
     570             : 
     571             :         //perspective
     572             :         {
     573             :             //ignore distance and focal length from file format and model completely
     574             :             //use vrp only to indicate the distance of the camera and thus influence the perspective
     575           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE, uno::makeAny(
     576           0 :                                         static_cast<sal_Int32>(ThreeDHelper::getCameraDistance( xSourceProp ))));
     577           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE,
     578           0 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE));
     579             :         }
     580             : 
     581             :         //light
     582             :         {
     583           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE,
     584           0 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE));
     585           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR,
     586           0 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR));
     587           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING,
     588           0 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING));
     589           0 :             lcl_setLightSources( xSourceProp, xDestProp );
     590             :         }
     591             : 
     592             :         //rotation
     593             :         {
     594             :             //set diagrams rotation is set exclusively via the transformation matrix
     595             :             //don't set a camera at all!
     596             :             //the camera's rotation is incorporated into this matrix
     597             : 
     598           0 :             ::basegfx::B3DHomMatrix aEffectiveTranformation;
     599           0 :             aEffectiveTranformation.translate(-FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0);
     600             : 
     601           0 :             if(!m_bRightAngledAxes)
     602           0 :                 aEffectiveTranformation.rotate(m_fXAnglePi,m_fYAnglePi,m_fZAnglePi);
     603             :             else
     604           0 :                 aEffectiveTranformation.shearXY(m_fYAnglePi,-m_fXAnglePi);
     605             : 
     606             :             //#i98497# 3D charts are rendered with wrong size
     607           0 :             E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     608           0 :             xDestProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX,
     609           0 :                     uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTranformation ) ) );
     610           0 :         }
     611             :     }
     612           0 :     catch( const uno::Exception & ex )
     613             :     {
     614             :         ASSERT_EXCEPTION( ex );
     615             :     }
     616             : 
     617             :     //add floor plate
     618             :     {
     619           0 :         uno::Reference< beans::XPropertySet > xFloorProp( NULL );
     620           0 :         if( m_xDiagram.is() )
     621           0 :             xFloorProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getFloor());
     622             : 
     623             :         Stripe aStripe( drawing::Position3D(0,0,0)
     624             :             , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
     625           0 :             , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
     626           0 :         aStripe.InvertNormal(true);
     627             : 
     628             :         uno::Reference< drawing::XShape > xShape =
     629             :             m_pShapeFactory->createStripe(xOuterGroup_Shapes, aStripe
     630           0 :                 , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, 0, bFlatNormals );
     631             : 
     632           0 :         CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     633           0 :         if( !bAddFloorAndWall || (CuboidPlanePosition_Bottom!=eBottomPos) )
     634             :         {
     635             :             //we always need this object as dummy object for correct scene dimensions
     636             :             //but it should not be visible in this case:
     637           0 :             AbstractShapeFactory::makeShapeInvisible( xShape );
     638             :         }
     639             :         else
     640             :         {
     641           0 :             OUString aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) );//@todo read CID from model
     642           0 :             AbstractShapeFactory::setShapeName( xShape, aFloorCID );
     643           0 :         }
     644             :     }
     645             : 
     646             :     //create an additional scene for the smaller inner coordinate region:
     647             :     {
     648           0 :         uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID" );
     649           0 :         m_xCoordinateRegionShape = uno::Reference< drawing::XShape >( xShapes, uno::UNO_QUERY );
     650             : 
     651           0 :         uno::Reference< beans::XPropertySet > xShapeProp( m_xCoordinateRegionShape, uno::UNO_QUERY );
     652             :         OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
     653           0 :         if( xShapeProp.is())
     654             :         {
     655             :             try
     656             :             {
     657           0 :                 double fXScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     658           0 :                 double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     659           0 :                 double fZScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     660             : 
     661           0 :                 ::basegfx::B3DHomMatrix aM;
     662           0 :                 aM.translate(GRID_TO_WALL_DISTANCE/fXScale, GRID_TO_WALL_DISTANCE/fYScale, GRID_TO_WALL_DISTANCE/fZScale);
     663           0 :                 aM.scale( fXScale, fYScale, fZScale );
     664           0 :                 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     665           0 :                 xShapeProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
     666           0 :                     , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM)) );
     667             :             }
     668           0 :             catch( const uno::Exception& e )
     669             :             {
     670             :                 ASSERT_EXCEPTION( e );
     671             :             }
     672           0 :         }
     673             :     }
     674             : 
     675           0 :     m_aCurrentPosWithoutAxes = m_aAvailablePosIncludingAxes;
     676           0 :     m_aCurrentSizeWithoutAxes = m_aAvailableSizeIncludingAxes;
     677           0 :     adjustPosAndSize_3d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
     678             : }
     679             : 
     680           0 : uno::Reference< drawing::XShapes > VDiagram::getCoordinateRegion()
     681             : {
     682           0 :     return uno::Reference<drawing::XShapes>( m_xCoordinateRegionShape, uno::UNO_QUERY );
     683             : }
     684             : 
     685           0 : ::basegfx::B2IRectangle VDiagram::getCurrentRectangle()
     686             : {
     687           0 :     return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
     688             : }
     689             : 
     690           0 : void VDiagram::reduceToMimimumSize()
     691             : {
     692           0 :     if( m_xOuterGroupShape.is() )
     693             :     {
     694           0 :         awt::Size aMaxSize( m_aAvailableSizeIncludingAxes );
     695           0 :         awt::Point aMaxPos( m_aAvailablePosIncludingAxes );
     696             : 
     697           0 :         sal_Int32 nNewWidth = aMaxSize.Width/3;
     698           0 :         sal_Int32 nNewHeight = aMaxSize.Height/3;
     699           0 :         awt::Size aNewSize( nNewWidth, nNewHeight );
     700           0 :         awt::Point aNewPos( aMaxPos );
     701           0 :         aNewPos.X += nNewWidth;
     702           0 :         aNewPos.Y += nNewHeight;
     703             : 
     704           0 :         adjustPosAndSize( aNewPos, aNewSize );
     705             :     }
     706           0 : }
     707             : 
     708           0 : ::basegfx::B2IRectangle VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle& rConsumedOuterRect )
     709             : {
     710           0 :     awt::Point aNewPos( m_aCurrentPosWithoutAxes );
     711           0 :     awt::Size aNewSize( m_aCurrentSizeWithoutAxes );
     712             : 
     713             :     ::basegfx::B2IRectangle rAvailableOuterRect(
     714           0 :         BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
     715             : 
     716           0 :     sal_Int32 nDeltaWidth = static_cast<sal_Int32>(rAvailableOuterRect.getWidth() - rConsumedOuterRect.getWidth());
     717           0 :     sal_Int32 nDeltaHeight = static_cast<sal_Int32>(rAvailableOuterRect.getHeight() - rConsumedOuterRect.getHeight());
     718           0 :     if( (aNewSize.Width + nDeltaWidth) < rAvailableOuterRect.getWidth()/3 )
     719           0 :         nDeltaWidth = static_cast<sal_Int32>(rAvailableOuterRect.getWidth()/3 - aNewSize.Width);
     720           0 :     aNewSize.Width += nDeltaWidth;
     721             : 
     722           0 :     if( (aNewSize.Height + nDeltaHeight) < rAvailableOuterRect.getHeight()/3 )
     723           0 :         nDeltaHeight = static_cast<sal_Int32>(rAvailableOuterRect.getHeight()/3 - aNewSize.Height);
     724           0 :     aNewSize.Height += nDeltaHeight;
     725             : 
     726           0 :     sal_Int32 nDiffLeft = rConsumedOuterRect.getMinX() - rAvailableOuterRect.getMinX();
     727           0 :     sal_Int32 nDiffRight = rAvailableOuterRect.getMaxX() - rConsumedOuterRect.getMaxX();
     728           0 :     if( nDiffLeft >= 0 )
     729           0 :         aNewPos.X -= nDiffLeft;
     730           0 :     else if( nDiffRight >= 0 )
     731             :     {
     732           0 :         if( nDiffRight > -nDiffLeft )
     733           0 :             aNewPos.X += abs(nDiffLeft);
     734           0 :         else if( nDiffRight > abs(nDeltaWidth) )
     735           0 :             aNewPos.X += nDiffRight;
     736             :         else
     737           0 :             aNewPos.X += abs(nDeltaWidth);
     738             :     }
     739             : 
     740           0 :     sal_Int32 nDiffUp = rConsumedOuterRect.getMinY() - rAvailableOuterRect.getMinY();
     741           0 :     sal_Int32 nDiffDown = rAvailableOuterRect.getMaxY() - rConsumedOuterRect.getMaxY();
     742           0 :     if( nDiffUp >= 0 )
     743           0 :         aNewPos.Y -= nDiffUp;
     744           0 :     else if( nDiffDown >= 0 )
     745             :     {
     746           0 :         if( nDiffDown > -nDiffUp )
     747           0 :             aNewPos.Y += abs(nDiffUp);
     748           0 :         else if( nDiffDown > abs(nDeltaHeight) )
     749           0 :             aNewPos.Y += nDiffDown;
     750             :         else
     751           0 :             aNewPos.Y += abs(nDeltaHeight);
     752             :     }
     753             : 
     754           0 :     return adjustPosAndSize( aNewPos, aNewSize );
     755             : }
     756             : 
     757             : } //namespace chart
     758             : 
     759             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10