LCOV - code coverage report
Current view: top level - chart2/source/view/main - ChartView.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1285 1727 74.4 %
Date: 2015-06-13 12:38:46 Functions: 82 116 70.7 %
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 <config_features.h>
      21             : 
      22             : #include "ChartView.hxx"
      23             : #include "chartview/DrawModelWrapper.hxx"
      24             : #include "NumberFormatterWrapper.hxx"
      25             : #include "ViewDefines.hxx"
      26             : #include "VDiagram.hxx"
      27             : #include "VTitle.hxx"
      28             : #include "AbstractShapeFactory.hxx"
      29             : #include "VCoordinateSystem.hxx"
      30             : #include "VSeriesPlotter.hxx"
      31             : #include "CommonConverters.hxx"
      32             : #include "macros.hxx"
      33             : #include "TitleHelper.hxx"
      34             : #include "LegendHelper.hxx"
      35             : #include "VLegend.hxx"
      36             : #include "PropertyMapper.hxx"
      37             : #include "ChartModelHelper.hxx"
      38             : #include "ChartTypeHelper.hxx"
      39             : #include "ScaleAutomatism.hxx"
      40             : #include "MinimumAndMaximumSupplier.hxx"
      41             : #include "ObjectIdentifier.hxx"
      42             : #include "DiagramHelper.hxx"
      43             : #include "RelativePositionHelper.hxx"
      44             : #include "servicenames.hxx"
      45             : #include "AxisHelper.hxx"
      46             : #include "AxisIndexDefines.hxx"
      47             : #include "ControllerLockGuard.hxx"
      48             : #include "BaseGFXHelper.hxx"
      49             : #include "DataSeriesHelper.hxx"
      50             : #include "DateHelper.hxx"
      51             : #include "defines.hxx"
      52             : #include <unonames.hxx>
      53             : #include <GL3DBarChart.hxx>
      54             : 
      55             : #include <editeng/frmdiritem.hxx>
      56             : #include <rtl/uuid.h>
      57             : #include <tools/globname.hxx>
      58             : #include <comphelper/scopeguard.hxx>
      59             : #include <comphelper/servicehelper.hxx>
      60             : #include <cppuhelper/supportsservice.hxx>
      61             : #include <boost/bind.hpp>
      62             : #include <unotools/streamwrap.hxx>
      63             : #include <unotools/localedatawrapper.hxx>
      64             : #include <svx/charthelper.hxx>
      65             : #include <svx/svdpage.hxx>
      66             : #include <svx/unopage.hxx>
      67             : #include <svx/unoshape.hxx>
      68             : #include <vcl/svapp.hxx>
      69             : #include <osl/mutex.hxx>
      70             : #include <svx/unofill.hxx>
      71             : #include <vcl/openglwin.hxx>
      72             : #include <vcl/opengl/OpenGLContext.hxx>
      73             : 
      74             : #include <drawinglayer/XShapeDumper.hxx>
      75             : 
      76             : #include <time.h>
      77             : 
      78             : #include <com/sun/star/awt/Size.hpp>
      79             : #include <com/sun/star/awt/Point.hpp>
      80             : #include <com/sun/star/chart/ChartAxisPosition.hpp>
      81             : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      82             : #include <com/sun/star/chart/MissingValueTreatment.hpp>
      83             : #include <com/sun/star/chart2/StackingDirection.hpp>
      84             : #include <com/sun/star/chart2/XChartDocument.hpp>
      85             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      86             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      87             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      88             : #include <com/sun/star/chart2/XTitled.hpp>
      89             : #include <com/sun/star/chart2/RelativePosition.hpp>
      90             : #include <com/sun/star/chart2/RelativeSize.hpp>
      91             : #include <com/sun/star/drawing/FillStyle.hpp>
      92             : #include <com/sun/star/drawing/GraphicExportFilter.hpp>
      93             : #include <com/sun/star/drawing/LineStyle.hpp>
      94             : #include <com/sun/star/drawing/XShapeGroup.hpp>
      95             : #include <com/sun/star/drawing/XShapeDescriptor.hpp>
      96             : #include <com/sun/star/document/XExporter.hpp>
      97             : #include <com/sun/star/document/XFilter.hpp>
      98             : #include <com/sun/star/embed/Aspects.hpp>
      99             : #include <com/sun/star/io/XSeekable.hpp>
     100             : #include <com/sun/star/util/XModifiable.hpp>
     101             : #include <com/sun/star/util/XRefreshable.hpp>
     102             : #include <com/sun/star/util/NumberFormat.hpp>
     103             : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
     104             : #include <com/sun/star/text/XText.hpp>
     105             : #include <com/sun/star/text/XTextDocument.hpp>
     106             : #include <com/sun/star/text/WritingMode2.hpp>
     107             : #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
     108             : #include <com/sun/star/view/XSelectionSupplier.hpp>
     109             : #include <svl/languageoptions.hxx>
     110             : #include <comphelper/classids.hxx>
     111             : #include "servicenames_charttypes.hxx"
     112             : 
     113             : #include <rtl/strbuf.hxx>
     114             : #include <rtl/ustring.hxx>
     115             : 
     116             : #include <osl/conditn.hxx>
     117             : #include <osl/time.h>
     118             : 
     119             : #include <boost/shared_ptr.hpp>
     120             : #include <boost/ptr_container/ptr_vector.hpp>
     121             : 
     122             : namespace chart {
     123             : 
     124             : using namespace ::com::sun::star;
     125             : using namespace ::com::sun::star::chart2;
     126             : using ::com::sun::star::uno::Reference;
     127             : using ::com::sun::star::uno::Sequence;
     128             : using ::com::sun::star::uno::Any;
     129             : 
     130             : namespace {
     131             : 
     132             : class theExplicitValueProviderUnoTunnelId  : public rtl::Static<UnoTunnelIdInit, theExplicitValueProviderUnoTunnelId> {};
     133             : 
     134             : typedef std::pair< sal_Int32, sal_Int32 > tFullAxisIndex; //first index is the dimension, second index is the axis index that indicates whether this is a main or secondary axis
     135             : typedef std::map< VCoordinateSystem*, tFullAxisIndex > tCoordinateSystemMap;
     136             : 
     137             : /** This class handles a collection of coordinate systems and is used for
     138             :  *  executing some action on all coordinate systems such as
     139             :  *  `prepareAutomaticAxisScaling` and `setExplicitScaleAndIncrement`.
     140             :  *  Moreover it contains the `aAutoScaling` object that is an instance of
     141             :  *  the `ScaleAutomatism` class. The initialization of `aAutoScaling` is
     142             :  *  performed in the `SeriesPlotterContainer::initAxisUsageList` method and is
     143             :  *  used in the `SeriesPlotterContainer::doAutoScaling` for calculating explicit
     144             :  *  scale and increment objects (see `SeriesPlotterContainer::doAutoScaling`).
     145             :  */
     146             : struct AxisUsage
     147             : {
     148             :     AxisUsage();
     149             :     ~AxisUsage();
     150             : 
     151             :     void addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );
     152             :     ::std::vector< VCoordinateSystem* > getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );
     153             :     sal_Int32 getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex );
     154             : 
     155             :     void prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex );
     156             :     void setExplicitScaleAndIncrement( sal_Int32 nDimIndex, sal_Int32 nAxisIndex, const ExplicitScaleData& rScale, const ExplicitIncrementData& rInc );
     157             : 
     158             :     ScaleAutomatism aAutoScaling;
     159             : 
     160             : private:
     161             :     tCoordinateSystemMap    aCoordinateSystems;
     162             :     std::map< sal_Int32, sal_Int32 > aMaxIndexPerDimension;
     163             : };
     164             : 
     165        2209 : AxisUsage::AxisUsage()
     166        2209 :     : aAutoScaling(AxisHelper::createDefaultScale(), Date(Date::SYSTEM))
     167             : {
     168        2209 : }
     169             : 
     170        4418 : AxisUsage::~AxisUsage()
     171             : {
     172        2209 :     aCoordinateSystems.clear();
     173        2209 : }
     174             : 
     175        2209 : void AxisUsage::addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
     176             : {
     177        2209 :     if(!pCooSys)
     178           0 :         return;
     179             : 
     180        2209 :     tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
     181        2209 :     tCoordinateSystemMap::const_iterator aFound( aCoordinateSystems.find(pCooSys) );
     182             : 
     183             :     //use one scale only once for each coordinate system
     184             :     //main axis are preferred over secondary axis
     185             :     //value scales are preferred
     186        2209 :     if(aFound!=aCoordinateSystems.end())
     187             :     {
     188           0 :         sal_Int32 nFoundAxisIndex = aFound->second.second;
     189           0 :         if( nFoundAxisIndex < nAxisIndex )
     190           0 :             return;
     191           0 :         sal_Int32 nFoundDimension = aFound->second.first;
     192           0 :         if( nFoundDimension ==1 )
     193           0 :             return;
     194           0 :         if( nFoundDimension < nDimensionIndex )
     195           0 :             return;
     196             :     }
     197        2209 :     aCoordinateSystems[pCooSys] = aFullAxisIndex;
     198             : 
     199             :     //set maximum scale index
     200        2209 :     std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex);
     201        2209 :     if( aIter != aMaxIndexPerDimension.end() )
     202             :     {
     203           0 :         sal_Int32 nCurrentMaxIndex = aIter->second;
     204           0 :         if( nCurrentMaxIndex < nAxisIndex )
     205           0 :             aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex;
     206             :     }
     207             :     else
     208        2209 :         aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex;
     209             : }
     210             : 
     211       45252 : ::std::vector< VCoordinateSystem* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
     212             : {
     213       45252 :     ::std::vector< VCoordinateSystem* > aRet;
     214             : 
     215       45252 :     tCoordinateSystemMap::const_iterator aIter;
     216       90504 :     for( aIter = aCoordinateSystems.begin(); aIter!=aCoordinateSystems.end();++aIter )
     217             :     {
     218       45252 :         if( aIter->second.first != nDimensionIndex )
     219       29497 :             continue;
     220       15755 :         if( aIter->second.second != nAxisIndex )
     221         672 :             continue;
     222       15083 :         aRet.push_back( aIter->first );
     223             :     }
     224             : 
     225       45252 :     return aRet;
     226             : }
     227             : 
     228        4589 : sal_Int32 AxisUsage::getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex )
     229             : {
     230        4589 :     sal_Int32 nRet = -1;
     231        4589 :     std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex);
     232        4589 :     if( aIter != aMaxIndexPerDimension.end() )
     233        2209 :         nRet = aIter->second;
     234        4589 :     return nRet;
     235             : }
     236             : 
     237       13638 : void AxisUsage::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
     238             : {
     239       13638 :     std::vector<VCoordinateSystem*> aVCooSysList = getCoordinateSystems(nDimIndex, nAxisIndex);
     240       17976 :     for (size_t i = 0, n = aVCooSysList.size(); i < n; ++i)
     241       17976 :         aVCooSysList[i]->prepareAutomaticAxisScaling(rScaleAutomatism, nDimIndex, nAxisIndex);
     242       13638 : }
     243             : 
     244       22730 : void AxisUsage::setExplicitScaleAndIncrement(
     245             :     sal_Int32 nDimIndex, sal_Int32 nAxisIndex, const ExplicitScaleData& rScale, const ExplicitIncrementData& rInc )
     246             : {
     247       22730 :     std::vector<VCoordinateSystem*> aVCooSysList = getCoordinateSystems(nDimIndex, nAxisIndex);
     248       29289 :     for (size_t i = 0, n = aVCooSysList.size(); i < n; ++i)
     249       29289 :         aVCooSysList[i]->setExplicitScaleAndIncrement(nDimIndex, nAxisIndex, rScale, rInc);
     250       22730 : }
     251             : 
     252             : typedef boost::ptr_vector<VSeriesPlotter> SeriesPlottersType;
     253             : 
     254             : /** This class is a container of `SeriesPlotter` objects (such as `PieChart`
     255             :  *  instances). It is used for initializing coordinate systems, axes and scales
     256             :  *  of all series plotters which belongs to the container.
     257             :  */
     258             : class SeriesPlotterContainer
     259             : {
     260             : public:
     261             :     explicit SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList );
     262             :     ~SeriesPlotterContainer();
     263             : 
     264             :     /** It is used to set coordinate systems (`m_rVCooSysList`), this method
     265             :      *  is invoked by `ChartView::createShapes2D` before of
     266             :      *  `ChartView::impl_createDiagramAndContent`.
     267             :      *  Coordinate systems are retrieved through the `XCoordinateSystemContainer`
     268             :      *  interface implemented by a diagram object which is provided by the
     269             :      *  `ChartModel` object passed to the method (`rChartModel.getFirstDiagram()`).
     270             :      *
     271             :      *  It is used for creating series plotters and appending them
     272             :      *  to `m_aSeriesPlotterList`. The created series plotters are initialized
     273             :      *  through data (number formats supplier, color scheme, data series),
     274             :      *  extracted from the chart model or the diagram objects. An exception is
     275             :      *  the explicit category provider that is retrieved through the
     276             :      *  `VCoordinateSystem` object used by the series plotter.
     277             :      *
     278             :      *  It sets the minimum-maximum supplier for a coordinate system:
     279             :      *  this supplier is the series plotter itself which utilizes the given
     280             :      *  coordinate system. In fact `VSeriesPlotter` has `MinimumMaximumSupplier`
     281             :      *  as one of its base classes.
     282             :      *  Hence, for instance, a `PieChart`, which is a series plotter, is
     283             :      *  a `MinimumMaximumSupplier`, too.
     284             :      */
     285             :     void initializeCooSysAndSeriesPlotter( ChartModel& rModel );
     286             : 
     287             :     /** This method is invoked by `ChartView::impl_createDiagramAndContent`.
     288             :      *  It iterates on every axis of every coordinate systems, and if the axis
     289             :      *  is not yet present in `m_aAxisUsageList` it creates a new `AxisUsage`
     290             :      *  object and initialize its `aAutoScaling` member to the `ScaleData`
     291             :      *  object of the current axis.
     292             :      */
     293             :     void initAxisUsageList(const Date& rNullDate);
     294             : 
     295             :     /**
     296             :      * Perform automatic axis scaling and determine the amount and spacing of
     297             :      * increments.  It assumes that the caller has determined the size of the
     298             :      * largest axis label text object prior to calling this method.
     299             :      *
     300             :      * The new axis scaling data will be stored in the VCoordinateSystem
     301             :      * objects.  The label alignment direction for each axis will also get
     302             :      * determined during this process, and stored in VAxis.
     303             :      *
     304             :      * This method is invoked by `ChartView::impl_createDiagramAndContent`
     305             :      * soon after `initAxisUsageList`.
     306             :      * It initializes explicit scale and increment objects for all coordinate
     307             :      * systems in `m_rVCooSysList`.
     308             :      * This action is achieved by iterating on the `m_aAxisUsageList` container,
     309             :      * and performing 3 steps:
     310             :      *   1- call `VCoordinateSystem::prepareAutomaticAxisScaling` for setting
     311             :      *      scaling parameters of the `aAutoScaling` member (a `ScaleAutomatism`
     312             :      *      object) for the current `AxisUsage` instance
     313             :      *      (see `VCoordinateSystem::prepareAutomaticAxisScaling`);
     314             :      *   2- calculate the explicit scale and increment objects
     315             :      *      (see ScaleAutomatism::calculateExplicitScaleAndIncrement);
     316             :      *   3- set the explicit scale and increment objects for each coordinate
     317             :      *      system.
     318             :      */
     319             :     void doAutoScaling( ChartModel& rModel );
     320             : 
     321             :     /**
     322             :      * After auto-scaling is performed, call this method to set the explicit
     323             :      * scaling and increment data to all relevant VAxis objects.
     324             :      */
     325             :     void updateScalesAndIncrementsOnAxes();
     326             : 
     327             :     /**
     328             :      * After auto-scaling is performed, call this method to set the explicit
     329             :      * scaling data to all the plotters.
     330             :      */
     331             :     void setScalesFromCooSysToPlotter();
     332             : 
     333             :     void setNumberFormatsFromAxes();
     334             :     drawing::Direction3D getPreferredAspectRatio();
     335             : 
     336        1053 :     SeriesPlottersType& getSeriesPlotterList() { return m_aSeriesPlotterList; }
     337        1053 :     std::vector< VCoordinateSystem* >& getCooSysList() { return m_rVCooSysList; }
     338             :     std::vector< LegendEntryProvider* > getLegendEntryProviderList();
     339             : 
     340             :     void AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel );
     341             : 
     342             :     bool isCategoryPositionShifted(
     343             :         const chart2::ScaleData& rSourceScale, bool bHasComplexCategories ) const;
     344             : 
     345             : private:
     346             :     /** A vector of series plotters.
     347             :      */
     348             :     SeriesPlottersType m_aSeriesPlotterList;
     349             : 
     350             :     /** A vector of coordinate systems.
     351             :      */
     352             :     std::vector< VCoordinateSystem* >& m_rVCooSysList;
     353             : 
     354             :     /** A map whose key is a `XAxis` interface and the related value is
     355             :      *  an object of `AxisUsage` type.
     356             :      */
     357             :     ::std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList;
     358             : 
     359             :     /**
     360             :      * Max axis index of all dimensions.  Currently this can be either 0 or 1
     361             :      * since we only support primary and secondary axes per dimension.  The
     362             :      * value of 0 means all dimensions have only primary axis, while 1 means
     363             :      * at least one dimension has a secondary axis.
     364             :      */
     365             :     sal_Int32 m_nMaxAxisIndex;
     366             : 
     367             :     bool m_bChartTypeUsesShiftedCategoryPositionPerDefault;
     368             :     sal_Int32 m_nDefaultDateNumberFormat;
     369             : };
     370             : 
     371        1121 : SeriesPlotterContainer::SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList )
     372             :         : m_rVCooSysList( rVCooSysList )
     373             :         , m_nMaxAxisIndex(0)
     374             :         , m_bChartTypeUsesShiftedCategoryPositionPerDefault(false)
     375        1121 :         , m_nDefaultDateNumberFormat(0)
     376             : {
     377        1121 : }
     378             : 
     379        2242 : SeriesPlotterContainer::~SeriesPlotterContainer()
     380             : {
     381             :     // - remove plotter from coordinatesystems
     382        2174 :     for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
     383        1053 :         m_rVCooSysList[nC]->clearMinimumAndMaximumSupplierList();
     384        1121 : }
     385             : 
     386        1121 : std::vector< LegendEntryProvider* > SeriesPlotterContainer::getLegendEntryProviderList()
     387             : {
     388        1121 :     std::vector< LegendEntryProvider* > aRet( m_aSeriesPlotterList.size() );
     389        1121 :     SeriesPlottersType::iterator       aPlotterIter = m_aSeriesPlotterList.begin();
     390        1121 :     const SeriesPlottersType::iterator aPlotterEnd  = m_aSeriesPlotterList.end();
     391        1121 :     sal_Int32 nN = 0;
     392        2195 :     for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter, nN++ )
     393        1074 :         aRet[nN] = &(*aPlotterIter);
     394        1121 :     return aRet;
     395             : }
     396             : 
     397       14596 : VCoordinateSystem* findInCooSysList( const std::vector< VCoordinateSystem* >& rVCooSysList
     398             :                                     , const uno::Reference< XCoordinateSystem >& xCooSys )
     399             : {
     400       14596 :     for( size_t nC=0; nC < rVCooSysList.size(); nC++)
     401             :     {
     402       13541 :         VCoordinateSystem* pVCooSys = rVCooSysList[nC];
     403       13541 :         if(pVCooSys->getModel()==xCooSys)
     404       13541 :             return pVCooSys;
     405             :     }
     406        1055 :     return NULL;
     407             : }
     408             : 
     409        4296 : VCoordinateSystem* lcl_getCooSysForPlotter( const std::vector< VCoordinateSystem* >& rVCooSysList, MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
     410             : {
     411        4296 :     if(!pMinimumAndMaximumSupplier)
     412           0 :         return 0;
     413        4296 :     for( size_t nC=0; nC < rVCooSysList.size(); nC++)
     414             :     {
     415        4296 :         VCoordinateSystem* pVCooSys = rVCooSysList[nC];
     416        4296 :         if(pVCooSys->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier ))
     417        4296 :             return pVCooSys;
     418             :     }
     419           0 :     return 0;
     420             : }
     421             : 
     422        1053 : VCoordinateSystem* addCooSysToList( std::vector< VCoordinateSystem* >& rVCooSysList
     423             :             , const uno::Reference< XCoordinateSystem >& xCooSys
     424             :             , ChartModel& rChartModel )
     425             : {
     426        1053 :     VCoordinateSystem* pVCooSys = findInCooSysList( rVCooSysList, xCooSys );
     427        1053 :     if( !pVCooSys )
     428             :     {
     429        1053 :         pVCooSys = VCoordinateSystem::createCoordinateSystem(xCooSys );
     430        1053 :         if(pVCooSys)
     431             :         {
     432        1053 :             OUString aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys, rChartModel ) );
     433        1053 :             pVCooSys->setParticle(aCooSysParticle);
     434             : 
     435        1053 :             pVCooSys->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys, rChartModel) );
     436             : 
     437        1053 :             rVCooSysList.push_back( pVCooSys );
     438             :         }
     439             :     }
     440        1053 :     return pVCooSys;
     441             : }
     442             : 
     443        1121 : void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
     444             :               ChartModel& rChartModel )
     445             : {
     446        1121 :     sal_Int32 nDiagramIndex = 0;//todo if more than one diagram is supported
     447        1121 :     uno::Reference< XDiagram > xDiagram( rChartModel.getFirstDiagram() );
     448        1121 :     if( !xDiagram.is())
     449          66 :         return;
     450             : 
     451        2110 :     uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject* >( &rChartModel ), uno::UNO_QUERY );
     452        1055 :     if( rChartModel.hasInternalDataProvider() && DiagramHelper::isSupportingDateAxis( xDiagram ) )
     453         843 :             m_nDefaultDateNumberFormat=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier );
     454             : 
     455        1055 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     456        1055 :     if(!nDimensionCount)
     457             :     {
     458             :         //@todo handle mixed dimension
     459           0 :         nDimensionCount = 2;
     460             :     }
     461             : 
     462        1055 :     bool bSortByXValues = false;
     463        1055 :     bool bConnectBars = false;
     464        1055 :     bool bGroupBarsPerAxis = true;
     465        1055 :     bool bIncludeHiddenCells = true;
     466        1055 :     sal_Int32 nStartingAngle = 90;
     467        1055 :     sal_Int32 n3DRelativeHeight = 100;
     468             :     try
     469             :     {
     470        1055 :         uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY_THROW );
     471        1055 :         xDiaProp->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= bSortByXValues;
     472        1055 :         xDiaProp->getPropertyValue( "ConnectBars" ) >>= bConnectBars;
     473        1055 :         xDiaProp->getPropertyValue( "GroupBarsPerAxis" ) >>= bGroupBarsPerAxis;
     474        1055 :         xDiaProp->getPropertyValue( "IncludeHiddenCells" ) >>= bIncludeHiddenCells;
     475        1055 :         xDiaProp->getPropertyValue( "StartingAngle" ) >>= nStartingAngle;
     476             : 
     477        1055 :         if (nDimensionCount == 3)
     478             :         {
     479          55 :             xDiaProp->getPropertyValue( "3DRelativeHeight" ) >>= n3DRelativeHeight;
     480        1055 :         }
     481             :     }
     482           0 :     catch( const uno::Exception & ex )
     483             :     {
     484             :         ASSERT_EXCEPTION( ex );
     485             :     }
     486             : 
     487             :     //prepare for autoscaling and shape creation
     488             :     // - create plotter for charttypes (for each first scale group at each plotter, as they are independent)
     489             :     // - add series to plotter (thus each charttype can provide minimum and maximum values for autoscaling)
     490             :     // - add plotter to coordinate systems
     491             : 
     492             :     //iterate through all coordinate systems
     493        2110 :     uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
     494             :     OSL_ASSERT( xCooSysContainer.is());
     495        1055 :     if( !xCooSysContainer.is())
     496           0 :         return;
     497        2110 :     uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
     498        2110 :     uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
     499        1055 :     sal_Int32 nGlobalSeriesIndex = 0;//for automatic symbols
     500        2108 :     for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
     501             :     {
     502        1053 :         uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
     503        1053 :         VCoordinateSystem* pVCooSys = addCooSysToList(m_rVCooSysList,xCooSys,rChartModel);
     504             : 
     505             :         //iterate through all chart types in the current coordinate system
     506        2106 :         uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
     507             :         OSL_ASSERT( xChartTypeContainer.is());
     508        1053 :         if( !xChartTypeContainer.is() )
     509           0 :             continue;
     510        2106 :         uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
     511        2127 :         for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
     512             :         {
     513        1074 :             uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
     514        1074 :             if(3 == nDimensionCount && xChartType->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE))
     515             :             {
     516           6 :                 uno::Reference< beans::XPropertySet > xPropertySet( xChartType, uno::UNO_QUERY );
     517           6 :                 if (xPropertySet.is())
     518             :                 {
     519             :                     try
     520             :                     {
     521           6 :                         sal_Int32 n3DRelativeHeightOldValue(100);
     522           6 :                         uno::Any aAny = xPropertySet->getPropertyValue( "3DRelativeHeight" );
     523           6 :                         aAny >>= n3DRelativeHeightOldValue;
     524           6 :                         if (n3DRelativeHeightOldValue != n3DRelativeHeight)
     525           0 :                             xPropertySet->setPropertyValue( "3DRelativeHeight", uno::makeAny(n3DRelativeHeight) );
     526             :                     }
     527           0 :                     catch (const uno::Exception&) { }
     528           6 :                 }
     529             :             }
     530             : 
     531        1074 :             if(nT==0)
     532        1053 :                 m_bChartTypeUsesShiftedCategoryPositionPerDefault = ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( xChartType );
     533             : 
     534        1074 :             bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram );
     535        1074 :             VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning );
     536        1074 :             if( !pPlotter )
     537           0 :                 continue;
     538             : 
     539        1074 :             m_aSeriesPlotterList.push_back( pPlotter );
     540        1074 :             pPlotter->setNumberFormatsSupplier( xNumberFormatsSupplier );
     541        1074 :             pPlotter->setColorScheme( xColorScheme );
     542        1074 :             if(pVCooSys)
     543        1074 :                 pPlotter->setExplicitCategoriesProvider( pVCooSys->getExplicitCategoriesProvider() );
     544        1074 :             sal_Int32 nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( xDiagram, xChartType );
     545             : 
     546        1074 :             if(pVCooSys)
     547        1074 :                 pVCooSys->addMinimumAndMaximumSupplier(pPlotter);
     548             : 
     549        2148 :             uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
     550             :             OSL_ASSERT( xDataSeriesContainer.is());
     551        1074 :             if( !xDataSeriesContainer.is() )
     552           0 :                 continue;
     553             : 
     554        1074 :             sal_Int32 zSlot=-1;
     555        1074 :             sal_Int32 xSlot=-1;
     556        1074 :             sal_Int32 ySlot=-1;
     557        2148 :             uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
     558        4176 :             for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
     559             :             {
     560        3102 :                 uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], uno::UNO_QUERY );
     561        3102 :                 if(!xDataSeries.is())
     562           0 :                     continue;
     563        3102 :                 if( !bIncludeHiddenCells && !DataSeriesHelper::hasUnhiddenData(xDataSeries) )
     564           4 :                     continue;
     565             : 
     566        3098 :                 VDataSeries* pSeries = new VDataSeries( xDataSeries );
     567             : 
     568        3098 :                 pSeries->setGlobalSeriesIndex(nGlobalSeriesIndex);
     569        3098 :                 nGlobalSeriesIndex++;
     570             : 
     571        3098 :                 if( bSortByXValues )
     572           0 :                     pSeries->doSortByXValues();
     573             : 
     574        3098 :                 pSeries->setConnectBars( bConnectBars );
     575        3098 :                 pSeries->setGroupBarsPerAxis( bGroupBarsPerAxis );
     576        3098 :                 pSeries->setStartingAngle( nStartingAngle );
     577             : 
     578        3098 :                 pSeries->setMissingValueTreatment( nMissingValueTreatment );
     579             : 
     580        6196 :                 OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCS, nT, nS ) );
     581        3098 :                 pSeries->setParticle(aSeriesParticle);
     582             : 
     583        6196 :                 OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
     584        3098 :                 pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole);
     585             : 
     586             :                 //ignore secondary axis for charttypes that do not suppoert them
     587        3132 :                 if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX &&
     588          34 :                     !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, 1 ) )
     589             :                 {
     590           0 :                     pSeries->setAttachedAxisIndex(MAIN_AXIS_INDEX);
     591             :                 }
     592             : 
     593        3098 :                 StackingDirection eDirection = pSeries->getStackingDirection();
     594        3098 :                 switch(eDirection)
     595             :                 {
     596             :                     case StackingDirection_NO_STACKING:
     597        2992 :                         xSlot++; ySlot=-1;
     598        2992 :                         if(zSlot<0)
     599        1037 :                             zSlot=0;
     600        2992 :                         break;
     601             :                     case StackingDirection_Y_STACKING:
     602          86 :                         ySlot++;
     603          86 :                         if(xSlot<0)
     604          30 :                             xSlot=0;
     605          86 :                         if(zSlot<0)
     606          30 :                             zSlot=0;
     607          86 :                         break;
     608             :                     case StackingDirection_Z_STACKING:
     609          20 :                         zSlot++; xSlot=-1; ySlot=-1;
     610          20 :                         break;
     611             :                     default:
     612             :                         // UNO enums have one additional auto-generated case
     613           0 :                         break;
     614             :                 }
     615        3098 :                 pPlotter->addSeries( pSeries, zSlot, xSlot, ySlot );
     616        3098 :             }
     617        1074 :         }
     618        1053 :     }
     619             : 
     620             :     //transport seriesnames to the coordinatesystems if needed
     621        1055 :     if( !m_aSeriesPlotterList.empty() )
     622             :     {
     623        1053 :         uno::Sequence< OUString > aSeriesNames;
     624        1053 :         bool bSeriesNamesInitialized = false;
     625        2106 :         for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
     626             :         {
     627        1053 :             VCoordinateSystem* pVCooSys = m_rVCooSysList[nC];
     628        1053 :             if(!pVCooSys)
     629           0 :                 continue;
     630        1053 :             if( pVCooSys->needSeriesNamesForAxis() )
     631             :             {
     632          55 :                 if(!bSeriesNamesInitialized)
     633             :                 {
     634          55 :                     VSeriesPlotter* pSeriesPlotter = &m_aSeriesPlotterList[0];
     635          55 :                     if( pSeriesPlotter )
     636          55 :                         aSeriesNames = pSeriesPlotter->getSeriesNames();
     637          55 :                     bSeriesNamesInitialized = true;
     638             :                 }
     639          55 :                 pVCooSys->setSeriesNamesForAxis( aSeriesNames );
     640             :             }
     641        1053 :         }
     642        1055 :     }
     643             : }
     644             : 
     645        2209 : bool SeriesPlotterContainer::isCategoryPositionShifted(
     646             :     const chart2::ScaleData& rSourceScale, bool bHasComplexCategories ) const
     647             : {
     648        2209 :     if (rSourceScale.AxisType == AxisType::CATEGORY && m_bChartTypeUsesShiftedCategoryPositionPerDefault)
     649         902 :         return true;
     650             : 
     651        1307 :     if (rSourceScale.AxisType==AxisType::CATEGORY && bHasComplexCategories)
     652           0 :         return true;
     653             : 
     654        1307 :     if (rSourceScale.AxisType == AxisType::DATE)
     655           0 :         return true;
     656             : 
     657        1307 :     if (rSourceScale.AxisType == AxisType::SERIES)
     658          55 :         return true;
     659             : 
     660        1252 :     return false;
     661             : }
     662             : 
     663        1053 : void SeriesPlotterContainer::initAxisUsageList(const Date& rNullDate)
     664             : {
     665        1053 :     m_aAxisUsageList.clear();
     666             : 
     667             :     // Loop through coordinate systems in the diagram (though for now
     668             :     // there should only be one coordinate system per diagram).
     669        2106 :     for (size_t i = 0, n = m_rVCooSysList.size(); i < n; ++i)
     670             :     {
     671        1053 :         VCoordinateSystem* pVCooSys = m_rVCooSysList[i];
     672        1053 :         uno::Reference<XCoordinateSystem> xCooSys = pVCooSys->getModel();
     673        1053 :         sal_Int32 nDimCount = xCooSys->getDimension();
     674             : 
     675        3214 :         for (sal_Int32 nDimIndex = 0; nDimIndex < nDimCount; ++nDimIndex)
     676             :         {
     677             :             bool bDateAxisAllowed = ChartTypeHelper::isSupportingDateAxis(
     678        2161 :                 AxisHelper::getChartTypeByIndex(xCooSys, 0), nDimCount, nDimIndex);
     679             : 
     680             :             // Each dimension may have primary and secondary axes.
     681        2161 :             const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex);
     682        4370 :             for (sal_Int32 nAxisIndex = 0; nAxisIndex <= nMaxAxisIndex; ++nAxisIndex)
     683             :             {
     684        2209 :                 uno::Reference<XAxis> xAxis = xCooSys->getAxisByDimension(nDimIndex, nAxisIndex);
     685             : 
     686        2209 :                 if (!xAxis.is())
     687           0 :                     continue;
     688             : 
     689        2209 :                 if (m_aAxisUsageList.find(xAxis) == m_aAxisUsageList.end())
     690             :                 {
     691             :                     // Create axis usage object for this axis.
     692             : 
     693        2209 :                     chart2::ScaleData aSourceScale = xAxis->getScaleData();
     694        2209 :                     ExplicitCategoriesProvider* pCatProvider = pVCooSys->getExplicitCategoriesProvider();
     695        2209 :                     if (nDimIndex == 0)
     696        1077 :                         AxisHelper::checkDateAxis( aSourceScale, pCatProvider, bDateAxisAllowed );
     697             : 
     698        2209 :                     bool bHasComplexCat = pCatProvider && pCatProvider->hasComplexCategories();
     699        2209 :                     aSourceScale.ShiftedCategoryPosition = isCategoryPositionShifted(aSourceScale, bHasComplexCat);
     700             : 
     701        2209 :                     m_aAxisUsageList[xAxis].aAutoScaling = ScaleAutomatism(aSourceScale, rNullDate);
     702             :                 }
     703             : 
     704        2209 :                 AxisUsage& rAxisUsage = m_aAxisUsageList[xAxis];
     705        2209 :                 rAxisUsage.addCoordinateSystem(pVCooSys, nDimIndex, nAxisIndex);
     706        2209 :             }
     707             :         }
     708        1053 :     }
     709             : 
     710             :     // Determine the highest axis index of all dimensions.
     711        1053 :     ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator             aAxisIter    = m_aAxisUsageList.begin();
     712        1053 :     const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
     713        1053 :     m_nMaxAxisIndex = 0;
     714        2106 :     for (size_t i = 0, n = m_rVCooSysList.size(); i < n; ++i)
     715             :     {
     716        1053 :         VCoordinateSystem* pVCooSys = m_rVCooSysList[i];
     717        1053 :         uno::Reference<XCoordinateSystem> xCooSys = pVCooSys->getModel();
     718        1053 :         sal_Int32 nDimCount = xCooSys->getDimension();
     719             : 
     720        3214 :         for (sal_Int32 nDimIndex = 0; nDimIndex < nDimCount; ++nDimIndex)
     721             :         {
     722        6750 :             for (aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter)
     723             :             {
     724        4589 :                 sal_Int32 nLocalMax = aAxisIter->second.getMaxAxisIndexForDimension(nDimIndex);
     725        4589 :                 if (m_nMaxAxisIndex < nLocalMax)
     726          26 :                     m_nMaxAxisIndex = nLocalMax;
     727             :             }
     728             :         }
     729        1053 :     }
     730        1053 : }
     731             : 
     732        2069 : void SeriesPlotterContainer::setScalesFromCooSysToPlotter()
     733             : {
     734             :     //set scales to plotter to enable them to provide the preferred scene AspectRatio
     735        2069 :     SeriesPlottersType::iterator       aPlotterIter = m_aSeriesPlotterList.begin();
     736        2069 :     const SeriesPlottersType::iterator aPlotterEnd  = m_aSeriesPlotterList.end();
     737        4180 :     for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
     738             :     {
     739        2111 :         VSeriesPlotter* pSeriesPlotter = &(*aPlotterIter);
     740        2111 :         VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter );
     741        2111 :         if(pVCooSys)
     742             :         {
     743        2111 :             pSeriesPlotter->setScales( pVCooSys->getExplicitScales(0,0), pVCooSys->getPropertySwapXAndYAxis() );
     744        2111 :             sal_Int32 nMaxAxisIndex = pVCooSys->getMaximumAxisIndexByDimension(1);//only additional value axis are relevant for series plotter
     745        2199 :             for( sal_Int32 nI=1; nI<=nMaxAxisIndex; nI++ )
     746          88 :                 pSeriesPlotter->addSecondaryValueScale( pVCooSys->getExplicitScale(1,nI), nI );
     747             :         }
     748             :     }
     749        2069 : }
     750             : 
     751        1053 : void SeriesPlotterContainer::setNumberFormatsFromAxes()
     752             : {
     753             :     //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis
     754        1053 :     SeriesPlottersType::iterator       aPlotterIter = m_aSeriesPlotterList.begin();
     755        1053 :     const SeriesPlottersType::iterator aPlotterEnd  = m_aSeriesPlotterList.end();
     756        2127 :     for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
     757             :     {
     758        1074 :         VSeriesPlotter* pSeriesPlotter = &(*aPlotterIter);
     759        1074 :         VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter );
     760        1074 :         if(pVCooSys)
     761             :         {
     762        1074 :             AxesNumberFormats aAxesNumberFormats;
     763        2148 :             uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel();
     764        1074 :             sal_Int32 nDimensionCount = xCooSys->getDimension();
     765        3277 :             for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nDimensionCount; ++nDimensionIndex)
     766             :             {
     767        2203 :                 const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
     768        4494 :                 for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
     769             :                 {
     770             :                     try
     771             :                     {
     772        2291 :                         Reference< beans::XPropertySet > xAxisProp( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
     773        2291 :                         if( xAxisProp.is())
     774             :                         {
     775        2291 :                             sal_Int32 nNumberFormatKey(0);
     776        2291 :                             if( xAxisProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey )
     777             :                             {
     778        1535 :                                 aAxesNumberFormats.setFormat( nNumberFormatKey, nDimensionIndex, nAxisIndex );
     779             :                             }
     780         756 :                             else if( nDimensionIndex==0 )
     781             :                             {
     782             :                                 //provide a default date format for date axis with own data
     783         165 :                                 aAxesNumberFormats.setFormat( m_nDefaultDateNumberFormat, nDimensionIndex, nAxisIndex );
     784             :                             }
     785        2291 :                         }
     786             :                     }
     787           0 :                     catch( const lang::IndexOutOfBoundsException& e )
     788             :                     {
     789             :                         ASSERT_EXCEPTION( e );
     790             :                     }
     791             :                 }
     792             :             }
     793        2148 :             pSeriesPlotter->setAxesNumberFormats( aAxesNumberFormats );
     794             :         }
     795             :     }
     796        1053 : }
     797             : 
     798        1016 : void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes()
     799             : {
     800        2032 :     for( size_t nC=0; nC < m_rVCooSysList.size(); nC++)
     801        1016 :         m_rVCooSysList[nC]->updateScalesAndIncrementsOnAxes();
     802        1016 : }
     803             : 
     804        2069 : void SeriesPlotterContainer::doAutoScaling( ChartModel& rChartModel )
     805             : {
     806        2069 :     if (m_aSeriesPlotterList.empty() || m_aAxisUsageList.empty())
     807             :         // We need these two containers populated to do auto-scaling.  Bail out.
     808        2069 :         return;
     809             : 
     810        2069 :     ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator             aAxisIter    = m_aAxisUsageList.begin();
     811        2069 :     const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
     812             : 
     813             :     //iterate over the main scales first than secondary axis
     814        4190 :     for (sal_Int32 nAxisIndex = 0; nAxisIndex <= m_nMaxAxisIndex; ++nAxisIndex)
     815             :     {
     816             :         // - first do autoscale for all x and z scales (because they are treated independent)
     817        6667 :         for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
     818             :         {
     819        4546 :             AxisUsage& rAxisUsage = (*aAxisIter).second;
     820             : 
     821        4546 :             rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 0, nAxisIndex);
     822        4546 :             rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 2, nAxisIndex);
     823             : 
     824        4546 :             ExplicitScaleData       aExplicitScale;
     825        9092 :             ExplicitIncrementData   aExplicitIncrement;
     826        4546 :             rAxisUsage.aAutoScaling.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement );
     827             : 
     828        4546 :             rAxisUsage.setExplicitScaleAndIncrement(0, nAxisIndex, aExplicitScale, aExplicitIncrement);
     829        4546 :             rAxisUsage.setExplicitScaleAndIncrement(2, nAxisIndex, aExplicitScale, aExplicitIncrement);
     830        4546 :         }
     831             : 
     832             :         // - second do autoscale for the dependent y scales (the coordinate systems are prepared with x and z scales already )
     833        6667 :         for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
     834             :         {
     835        4546 :             AxisUsage& rAxisUsage = (*aAxisIter).second;
     836             : 
     837        4546 :             rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 1, nAxisIndex);
     838             : 
     839        4546 :             ExplicitScaleData       aExplicitScale;
     840        9092 :             ExplicitIncrementData   aExplicitIncrement;
     841        4546 :             rAxisUsage.aAutoScaling.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement );
     842             : 
     843        4546 :             rAxisUsage.setExplicitScaleAndIncrement(0, nAxisIndex, aExplicitScale, aExplicitIncrement);
     844        4546 :             rAxisUsage.setExplicitScaleAndIncrement(1, nAxisIndex, aExplicitScale, aExplicitIncrement);
     845        4546 :             rAxisUsage.setExplicitScaleAndIncrement(2, nAxisIndex, aExplicitScale, aExplicitIncrement);
     846        4546 :         }
     847             :     }
     848        2069 :     AdaptScaleOfYAxisWithoutAttachedSeries( rChartModel );
     849             : }
     850             : 
     851        2069 : void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel )
     852             : {
     853             :     //issue #i80518#
     854             : 
     855        2069 :     ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator             aAxisIter    = m_aAxisUsageList.begin();
     856        2069 :     const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end();
     857             : 
     858        4190 :     for( sal_Int32 nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ )
     859             :     {
     860        6667 :         for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
     861             :         {
     862        4546 :             AxisUsage& rAxisUsage = (*aAxisIter).second;
     863        4546 :             ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems( 1, nAxisIndex );
     864        4546 :             if( !aVCooSysList_Y.size() )
     865        2429 :                 continue;
     866             : 
     867        2121 :             uno::Reference< XDiagram > xDiagram( rModel.getFirstDiagram() );
     868        2117 :             if (!xDiagram.is())
     869           0 :                 continue;
     870             : 
     871        2117 :             bool bSeriesAttachedToThisAxis = false;
     872        2117 :             sal_Int32 nAttachedAxisIndex = -1;
     873             :             {
     874        2117 :                 ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
     875        2117 :                 ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin();
     876        2187 :                 for( ; aIter != aSeriesVector.end(); ++aIter )
     877             :                 {
     878        2181 :                     sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter );
     879        2181 :                     if( nAxisIndex == nCurrentIndex )
     880             :                     {
     881        2111 :                         bSeriesAttachedToThisAxis = true;
     882        2111 :                         break;
     883             :                     }
     884          70 :                     else if( nAttachedAxisIndex<0 || nAttachedAxisIndex>nCurrentIndex )
     885          48 :                         nAttachedAxisIndex=nCurrentIndex;
     886        2117 :                 }
     887             :             }
     888             : 
     889        2117 :             if (bSeriesAttachedToThisAxis || nAttachedAxisIndex < 0)
     890        2113 :                 continue;
     891             : 
     892           8 :             for( size_t nC = 0; nC < aVCooSysList_Y.size(); ++nC )
     893             :             {
     894           4 :                 aVCooSysList_Y[nC]->prepareAutomaticAxisScaling( rAxisUsage.aAutoScaling, 1, nAttachedAxisIndex );
     895             : 
     896           4 :                 ExplicitScaleData aExplicitScaleSource = aVCooSysList_Y[nC]->getExplicitScale( 1,nAttachedAxisIndex );
     897           8 :                 ExplicitIncrementData aExplicitIncrementSource = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAttachedAxisIndex );
     898             : 
     899           8 :                 ExplicitScaleData aExplicitScaleDest = aVCooSysList_Y[nC]->getExplicitScale( 1,nAxisIndex );;
     900           8 :                 ExplicitIncrementData aExplicitIncrementDest = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAxisIndex );;
     901             : 
     902           4 :                 aExplicitScaleDest.Orientation = aExplicitScaleSource.Orientation;
     903           4 :                 aExplicitScaleDest.Scaling = aExplicitScaleSource.Scaling;
     904           4 :                 aExplicitScaleDest.AxisType = aExplicitScaleSource.AxisType;
     905             : 
     906           4 :                 aExplicitIncrementDest.BaseValue = aExplicitIncrementSource.BaseValue;
     907             : 
     908           8 :                 ScaleData aScale( rAxisUsage.aAutoScaling.getScale() );
     909           4 :                 if( !aScale.Minimum.hasValue() )
     910             :                 {
     911           4 :                     bool bNewMinOK = true;
     912           4 :                     double fMax=0.0;
     913           4 :                     if( aScale.Maximum >>= fMax )
     914           0 :                         bNewMinOK = (aExplicitScaleSource.Minimum <= fMax);
     915           4 :                     if( bNewMinOK )
     916           4 :                         aExplicitScaleDest.Minimum = aExplicitScaleSource.Minimum;
     917             :                 }
     918             :                 else
     919           0 :                     aExplicitIncrementDest.BaseValue = aExplicitScaleDest.Minimum;
     920             : 
     921           4 :                 if( !aScale.Maximum.hasValue() )
     922             :                 {
     923           4 :                     bool bNewMaxOK = true;
     924           4 :                     double fMin=0.0;
     925           4 :                     if( aScale.Minimum >>= fMin )
     926           0 :                         bNewMaxOK = (fMin <= aExplicitScaleSource.Maximum);
     927           4 :                     if( bNewMaxOK )
     928           4 :                         aExplicitScaleDest.Maximum = aExplicitScaleSource.Maximum;
     929             :                 }
     930           4 :                 if( !aScale.Origin.hasValue() )
     931           4 :                     aExplicitScaleDest.Origin = aExplicitScaleSource.Origin;
     932             : 
     933           4 :                 if( !aScale.IncrementData.Distance.hasValue() )
     934           4 :                     aExplicitIncrementDest.Distance = aExplicitIncrementSource.Distance;
     935             : 
     936           4 :                 bool bAutoMinorInterval = true;
     937           4 :                 if( aScale.IncrementData.SubIncrements.getLength() )
     938           4 :                     bAutoMinorInterval = !( aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() );
     939           4 :                 if( bAutoMinorInterval )
     940             :                 {
     941           4 :                     if( !aExplicitIncrementDest.SubIncrements.empty() && !aExplicitIncrementSource.SubIncrements.empty() )
     942           4 :                         aExplicitIncrementDest.SubIncrements[0].IntervalCount =
     943           4 :                             aExplicitIncrementSource.SubIncrements[0].IntervalCount;
     944             :                 }
     945             : 
     946           4 :                 aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScaleDest, aExplicitIncrementDest );
     947           4 :             }
     948           4 :         }
     949             :     }
     950             : 
     951        2069 :     if( AxisHelper::isAxisPositioningEnabled() )
     952             :     {
     953             :         //correct origin for y main axis (the origin is where the other main axis crosses)
     954        2069 :         sal_Int32 nAxisIndex=0;
     955        2069 :         sal_Int32 nDimensionIndex=1;
     956        6407 :         for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter )
     957             :         {
     958        4338 :             AxisUsage& rAxisUsage = (*aAxisIter).second;
     959        4338 :             ::std::vector< VCoordinateSystem* > aVCooSysList = rAxisUsage.getCoordinateSystems(nDimensionIndex,nAxisIndex);
     960             :             size_t nC;
     961        6407 :             for( nC=0; nC < aVCooSysList.size(); nC++)
     962             :             {
     963        2069 :                 ExplicitScaleData aExplicitScale( aVCooSysList[nC]->getExplicitScale( nDimensionIndex, nAxisIndex ) );
     964        4138 :                 ExplicitIncrementData aExplicitIncrement( aVCooSysList[nC]->getExplicitIncrement( nDimensionIndex, nAxisIndex ) );
     965             : 
     966        4138 :                 Reference< chart2::XCoordinateSystem > xCooSys( aVCooSysList[nC]->getModel() );
     967        4138 :                 Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
     968        4138 :                 Reference< beans::XPropertySet > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis, xCooSys ), uno::UNO_QUERY );
     969             : 
     970        2069 :                 ::com::sun::star::chart::ChartAxisPosition eCrossingMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
     971        2069 :                 if( xCrossingMainAxis.is() )
     972             :                 {
     973        2069 :                     xCrossingMainAxis->getPropertyValue("CrossoverPosition") >>= eCrossingMainAxisPos;
     974        2069 :                     if( ::com::sun::star::chart::ChartAxisPosition_VALUE == eCrossingMainAxisPos )
     975             :                     {
     976         132 :                         double fValue = 0.0;
     977         132 :                         xCrossingMainAxis->getPropertyValue("CrossoverValue") >>= fValue;
     978         132 :                         aExplicitScale.Origin = fValue;
     979             :                     }
     980        1937 :                     else if( ::com::sun::star::chart::ChartAxisPosition_ZERO == eCrossingMainAxisPos )
     981        1937 :                         aExplicitScale.Origin = 0.0;
     982           0 :                     else  if( ::com::sun::star::chart::ChartAxisPosition_START == eCrossingMainAxisPos )
     983           0 :                         aExplicitScale.Origin = aExplicitScale.Minimum;
     984           0 :                     else  if( ::com::sun::star::chart::ChartAxisPosition_END == eCrossingMainAxisPos )
     985           0 :                         aExplicitScale.Origin = aExplicitScale.Maximum;
     986             :                 }
     987             : 
     988        2069 :                 aVCooSysList[nC]->setExplicitScaleAndIncrement( nDimensionIndex, nAxisIndex, aExplicitScale, aExplicitIncrement );
     989        2069 :             }
     990        4338 :         }
     991             :     }
     992        2069 : }
     993             : 
     994        1053 : drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio()
     995             : {
     996        1053 :     drawing::Direction3D aPreferredAspectRatio(1.0,1.0,1.0);
     997             : 
     998        1053 :     sal_Int32 nPlotterCount=0;
     999             :     //get a list of all preferred aspect ratios and combine them
    1000             :     //first with special demands wins (less or equal zero <-> arbitrary)
    1001             :     double fx, fy, fz;
    1002        1053 :     fx = fy = fz = -1.0;
    1003        1053 :     SeriesPlottersType::const_iterator       aPlotterIter = m_aSeriesPlotterList.begin();
    1004        1053 :     const SeriesPlottersType::const_iterator aPlotterEnd  = m_aSeriesPlotterList.end();
    1005        3141 :     for( aPlotterIter = m_aSeriesPlotterList.begin(), nPlotterCount=0
    1006        1053 :         ; aPlotterIter != aPlotterEnd; ++aPlotterIter, ++nPlotterCount )
    1007             :     {
    1008        1074 :         drawing::Direction3D aSingleRatio( aPlotterIter->getPreferredDiagramAspectRatio() );
    1009        1074 :         if( fx<0 && aSingleRatio.DirectionX>0 )
    1010          77 :             fx = aSingleRatio.DirectionX;
    1011             : 
    1012        1074 :         if( fy<0 && aSingleRatio.DirectionY>0 )
    1013             :         {
    1014          50 :             if( fx>0 && aSingleRatio.DirectionX>0 )
    1015          39 :                 fy = fx*aSingleRatio.DirectionY/aSingleRatio.DirectionX;
    1016          11 :             else if( fz>0 && aSingleRatio.DirectionZ>0 )
    1017           0 :                 fy = fz*aSingleRatio.DirectionY/aSingleRatio.DirectionZ;
    1018             :             else
    1019          11 :                 fy = aSingleRatio.DirectionY;
    1020             :         }
    1021             : 
    1022        1074 :         if( fz<0 && aSingleRatio.DirectionZ>0 )
    1023             :         {
    1024          88 :             if( fx>0 && aSingleRatio.DirectionX>0 )
    1025          77 :                 fz = fx*aSingleRatio.DirectionZ/aSingleRatio.DirectionX;
    1026          11 :             else if( fy>0 && aSingleRatio.DirectionY>0 )
    1027          11 :                 fz = fy*aSingleRatio.DirectionZ/aSingleRatio.DirectionY;
    1028             :             else
    1029           0 :                 fz = aSingleRatio.DirectionZ;
    1030             :         }
    1031             : 
    1032        1074 :         if( fx>0 && fy>0 && fz>0 )
    1033          39 :             break;
    1034             :     }
    1035        1053 :     aPreferredAspectRatio = drawing::Direction3D(fx, fy, fz);
    1036        1053 :     return aPreferredAspectRatio;
    1037             : }
    1038             : 
    1039             : }
    1040             : 
    1041        1176 : struct CreateShapeParam2D
    1042             : {
    1043             :     css::awt::Rectangle maRemainingSpace;
    1044             : 
    1045             :     boost::shared_ptr<SeriesPlotterContainer> mpSeriesPlotterContainer;
    1046             : 
    1047             :     boost::shared_ptr<VTitle> mpVTitleX;
    1048             :     boost::shared_ptr<VTitle> mpVTitleY;
    1049             :     boost::shared_ptr<VTitle> mpVTitleZ;
    1050             : 
    1051             :     boost::shared_ptr<VTitle> mpVTitleSecondX;
    1052             :     boost::shared_ptr<VTitle> mpVTitleSecondY;
    1053             : 
    1054             :     css::uno::Reference<css::drawing::XShape> mxMarkHandles;
    1055             :     css::uno::Reference<css::drawing::XShape> mxPlotAreaWithAxes;
    1056             : 
    1057             :     css::uno::Reference<css::drawing::XShapes> mxDiagramWithAxesShapes;
    1058             : 
    1059             :     bool mbAutoPosTitleX;
    1060             :     bool mbAutoPosTitleY;
    1061             :     bool mbAutoPosTitleZ;
    1062             : 
    1063             :     bool mbAutoPosSecondTitleX;
    1064             :     bool mbAutoPosSecondTitleY;
    1065             : 
    1066             :     bool mbUseFixedInnerSize;
    1067             : 
    1068        1176 :     CreateShapeParam2D() :
    1069             :         mbAutoPosTitleX(true),
    1070             :         mbAutoPosTitleY(true),
    1071             :         mbAutoPosTitleZ(true),
    1072             :         mbAutoPosSecondTitleX(true),
    1073             :         mbAutoPosSecondTitleY(true),
    1074        1176 :         mbUseFixedInnerSize(false) {}
    1075             : };
    1076             : 
    1077             : class GL2DRenderer : public IRenderer
    1078             : {
    1079             : public:
    1080             :     explicit GL2DRenderer(ChartView* pView);
    1081             :     virtual ~GL2DRenderer();
    1082             : 
    1083             :     virtual void update() SAL_OVERRIDE;
    1084             :     virtual void clickedAt(const Point& rPos, sal_uInt16 nButton) SAL_OVERRIDE;
    1085             :     virtual void mouseDragMove(const Point& rBegin, const Point& rEnd, sal_uInt16 nButton) SAL_OVERRIDE;
    1086             :     virtual void scroll(long nDelta) SAL_OVERRIDE;
    1087             :     virtual void contextDestroyed() SAL_OVERRIDE;
    1088             : 
    1089             :     const OpenGLWindow* getOpenGLWindow() const;
    1090             :     void updateOpenGLWindow();
    1091             : private:
    1092             :     ChartView* mpView;
    1093             :     bool mbContextDestroyed;
    1094             :     VclPtr<OpenGLWindow> mpWindow;
    1095             : };
    1096             : 
    1097         321 : GL2DRenderer::GL2DRenderer(ChartView* pView):
    1098             :     mpView(pView),
    1099             :     mbContextDestroyed(false),
    1100         321 :     mpWindow(mpView->mrChartModel.getOpenGLWindow())
    1101             : {
    1102         321 : }
    1103             : 
    1104         915 : GL2DRenderer::~GL2DRenderer()
    1105             : {
    1106         305 :     if(!mbContextDestroyed && mpWindow)
    1107           0 :         mpWindow->setRenderer(NULL);
    1108         610 : }
    1109             : 
    1110           0 : void GL2DRenderer::update()
    1111             : {
    1112           0 :     mpView->update();
    1113           0 :     mpView->render();
    1114           0 : }
    1115             : 
    1116           0 : void GL2DRenderer::clickedAt(const Point&, sal_uInt16 )
    1117             : {
    1118           0 : }
    1119             : 
    1120           0 : void GL2DRenderer::mouseDragMove(const Point& , const Point& , sal_uInt16 )
    1121             : {
    1122           0 : }
    1123             : 
    1124           0 : void GL2DRenderer::scroll(long )
    1125             : {
    1126           0 : }
    1127             : 
    1128          17 : void GL2DRenderer::contextDestroyed()
    1129             : {
    1130          17 :     mbContextDestroyed = true;
    1131          17 : }
    1132             : 
    1133        1119 : const OpenGLWindow* GL2DRenderer::getOpenGLWindow() const
    1134             : {
    1135        1119 :     return mpWindow;
    1136             : }
    1137             : 
    1138          17 : void GL2DRenderer::updateOpenGLWindow()
    1139             : {
    1140          17 :     if(mbContextDestroyed)
    1141          17 :         return;
    1142             : 
    1143          17 :     OpenGLWindow* pWindow = mpView->mrChartModel.getOpenGLWindow();
    1144          17 :     if(pWindow != mpWindow)
    1145             :     {
    1146          17 :         if(mpWindow)
    1147             :         {
    1148           0 :             mpWindow->setRenderer(NULL);
    1149             :         }
    1150             : 
    1151          17 :         if(pWindow)
    1152             :         {
    1153          17 :             pWindow->setRenderer(this);
    1154             :         }
    1155             :     }
    1156          17 :     mpWindow = pWindow;
    1157             : }
    1158             : 
    1159       33506 : const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId()
    1160             : {
    1161       33506 :     return theExplicitValueProviderUnoTunnelId::get().getSeq();
    1162             : }
    1163             : 
    1164          17 : ExplicitValueProvider* ExplicitValueProvider::getExplicitValueProvider(
    1165             :         const Reference< uno::XInterface >& xChartView )
    1166             : {
    1167          17 :     ExplicitValueProvider* pExplicitValueProvider=0;
    1168             : 
    1169          17 :     Reference< lang::XUnoTunnel > xTunnel( xChartView, uno::UNO_QUERY );
    1170          17 :     if( xTunnel.is() )
    1171             :     {
    1172          17 :         pExplicitValueProvider = reinterpret_cast<ExplicitValueProvider*>(xTunnel->getSomething(
    1173          17 :             ExplicitValueProvider::getUnoTunnelId() ));
    1174             :     }
    1175          17 :     return pExplicitValueProvider;
    1176             : }
    1177             : 
    1178         321 : ChartView::ChartView(
    1179             :         uno::Reference<uno::XComponentContext> const & xContext,
    1180             :         ChartModel& rModel)
    1181             :     : m_aMutex()
    1182             :     , m_xCC(xContext)
    1183             :     , mrChartModel(rModel)
    1184             :     , m_xShapeFactory()
    1185             :     , m_xDrawPage()
    1186             :     , m_pDrawModelWrapper()
    1187             :     , m_aListenerContainer( m_aMutex )
    1188             :     , m_bViewDirty(true)
    1189             :     , m_bInViewUpdate(false)
    1190             :     , m_bViewUpdatePending(false)
    1191             :     , m_bRefreshAddIn(true)
    1192             :     , m_aPageResolution(1000,1000)
    1193             :     , m_bPointsWereSkipped(false)
    1194             :     , m_nScaleXNumerator(1)
    1195             :     , m_nScaleXDenominator(1)
    1196             :     , m_nScaleYNumerator(1)
    1197             :     , m_nScaleYDenominator(1)
    1198             :     , m_bSdrViewIsInEditMode(false)
    1199             :     , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0)
    1200         321 :     , mp2DRenderer(new GL2DRenderer(this))
    1201             : {
    1202         321 :     init();
    1203         321 : }
    1204             : 
    1205         321 : void ChartView::init()
    1206             : {
    1207         321 :     if( !m_pDrawModelWrapper.get() )
    1208             :     {
    1209         321 :         SolarMutexGuard aSolarGuard;
    1210         321 :         m_pDrawModelWrapper = ::boost::shared_ptr< DrawModelWrapper >( new DrawModelWrapper( m_xCC ) );
    1211         321 :         m_xShapeFactory = m_pDrawModelWrapper->getShapeFactory();
    1212         321 :         m_xDrawPage = m_pDrawModelWrapper->getMainDrawPage();
    1213         321 :         StartListening( m_pDrawModelWrapper->getSdrModel(), false /*bPreventDups*/ );
    1214             :     }
    1215         321 : }
    1216             : 
    1217           0 : void SAL_CALL ChartView::initialize( const uno::Sequence< uno::Any >& )
    1218             :                 throw ( uno::Exception, uno::RuntimeException, std::exception)
    1219             : {
    1220           0 :     init();
    1221           0 : }
    1222             : 
    1223         915 : ChartView::~ChartView()
    1224             : {
    1225         305 :     maTimeBased.maTimer.Stop();
    1226             :     // #i120831#. In ChartView::initialize(), m_xShapeFactory is created from SdrModel::getUnoModel() and indirectly
    1227             :     //   from SfxBaseModel, it needs call dispose() to make sure SfxBaseModel object is freed correctly.
    1228         305 :     uno::Reference< lang::XComponent > xComp( m_xShapeFactory, uno::UNO_QUERY);
    1229         305 :     if ( xComp.is() )
    1230         305 :         xComp->dispose();
    1231             : 
    1232         305 :     if( m_pDrawModelWrapper.get() )
    1233             :     {
    1234         305 :         SolarMutexGuard aSolarGuard;
    1235         305 :         EndListening( m_pDrawModelWrapper->getSdrModel(), false /*bAllDups*/ );
    1236         305 :         m_pDrawModelWrapper.reset();
    1237             :     }
    1238         305 :     m_xDrawPage = NULL;
    1239         305 :     impl_deleteCoordinateSystems();
    1240         610 : }
    1241             : 
    1242        1481 : void ChartView::impl_deleteCoordinateSystems()
    1243             : {
    1244             :     //delete all coordinate systems
    1245        1481 :     ::std::vector< VCoordinateSystem* > aVectorToDeleteObjects;
    1246        1481 :     ::std::swap( aVectorToDeleteObjects, m_aVCooSysList );//#i109770#
    1247        1481 :     ::std::vector< VCoordinateSystem* >::const_iterator       aIter = aVectorToDeleteObjects.begin();
    1248        1481 :     const ::std::vector< VCoordinateSystem* >::const_iterator aEnd  = aVectorToDeleteObjects.end();
    1249        2518 :     for( ; aIter != aEnd; ++aIter )
    1250             :     {
    1251        1037 :         delete *aIter;
    1252             :     }
    1253        1481 :     aVectorToDeleteObjects.clear();
    1254        1481 : }
    1255             : 
    1256             : // datatransfer::XTransferable
    1257             : namespace
    1258             : {
    1259          38 : const OUString lcl_aGDIMetaFileMIMEType(
    1260          19 :     "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
    1261          38 : const OUString lcl_aGDIMetaFileMIMETypeHighContrast(
    1262          19 :     "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
    1263             : } // anonymous namespace
    1264             : 
    1265           6 : void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStream
    1266             :                            , bool bUseHighContrast )
    1267             : {
    1268           6 :     if( !m_xDrawPage.is() )
    1269           6 :         return;
    1270             : 
    1271             :     // creating the graphic exporter
    1272           6 :     uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( m_xCC );
    1273             : 
    1274          12 :     uno::Sequence< beans::PropertyValue > aProps(3);
    1275           6 :     aProps[0].Name = "FilterName";
    1276           6 :     aProps[0].Value <<= OUString("SVM");
    1277             : 
    1278           6 :     aProps[1].Name = "OutputStream";
    1279           6 :     aProps[1].Value <<= xOutStream;
    1280             : 
    1281          12 :     uno::Sequence< beans::PropertyValue > aFilterData(4);
    1282           6 :     aFilterData[0].Name = "ExportOnlyBackground";
    1283           6 :     aFilterData[0].Value <<= sal_False;
    1284           6 :     aFilterData[1].Name = "HighContrast";
    1285           6 :     aFilterData[1].Value <<= bUseHighContrast;
    1286             : 
    1287           6 :     aFilterData[2].Name = "Version";
    1288           6 :     const sal_Int32 nVersion = SOFFICE_FILEFORMAT_50;
    1289           6 :     aFilterData[2].Value <<= nVersion;
    1290             : 
    1291           6 :     aFilterData[3].Name = "CurrentPage";
    1292           6 :     aFilterData[3].Value <<= uno::Reference< uno::XInterface >( m_xDrawPage, uno::UNO_QUERY );
    1293             : 
    1294             :     //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
    1295             :     {
    1296           6 :         aFilterData.realloc( aFilterData.getLength()+4 );
    1297           6 :         aFilterData[4].Name = "ScaleXNumerator";
    1298           6 :         aFilterData[4].Value = uno::makeAny( m_nScaleXNumerator );
    1299           6 :         aFilterData[5].Name = "ScaleXDenominator";
    1300           6 :         aFilterData[5].Value = uno::makeAny( m_nScaleXDenominator );
    1301           6 :         aFilterData[6].Name = "ScaleYNumerator";
    1302           6 :         aFilterData[6].Value = uno::makeAny( m_nScaleYNumerator );
    1303           6 :         aFilterData[7].Name = "ScaleYDenominator";
    1304           6 :         aFilterData[7].Value = uno::makeAny( m_nScaleYDenominator );
    1305             :     }
    1306             : 
    1307           6 :     aProps[2].Name = "FilterData";
    1308           6 :     aProps[2].Value <<= aFilterData;
    1309             : 
    1310           6 :     xExporter->setSourceDocument( uno::Reference< lang::XComponent >( m_xDrawPage, uno::UNO_QUERY) );
    1311           6 :     if( xExporter->filter( aProps ) )
    1312             :     {
    1313           6 :         xOutStream->flush();
    1314           6 :         xOutStream->closeOutput();
    1315           6 :         uno::Reference< io::XSeekable > xSeekable( xOutStream, uno::UNO_QUERY );
    1316           6 :         if( xSeekable.is() )
    1317           6 :             xSeekable->seek(0);
    1318           6 :     }
    1319             : }
    1320             : 
    1321           6 : uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aFlavor )
    1322             :                 throw (datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception)
    1323             : {
    1324           6 :     bool bHighContrastMetaFile( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast));
    1325           6 :     uno::Any aRet;
    1326           6 :     if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) )
    1327           0 :         return aRet;
    1328             : 
    1329           6 :     update();
    1330             : 
    1331          12 :     SvMemoryStream aStream( 1024, 1024 );
    1332           6 :     utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream );
    1333             : 
    1334          12 :     uno::Reference< io::XOutputStream > xOutStream( pStreamWrapper );
    1335          12 :     uno::Reference< io::XInputStream > xInStream( pStreamWrapper );
    1336          12 :     uno::Reference< io::XSeekable > xSeekable( pStreamWrapper );
    1337             : 
    1338           6 :     if( xOutStream.is() )
    1339             :     {
    1340           6 :         this->getMetaFile( xOutStream, bHighContrastMetaFile );
    1341             : 
    1342           6 :         if( xInStream.is() && xSeekable.is() )
    1343             :         {
    1344           6 :             xSeekable->seek(0);
    1345           6 :             sal_Int32 nBytesToRead = xInStream->available();
    1346           6 :             uno::Sequence< sal_Int8 > aSeq( nBytesToRead );
    1347           6 :             xInStream->readBytes( aSeq, nBytesToRead);
    1348           6 :             aRet <<= aSeq;
    1349           6 :             xInStream->closeInput();
    1350             :         }
    1351             :     }
    1352             : 
    1353           6 :     return aRet;
    1354             : }
    1355           0 : uno::Sequence< datatransfer::DataFlavor > SAL_CALL ChartView::getTransferDataFlavors()
    1356             :                 throw (uno::RuntimeException, std::exception)
    1357             : {
    1358           0 :     uno::Sequence< datatransfer::DataFlavor > aRet(2);
    1359             : 
    1360           0 :     aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType,
    1361             :         "GDIMetaFile",
    1362           0 :         cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
    1363           0 :     aRet[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast,
    1364             :         "GDIMetaFile",
    1365           0 :         cppu::UnoType<uno::Sequence< sal_Int8 >>::get() );
    1366             : 
    1367           0 :     return aRet;
    1368             : }
    1369           0 : sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
    1370             :                 throw (uno::RuntimeException, std::exception)
    1371             : {
    1372           0 :     return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) ||
    1373           0 :              aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) );
    1374             : }
    1375             : 
    1376             : // ____ XUnoTunnel ___
    1377       16753 : ::sal_Int64 SAL_CALL ChartView::getSomething( const uno::Sequence< ::sal_Int8 >& aIdentifier )
    1378             :         throw( uno::RuntimeException, std::exception)
    1379             : {
    1380       50259 :     if( aIdentifier.getLength() == 16 && 0 == memcmp( ExplicitValueProvider::getUnoTunnelId().getConstArray(),
    1381       33506 :                                                          aIdentifier.getConstArray(), 16 ) )
    1382             :     {
    1383       16753 :         ExplicitValueProvider* pProvider = this;
    1384       16753 :         return reinterpret_cast<sal_Int64>(pProvider);
    1385             :     }
    1386           0 :     return 0;
    1387             : }
    1388             : 
    1389             : // lang::XServiceInfo
    1390             : 
    1391           0 : OUString SAL_CALL ChartView::getImplementationName()
    1392             :     throw( css::uno::RuntimeException, std::exception )
    1393             : {
    1394           0 :     return getImplementationName_Static();
    1395             : }
    1396             : 
    1397           0 : OUString ChartView::getImplementationName_Static()
    1398             : {
    1399           0 :     return OUString(CHART_VIEW_SERVICE_IMPLEMENTATION_NAME);
    1400             : }
    1401             : 
    1402           0 : sal_Bool SAL_CALL ChartView::supportsService( const OUString& rServiceName )
    1403             :     throw( css::uno::RuntimeException, std::exception )
    1404             : {
    1405           0 :     return cppu::supportsService(this, rServiceName);
    1406             : }
    1407             : 
    1408           0 : css::uno::Sequence< OUString > SAL_CALL ChartView::getSupportedServiceNames()
    1409             :     throw( css::uno::RuntimeException, std::exception )
    1410             : {
    1411           0 :     return getSupportedServiceNames_Static();
    1412             : }
    1413             : 
    1414           0 : uno::Sequence< OUString > ChartView::getSupportedServiceNames_Static()
    1415             : {
    1416           0 :     uno::Sequence< OUString > aSNS( 1 );
    1417           0 :     aSNS.getArray()[ 0 ] = CHART_VIEW_SERVICE_NAME;
    1418           0 :     return aSNS;
    1419             : }
    1420             : 
    1421        4170 : ::basegfx::B3DHomMatrix createTransformationSceneToScreen(
    1422             :     const ::basegfx::B2IRectangle& rDiagramRectangleWithoutAxes )
    1423             : {
    1424        4170 :     ::basegfx::B3DHomMatrix aM;
    1425        4170 :     aM.scale(double(rDiagramRectangleWithoutAxes.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME
    1426        8340 :             , -double(rDiagramRectangleWithoutAxes.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 );
    1427        4170 :     aM.translate(double(rDiagramRectangleWithoutAxes.getMinX())
    1428        8340 :         , double(rDiagramRectangleWithoutAxes.getMinY()+rDiagramRectangleWithoutAxes.getHeight()-1), 0);
    1429        4170 :     return aM;
    1430             : }
    1431             : 
    1432             : namespace
    1433             : {
    1434             : 
    1435        1053 : bool lcl_IsPieOrDonut( const uno::Reference< XDiagram >& xDiagram )
    1436             : {
    1437             :     //special treatment for pie charts
    1438             :     //the size is checked after complete creation to get the datalabels into the given space
    1439             : 
    1440             :     //todo: this is just a workaround at the moment for pie and donut labels
    1441        1053 :     return DiagramHelper::isPieOrDonutChart( xDiagram );
    1442             : }
    1443             : 
    1444        1176 : void lcl_setDefaultWritingMode( ::boost::shared_ptr< DrawModelWrapper > pDrawModelWrapper, ChartModel& rModel)
    1445             : {
    1446             :     //get writing mode from parent document:
    1447        1176 :     if( SvtLanguageOptions().IsCTLFontEnabled() )
    1448             :     {
    1449             :         try
    1450             :         {
    1451        1176 :             sal_Int16 nWritingMode=-1;
    1452        1176 :             uno::Reference< beans::XPropertySet > xParentProps( rModel.getParent(), uno::UNO_QUERY );
    1453        2352 :             uno::Reference< style::XStyleFamiliesSupplier > xStyleFamiliesSupplier( xParentProps, uno::UNO_QUERY );
    1454        1176 :             if( xStyleFamiliesSupplier.is() )
    1455             :             {
    1456         359 :                 uno::Reference< container::XNameAccess > xStylesFamilies( xStyleFamiliesSupplier->getStyleFamilies() );
    1457         359 :                 if( xStylesFamilies.is() )
    1458             :                 {
    1459         359 :                     if( !xStylesFamilies->hasByName( "PageStyles" ) )
    1460             :                     {
    1461             :                         //draw/impress is parent document
    1462          13 :                         uno::Reference< lang::XMultiServiceFactory > xFatcory( xParentProps, uno::UNO_QUERY );
    1463          13 :                         if( xFatcory.is() )
    1464             :                         {
    1465          13 :                             uno::Reference< beans::XPropertySet > xDrawDefaults( xFatcory->createInstance( "com.sun.star.drawing.Defaults" ), uno::UNO_QUERY );
    1466          13 :                             if( xDrawDefaults.is() )
    1467          13 :                                 xDrawDefaults->getPropertyValue( "WritingMode" ) >>= nWritingMode;
    1468          13 :                         }
    1469             :                     }
    1470             :                     else
    1471             :                     {
    1472         346 :                         uno::Reference< container::XNameAccess > xPageStyles( xStylesFamilies->getByName( "PageStyles" ), uno::UNO_QUERY );
    1473         346 :                         if( xPageStyles.is() )
    1474             :                         {
    1475         346 :                             OUString aPageStyle;
    1476             : 
    1477         692 :                             uno::Reference< text::XTextDocument > xTextDocument( xParentProps, uno::UNO_QUERY );
    1478         346 :                             if( xTextDocument.is() )
    1479             :                             {
    1480             :                                 //writer is parent document
    1481             :                                 //retrieve the current page style from the text cursor property PageStyleName
    1482             : 
    1483         131 :                                 uno::Reference< text::XTextEmbeddedObjectsSupplier > xTextEmbeddedObjectsSupplier( xTextDocument, uno::UNO_QUERY );
    1484         131 :                                 if( xTextEmbeddedObjectsSupplier.is() )
    1485             :                                 {
    1486         131 :                                     uno::Reference< container::XNameAccess > xEmbeddedObjects( xTextEmbeddedObjectsSupplier->getEmbeddedObjects() );
    1487         131 :                                     if( xEmbeddedObjects.is() )
    1488             :                                     {
    1489         131 :                                         uno::Sequence< OUString > aNames( xEmbeddedObjects->getElementNames() );
    1490             : 
    1491         131 :                                         sal_Int32 nCount = aNames.getLength();
    1492         131 :                                         for( sal_Int32 nN=0; nN<nCount; nN++ )
    1493             :                                         {
    1494          49 :                                             uno::Reference< beans::XPropertySet > xEmbeddedProps( xEmbeddedObjects->getByName( aNames[nN] ), uno::UNO_QUERY );
    1495          49 :                                             if( xEmbeddedProps.is() )
    1496             :                                             {
    1497          49 :                                                 static OUString aChartCLSID = OUString( SvGlobalName( SO3_SCH_CLASSID ).GetHexName());
    1498          49 :                                                 OUString aCLSID;
    1499          49 :                                                 xEmbeddedProps->getPropertyValue( "CLSID" ) >>= aCLSID;
    1500          49 :                                                 if( aCLSID.equals(aChartCLSID) )
    1501             :                                                 {
    1502          49 :                                                     uno::Reference< text::XTextContent > xEmbeddedObject( xEmbeddedProps, uno::UNO_QUERY );
    1503          49 :                                                     if( xEmbeddedObject.is() )
    1504             :                                                     {
    1505          49 :                                                         uno::Reference< text::XTextRange > xAnchor( xEmbeddedObject->getAnchor() );
    1506          49 :                                                         if( xAnchor.is() )
    1507             :                                                         {
    1508          49 :                                                             uno::Reference< beans::XPropertySet > xAnchorProps( xAnchor, uno::UNO_QUERY );
    1509          49 :                                                             if( xAnchorProps.is() )
    1510             :                                                             {
    1511          49 :                                                                 xAnchorProps->getPropertyValue( "WritingMode" ) >>= nWritingMode;
    1512             :                                                             }
    1513          98 :                                                             uno::Reference< text::XText > xText( xAnchor->getText() );
    1514          49 :                                                             if( xText.is() )
    1515             :                                                             {
    1516          49 :                                                                 uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
    1517          49 :                                                                 if( xTextCursorProps.is() )
    1518          49 :                                                                     xTextCursorProps->getPropertyValue( "PageStyleName" ) >>= aPageStyle;
    1519          49 :                                                             }
    1520          49 :                                                         }
    1521             :                                                     }
    1522          49 :                                                     break;
    1523           0 :                                                 }
    1524             :                                             }
    1525         131 :                                         }
    1526         131 :                                     }
    1527             :                                 }
    1528         131 :                                 if( aPageStyle.isEmpty() )
    1529             :                                 {
    1530          94 :                                     uno::Reference< text::XText > xText( xTextDocument->getText() );
    1531          94 :                                     if( xText.is() )
    1532             :                                     {
    1533          94 :                                         uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
    1534          94 :                                         if( xTextCursorProps.is() )
    1535          94 :                                             xTextCursorProps->getPropertyValue( "PageStyleName" ) >>= aPageStyle;
    1536          94 :                                     }
    1537         131 :                                 }
    1538             :                             }
    1539             :                             else
    1540             :                             {
    1541             :                                 //Calc is parent document
    1542         215 :                                 xParentProps->getPropertyValue( "PageStyle" ) >>= aPageStyle;
    1543         215 :                                 if(aPageStyle.isEmpty())
    1544         215 :                                     aPageStyle = "Default";
    1545             :                             }
    1546         346 :                             if( nWritingMode == -1 || nWritingMode == text::WritingMode2::PAGE )
    1547             :                             {
    1548         334 :                                 uno::Reference< beans::XPropertySet > xPageStyle( xPageStyles->getByName( aPageStyle ), uno::UNO_QUERY );
    1549         253 :                                 if( xPageStyle.is() )
    1550         253 :                                     xPageStyle->getPropertyValue( "WritingMode" ) >>= nWritingMode;
    1551         346 :                             }
    1552         346 :                         }
    1553             :                     }
    1554         359 :                 }
    1555             :             }
    1556        1095 :             if( nWritingMode != -1 && nWritingMode != text::WritingMode2::PAGE )
    1557             :             {
    1558         278 :                 if( pDrawModelWrapper.get() )
    1559         278 :                     pDrawModelWrapper->GetItemPool().SetPoolDefaultItem(SvxFrameDirectionItem(static_cast<SvxFrameDirection>(nWritingMode), EE_PARA_WRITINGDIR) );
    1560        1176 :             }
    1561             :         }
    1562          81 :         catch( const uno::Exception& ex )
    1563             :         {
    1564             :             ASSERT_EXCEPTION( ex );
    1565             :         }
    1566             :     }
    1567        1176 : }
    1568             : 
    1569        1121 : sal_Int16 lcl_getDefaultWritingModeFromPool( const boost::shared_ptr<DrawModelWrapper>& pDrawModelWrapper )
    1570             : {
    1571        1121 :     sal_Int16 nWritingMode = text::WritingMode2::LR_TB;
    1572        1121 :     if(!pDrawModelWrapper)
    1573           0 :         return nWritingMode;
    1574             : 
    1575        1121 :     const SfxPoolItem* pItem = &(pDrawModelWrapper->GetItemPool().GetDefaultItem( EE_PARA_WRITINGDIR ));
    1576        1121 :     if( pItem )
    1577        1121 :         nWritingMode = static_cast< sal_Int16 >((static_cast< const SvxFrameDirectionItem * >( pItem ))->GetValue());
    1578        1121 :     return nWritingMode;
    1579             : }
    1580             : 
    1581             : } //end anonymous namespace
    1582             : 
    1583        1119 : awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D& rParam, const awt::Size& rPageSize )
    1584             : {
    1585             :     //return the used rectangle
    1586        1119 :     awt::Rectangle aUsedOuterRect(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y, 0, 0);
    1587             : 
    1588        1119 :     uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
    1589        1119 :     if( !xDiagram.is())
    1590          66 :         return aUsedOuterRect;
    1591             : 
    1592        1053 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
    1593        1053 :     if(!nDimensionCount)
    1594             :     {
    1595             :         //@todo handle mixed dimension
    1596           0 :         nDimensionCount = 2;
    1597             :     }
    1598             : 
    1599        1053 :     basegfx::B2IRectangle aAvailableOuterRect = BaseGFXHelper::makeRectangle(rParam.maRemainingSpace);
    1600             : 
    1601        1053 :     const std::vector< VCoordinateSystem* >& rVCooSysList( rParam.mpSeriesPlotterContainer->getCooSysList() );
    1602        1053 :     SeriesPlottersType& rSeriesPlotterList = rParam.mpSeriesPlotterContainer->getSeriesPlotterList();
    1603             : 
    1604             :     //create VAxis, so they can give necessary information for automatic scaling
    1605        2106 :     uno::Reference<chart2::XChartDocument> const xChartDoc(&mrChartModel);
    1606             :     uno::Reference<util::XNumberFormatsSupplier> const xNumberFormatsSupplier(
    1607        2106 :             mrChartModel.getNumberFormatsSupplier());
    1608        1053 :     size_t nC = 0;
    1609        2106 :     for( nC=0; nC < rVCooSysList.size(); nC++)
    1610             :     {
    1611        1053 :         VCoordinateSystem* pVCooSys = rVCooSysList[nC];
    1612        1053 :         if(3==nDimensionCount)
    1613             :         {
    1614          55 :             uno::Reference<beans::XPropertySet> xSceneProperties( xDiagram, uno::UNO_QUERY );
    1615          55 :             CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( xSceneProperties ) );
    1616          55 :             CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( xSceneProperties ) );
    1617          55 :             CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( xSceneProperties ) );
    1618          55 :             pVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos );
    1619             :         }
    1620             : 
    1621        1053 :         pVCooSys->createVAxisList(xChartDoc, rPageSize, rParam.maRemainingSpace);
    1622             :     }
    1623             : 
    1624             :     // - prepare list of all axis and how they are used
    1625        1053 :     Date aNullDate = NumberFormatterWrapper( xNumberFormatsSupplier ).getNullDate();
    1626        1053 :     rParam.mpSeriesPlotterContainer->initAxisUsageList(aNullDate);
    1627        1053 :     rParam.mpSeriesPlotterContainer->doAutoScaling( mrChartModel );
    1628        1053 :     rParam.mpSeriesPlotterContainer->setScalesFromCooSysToPlotter();
    1629        1053 :     rParam.mpSeriesPlotterContainer->setNumberFormatsFromAxes();
    1630             : 
    1631             :     //create shapes
    1632             : 
    1633             :     //aspect ratio
    1634             :     drawing::Direction3D aPreferredAspectRatio =
    1635        1053 :         rParam.mpSeriesPlotterContainer->getPreferredAspectRatio();
    1636             : 
    1637        2106 :     uno::Reference< drawing::XShapes > xSeriesTargetInFrontOfAxis(0);
    1638        2106 :     uno::Reference< drawing::XShapes > xSeriesTargetBehindAxis(0);
    1639        2106 :     VDiagram aVDiagram(xDiagram, aPreferredAspectRatio, nDimensionCount);
    1640        1053 :     bool bIsPieOrDonut = lcl_IsPieOrDonut(xDiagram);
    1641             :     {//create diagram
    1642        1053 :         aVDiagram.init(rParam.mxDiagramWithAxesShapes, m_xShapeFactory);
    1643             :         aVDiagram.createShapes(
    1644             :             awt::Point(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y),
    1645        1053 :             awt::Size(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height));
    1646             : 
    1647        1053 :         xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion();
    1648             :         // It is preferrable to use full size than minimum for pie charts
    1649        1053 :         if (!bIsPieOrDonut && !rParam.mbUseFixedInnerSize)
    1650        1011 :             aVDiagram.reduceToMimimumSize();
    1651             :     }
    1652             : 
    1653             :     uno::Reference< drawing::XShapes > xTextTargetShapes =
    1654        2106 :         AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory)->createGroup2D(rParam.mxDiagramWithAxesShapes);
    1655             : 
    1656             :     // - create axis and grids for all coordinate systems
    1657             : 
    1658             :     //init all coordinate systems
    1659        2106 :     for( nC=0; nC < rVCooSysList.size(); nC++)
    1660             :     {
    1661        1053 :         VCoordinateSystem* pVCooSys = rVCooSysList[nC];
    1662        1053 :         pVCooSys->initPlottingTargets(xSeriesTargetInFrontOfAxis,xTextTargetShapes,m_xShapeFactory,xSeriesTargetBehindAxis);
    1663             : 
    1664             :         pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
    1665        1053 :             createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
    1666             : 
    1667        1053 :         pVCooSys->initVAxisInList();
    1668             :     }
    1669             : 
    1670             :     //calculate resulting size respecting axis label layout and fontscaling
    1671             : 
    1672        2106 :     uno::Reference< drawing::XShape > xBoundingShape(rParam.mxDiagramWithAxesShapes, uno::UNO_QUERY);
    1673        1053 :     ::basegfx::B2IRectangle aConsumedOuterRect;
    1674             : 
    1675             :     //use first coosys only so far; todo: calculate for more than one coosys if we have more in future
    1676             :     //todo: this is just a workaround at the moment for pie and donut labels
    1677        1053 :     if( !bIsPieOrDonut && (!rVCooSysList.empty()) )
    1678             :     {
    1679        1016 :         VCoordinateSystem* pVCooSys = rVCooSysList[0];
    1680        1016 :         pVCooSys->createMaximumAxesLabels();
    1681             : 
    1682        1016 :         aConsumedOuterRect = AbstractShapeFactory::getRectangleOfShape(xBoundingShape);
    1683        1016 :         ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
    1684        1016 :         if (!rParam.mbUseFixedInnerSize)
    1685        1011 :             aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
    1686             : 
    1687             :         pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
    1688        1016 :             createTransformationSceneToScreen( aNewInnerRect ) ));
    1689             : 
    1690             :         //redo autoscaling to get size and text dependent automatic main increment count
    1691        1016 :         rParam.mpSeriesPlotterContainer->doAutoScaling( mrChartModel );
    1692        1016 :         rParam.mpSeriesPlotterContainer->updateScalesAndIncrementsOnAxes();
    1693        1016 :         rParam.mpSeriesPlotterContainer->setScalesFromCooSysToPlotter();
    1694             : 
    1695        1016 :         pVCooSys->createAxesLabels();
    1696             : 
    1697        1016 :         bool bLessSpaceConsumedThanExpected = false;
    1698             :         {
    1699        1016 :             aConsumedOuterRect = AbstractShapeFactory::getRectangleOfShape(xBoundingShape);
    1700        2032 :             if( aConsumedOuterRect.getMinX() > aAvailableOuterRect.getMinX()
    1701         971 :                 || aConsumedOuterRect.getMaxX() < aAvailableOuterRect.getMaxX()
    1702         959 :                 || aConsumedOuterRect.getMinY() > aAvailableOuterRect.getMinY()
    1703        1919 :                 || aConsumedOuterRect.getMinY() < aAvailableOuterRect.getMaxY() )
    1704        1016 :                 bLessSpaceConsumedThanExpected = true;
    1705             :         }
    1706             : 
    1707        1016 :         if (bLessSpaceConsumedThanExpected && !rParam.mbUseFixedInnerSize)
    1708             :         {
    1709        1011 :             aVDiagram.adjustInnerSize( aConsumedOuterRect );
    1710             :             pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
    1711        1011 :                 createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
    1712             :         }
    1713        1016 :         pVCooSys->updatePositions();//todo: logically this belongs to the condition above, but it seems also to be necessary to give the axes group shapes the right bounding rects for hit test -  probably caused by bug i106183 -> check again if fixed
    1714             :     }
    1715             : 
    1716             :     //create axes and grids for the final size
    1717        2106 :     for( nC=0; nC < rVCooSysList.size(); nC++)
    1718             :     {
    1719        1053 :         VCoordinateSystem* pVCooSys = rVCooSysList[nC];
    1720             : 
    1721             :         pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
    1722        1053 :             createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
    1723             : 
    1724        1053 :         pVCooSys->createAxesShapes();
    1725        1053 :         pVCooSys->createGridShapes();
    1726             :     }
    1727             : 
    1728             :     // - create data series for all charttypes
    1729        1053 :     m_bPointsWereSkipped = false;
    1730        1053 :     SeriesPlottersType::iterator       aPlotterIter = rSeriesPlotterList.begin();
    1731        1053 :     const SeriesPlottersType::iterator aPlotterEnd  = rSeriesPlotterList.end();
    1732        2127 :     for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
    1733             :     {
    1734        1074 :         VSeriesPlotter* pSeriesPlotter = &(*aPlotterIter);
    1735        1074 :         OUString aCID; //III
    1736        2148 :         uno::Reference< drawing::XShapes > xSeriesTarget(0);
    1737        1074 :         if( pSeriesPlotter->WantToPlotInFrontOfAxisLine() )
    1738        1072 :             xSeriesTarget = xSeriesTargetInFrontOfAxis;
    1739             :         else
    1740             :         {
    1741           2 :             xSeriesTarget = xSeriesTargetBehindAxis;
    1742             :             OSL_ENSURE( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
    1743             :         }
    1744        1074 :         pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,m_xShapeFactory,aCID );
    1745        1074 :         pSeriesPlotter->setPageReferenceSize( rPageSize );
    1746        1074 :         VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, pSeriesPlotter );
    1747        1074 :         if(2==nDimensionCount)
    1748        1019 :             pSeriesPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() );
    1749             :         //better performance for big data
    1750        1074 :         awt::Size aCoordinateRegionResolution(1000,1000);
    1751             :         {
    1752             :             //calculate resolution for coordinate system
    1753        1074 :             Sequence<sal_Int32> aCoordinateSystemResolution = pVCooSys->getCoordinateSystemResolution( rPageSize, m_aPageResolution );
    1754        1074 :             pSeriesPlotter->setCoordinateSystemResolution( aCoordinateSystemResolution );
    1755             :         }
    1756             : 
    1757        1074 :         pSeriesPlotter->createShapes();
    1758        1074 :         m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped();
    1759        1074 :     }
    1760             : 
    1761             :     //recreate all with corrected sizes if requested
    1762        1053 :     if( bIsPieOrDonut )
    1763             :     {
    1764          37 :         m_bPointsWereSkipped = false;
    1765             : 
    1766          37 :         aConsumedOuterRect = ::basegfx::B2IRectangle( AbstractShapeFactory::getRectangleOfShape(xBoundingShape) );
    1767          37 :         ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
    1768          37 :         if (!rParam.mbUseFixedInnerSize)
    1769          37 :             aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
    1770             : 
    1771          74 :         for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
    1772             :         {
    1773          37 :             VSeriesPlotter* pSeriesPlotter = &(*aPlotterIter);
    1774          37 :             pSeriesPlotter->releaseShapes();
    1775             :         }
    1776             : 
    1777             :         //clear and recreate
    1778          37 :         AbstractShapeFactory::removeSubShapes( xSeriesTargetInFrontOfAxis ); //xSeriesTargetBehindAxis is a sub shape of xSeriesTargetInFrontOfAxis and will be removed here
    1779          37 :         xSeriesTargetBehindAxis.clear();
    1780          37 :         AbstractShapeFactory::removeSubShapes( xTextTargetShapes );
    1781             : 
    1782             :         //set new transformation
    1783          74 :         for( nC=0; nC < rVCooSysList.size(); nC++)
    1784             :         {
    1785          37 :             VCoordinateSystem* pVCooSys = rVCooSysList[nC];
    1786             :             pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
    1787          37 :                 createTransformationSceneToScreen( aNewInnerRect ) ));
    1788             :         }
    1789             : 
    1790             :         // - create data series for all charttypes
    1791          74 :         for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
    1792             :         {
    1793          37 :             VSeriesPlotter* pSeriesPlotter = &(*aPlotterIter);
    1794          37 :             VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, pSeriesPlotter );
    1795          37 :             if(2==nDimensionCount)
    1796          31 :                 pSeriesPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() );
    1797          37 :             pSeriesPlotter->createShapes();
    1798          37 :             m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped();
    1799             :         }
    1800             : 
    1801          74 :         for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
    1802          37 :             aPlotterIter->rearrangeLabelToAvoidOverlapIfRequested(rPageSize);
    1803             :     }
    1804             : 
    1805        1053 :     if (rParam.mbUseFixedInnerSize)
    1806             :     {
    1807           5 :         aUsedOuterRect = awt::Rectangle( aConsumedOuterRect.getMinX(), aConsumedOuterRect.getMinY(), aConsumedOuterRect.getWidth(), aConsumedOuterRect.getHeight() );
    1808             :     }
    1809             :     else
    1810        1048 :         aUsedOuterRect = rParam.maRemainingSpace;
    1811             : 
    1812        1053 :     bool bSnapRectToUsedArea = false;
    1813        1102 :     for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter )
    1814             :     {
    1815        1053 :         bSnapRectToUsedArea = aPlotterIter->shouldSnapRectToUsedArea();
    1816        1053 :         if(bSnapRectToUsedArea)
    1817        1004 :             break;
    1818             :     }
    1819        1053 :     if(bSnapRectToUsedArea)
    1820             :     {
    1821        1004 :         if (rParam.mbUseFixedInnerSize)
    1822           5 :             m_aResultingDiagramRectangleExcludingAxes = getRectangleOfObject( "PlotAreaExcludingAxes" );
    1823             :         else
    1824             :         {
    1825         999 :             ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
    1826         999 :             m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
    1827             :         }
    1828             :     }
    1829             :     else
    1830             :     {
    1831          49 :         if (rParam.mbUseFixedInnerSize)
    1832           0 :             m_aResultingDiagramRectangleExcludingAxes = rParam.maRemainingSpace;
    1833             :         else
    1834             :         {
    1835          49 :             ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
    1836          49 :             m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
    1837             :         }
    1838             :     }
    1839             : 
    1840        1053 :     if (rParam.mxMarkHandles.is())
    1841             :     {
    1842        1053 :         awt::Point aPos(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y);
    1843        1053 :         awt::Size  aSize(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height);
    1844             : 
    1845        1053 :         bool bPosSizeExcludeAxesProperty = true;
    1846        1053 :         uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY_THROW );
    1847        1053 :         if( xDiaProps.is() )
    1848        1053 :             xDiaProps->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxesProperty;
    1849        1053 :         if (rParam.mbUseFixedInnerSize || bPosSizeExcludeAxesProperty)
    1850             :         {
    1851         746 :             aPos = awt::Point( m_aResultingDiagramRectangleExcludingAxes.X, m_aResultingDiagramRectangleExcludingAxes.Y );
    1852         746 :             aSize = awt::Size( m_aResultingDiagramRectangleExcludingAxes.Width, m_aResultingDiagramRectangleExcludingAxes.Height );
    1853             :         }
    1854        1053 :         rParam.mxMarkHandles->setPosition(aPos);
    1855        1053 :         rParam.mxMarkHandles->setSize(aSize);
    1856             :     }
    1857             : 
    1858        2172 :     return aUsedOuterRect;
    1859             : }
    1860             : 
    1861       13543 : bool ChartView::getExplicitValuesForAxis(
    1862             :                      uno::Reference< XAxis > xAxis
    1863             :                      , ExplicitScaleData&  rExplicitScale
    1864             :                      , ExplicitIncrementData& rExplicitIncrement )
    1865             : {
    1866       13543 :     impl_updateView();
    1867             : 
    1868       13543 :     if(!xAxis.is())
    1869           0 :         return false;
    1870             : 
    1871       13543 :     uno::Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(xAxis, mrChartModel.getFirstDiagram() ) );
    1872       13543 :     const VCoordinateSystem* pVCooSys = findInCooSysList(m_aVCooSysList,xCooSys);
    1873       13543 :     if(!pVCooSys)
    1874           2 :         return false;
    1875             : 
    1876       13541 :     sal_Int32 nDimensionIndex=-1;
    1877       13541 :     sal_Int32 nAxisIndex=-1;
    1878       13541 :     if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
    1879             :     {
    1880       13541 :         rExplicitScale = pVCooSys->getExplicitScale(nDimensionIndex,nAxisIndex);
    1881       13541 :         rExplicitIncrement = pVCooSys->getExplicitIncrement(nDimensionIndex,nAxisIndex);
    1882       13541 :         if( rExplicitScale.ShiftedCategoryPosition )
    1883             :         {
    1884             :             //remove 'one' from max
    1885        5751 :             if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::DATE )
    1886             :             {
    1887           0 :                 Date aMaxDate(rExplicitScale.NullDate); aMaxDate += static_cast<long>(::rtl::math::approxFloor(rExplicitScale.Maximum));
    1888             :                 //for explicit scales with shifted categories we need one interval more
    1889           0 :                 switch( rExplicitScale.TimeResolution )
    1890             :                 {
    1891             :                 case ::com::sun::star::chart::TimeUnit::DAY:
    1892           0 :                     --aMaxDate;
    1893           0 :                     break;
    1894             :                 case ::com::sun::star::chart::TimeUnit::MONTH:
    1895           0 :                     aMaxDate = DateHelper::GetDateSomeMonthsAway(aMaxDate,-1);
    1896           0 :                     break;
    1897             :                 case ::com::sun::star::chart::TimeUnit::YEAR:
    1898           0 :                     aMaxDate = DateHelper::GetDateSomeYearsAway(aMaxDate,-1);
    1899           0 :                     break;
    1900             :                 }
    1901           0 :                 rExplicitScale.Maximum = aMaxDate - rExplicitScale.NullDate;
    1902             :             }
    1903        5751 :             else if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::CATEGORY )
    1904        3711 :                 rExplicitScale.Maximum -= 1.0;
    1905        2040 :             else if( rExplicitScale.AxisType == ::com::sun::star::chart2::AxisType::SERIES )
    1906        2040 :                 rExplicitScale.Maximum -= 1.0;
    1907             :         }
    1908       13541 :         return true;
    1909             :     }
    1910           0 :     return false;
    1911             : }
    1912             : 
    1913        2198 : SdrPage* ChartView::getSdrPage()
    1914             : {
    1915        2198 :     SdrPage* pPage=0;
    1916        2198 :     Reference< lang::XUnoTunnel> xUnoTunnel(m_xDrawPage,uno::UNO_QUERY);
    1917        2198 :     if(xUnoTunnel.is())
    1918             :     {
    1919        2198 :         SvxDrawPage* pSvxDrawPage = reinterpret_cast<SvxDrawPage*>(xUnoTunnel->getSomething(
    1920        2198 :             SvxDrawPage::getUnoTunnelId() ));
    1921        2198 :         if(pSvxDrawPage)
    1922             :         {
    1923        2198 :             pPage = pSvxDrawPage->GetSdrPage();
    1924             :         }
    1925             :     }
    1926        2198 :     return pPage;
    1927             : }
    1928             : 
    1929        1022 : uno::Reference< drawing::XShape > ChartView::getShapeForCID( const OUString& rObjectCID )
    1930             : {
    1931        1022 :     SolarMutexGuard aSolarGuard;
    1932        1022 :     SdrObject* pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, this->getSdrPage() );
    1933        1022 :     if( pObj )
    1934         996 :         return uno::Reference< drawing::XShape >( pObj->getUnoShape(), uno::UNO_QUERY);
    1935          26 :     return 0;
    1936             : }
    1937             : 
    1938         319 : awt::Rectangle ChartView::getDiagramRectangleExcludingAxes()
    1939             : {
    1940         319 :     impl_updateView();
    1941         319 :     return m_aResultingDiagramRectangleExcludingAxes;
    1942             : }
    1943             : 
    1944        1022 : awt::Rectangle ChartView::getRectangleOfObject( const OUString& rObjectCID, bool bSnapRect )
    1945             : {
    1946        1022 :     impl_updateView();
    1947             : 
    1948        1022 :     awt::Rectangle aRet;
    1949        1022 :     uno::Reference< drawing::XShape > xShape( getShapeForCID(rObjectCID) );
    1950        1022 :     if(xShape.is())
    1951             :     {
    1952             :         //special handling for axis for old api:
    1953             :         //same special handling for diagram
    1954         996 :         ObjectType eObjectType( ObjectIdentifier::getObjectType( rObjectCID ) );
    1955         996 :         if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_DIAGRAM )
    1956             :         {
    1957           0 :             SolarMutexGuard aSolarGuard;
    1958           0 :             SvxShape* pRoot = SvxShape::getImplementation( xShape );
    1959           0 :             if( pRoot )
    1960             :             {
    1961           0 :                 SdrObject* pRootSdrObject = pRoot->GetSdrObject();
    1962           0 :                 if( pRootSdrObject )
    1963             :                 {
    1964           0 :                     SdrObjList* pRootList = pRootSdrObject->GetSubList();
    1965           0 :                     if( pRootList )
    1966             :                     {
    1967           0 :                         OUString aShapeName = "MarkHandles";
    1968           0 :                         if( eObjectType == OBJECTTYPE_DIAGRAM )
    1969           0 :                             aShapeName = "PlotAreaIncludingAxes";
    1970           0 :                         SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList );
    1971           0 :                         if( pShape )
    1972           0 :                             xShape = uno::Reference< drawing::XShape >( pShape->getUnoShape(), uno::UNO_QUERY);
    1973             :                     }
    1974             :                 }
    1975           0 :             }
    1976             :         }
    1977             : 
    1978         996 :         awt::Size aSize( xShape->getSize() );
    1979         996 :         awt::Point aPoint( xShape->getPosition() );
    1980         996 :         aRet = awt::Rectangle( aPoint.X, aPoint.Y, aSize.Width, aSize.Height );
    1981         996 :         if( bSnapRect )
    1982             :         {
    1983             :             //for rotated objects the shape size and position differs from the visible rectangle
    1984           0 :             SvxShape* pShape = SvxShape::getImplementation( xShape );
    1985           0 :             if( pShape )
    1986             :             {
    1987           0 :                 SdrObject* pSdrObject = pShape->GetSdrObject();
    1988           0 :                 if( pSdrObject )
    1989             :                 {
    1990           0 :                     Rectangle aSnapRect( pSdrObject->GetSnapRect() );
    1991           0 :                     aRet = awt::Rectangle(aSnapRect.Left(),aSnapRect.Top(),aSnapRect.GetWidth(),aSnapRect.GetHeight());
    1992             :                 }
    1993             :             }
    1994             :         }
    1995             :     }
    1996        1022 :     return aRet;
    1997             : }
    1998             : 
    1999        1874 : ::boost::shared_ptr< DrawModelWrapper > ChartView::getDrawModelWrapper()
    2000             : {
    2001        1874 :     return m_pDrawModelWrapper;
    2002             : }
    2003             : 
    2004             : namespace
    2005             : {
    2006           0 : inline sal_Int32 lcl_getDiagramTitleSpace()
    2007             : {
    2008           0 :     return 200; //=0,2 cm spacing
    2009             : }
    2010           0 : bool lcl_getPropertySwapXAndYAxis( const uno::Reference< XDiagram >& xDiagram )
    2011             : {
    2012           0 :     bool bSwapXAndY = false;
    2013             : 
    2014           0 :     uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
    2015           0 :     if( xCooSysContainer.is() )
    2016             :     {
    2017           0 :         uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
    2018           0 :         if( aCooSysList.getLength() )
    2019             :         {
    2020           0 :             uno::Reference<beans::XPropertySet> xProp(aCooSysList[0], uno::UNO_QUERY );
    2021           0 :             if( xProp.is()) try
    2022             :             {
    2023           0 :                 xProp->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXAndY;
    2024             :             }
    2025           0 :             catch( const uno::Exception& e )
    2026             :             {
    2027             :                 ASSERT_EXCEPTION( e );
    2028           0 :             }
    2029           0 :         }
    2030             :     }
    2031           0 :     return bSwapXAndY;
    2032             : }
    2033             : 
    2034             : }
    2035             : 
    2036        2943 : sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
    2037             :                   const Reference< chart2::XAxis >& xAxis
    2038             :                 , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem
    2039             :                 , const Reference<chart2::XChartDocument>& xChartDoc)
    2040             : {
    2041             :     return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis, xCorrespondingCoordinateSystem, xChartDoc
    2042        2943 :         , true /*bSearchForParallelAxisIfNothingIsFound*/ );
    2043             : }
    2044             : 
    2045         220 : sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
    2046             :         const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
    2047             :         const uno::Reference< XDataSeries >& xSeries,
    2048             :         sal_Int32 nPointIndex /*-1 for whole series*/,
    2049             :         const uno::Reference< XDiagram >& xDiagram
    2050             :         )
    2051             : {
    2052         220 :     sal_Int32 nFormat=0;
    2053         220 :     if( !xSeriesOrPointProp.is() )
    2054           0 :         return nFormat;
    2055             : 
    2056         220 :     bool bLinkToSource = true;
    2057             :     try
    2058             :     {
    2059         220 :         xSeriesOrPointProp->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bLinkToSource;
    2060             :     }
    2061           0 :     catch ( const beans::UnknownPropertyException& ) {}
    2062             : 
    2063         220 :     xSeriesOrPointProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nFormat;
    2064         220 :     sal_Int32 nOldFormat = nFormat;
    2065         220 :     if (bLinkToSource)
    2066             :     {
    2067         208 :         uno::Reference< chart2::XChartType > xChartType( DataSeriesHelper::getChartTypeOfSeries( xSeries, xDiagram ) );
    2068             : 
    2069         208 :         bool bFormatFound = false;
    2070         208 :         if( ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( xChartType ) )
    2071             :         {
    2072         208 :             uno::Reference< beans::XPropertySet > xAttachedAxisProps( DiagramHelper::getAttachedAxis( xSeries, xDiagram ), uno::UNO_QUERY );
    2073         208 :             if (xAttachedAxisProps.is() && (xAttachedAxisProps->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nFormat))
    2074         144 :                 bFormatFound = true;
    2075             :         }
    2076         208 :         if( !bFormatFound )
    2077             :         {
    2078          64 :             Reference< chart2::data::XDataSource > xSeriesSource( xSeries, uno::UNO_QUERY );
    2079         128 :             OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) );
    2080             : 
    2081             :             Reference< data::XLabeledDataSequence > xLabeledSequence(
    2082         128 :                 DataSeriesHelper::getDataSequenceByRole( xSeriesSource, aRole, false ));
    2083          64 :             if( xLabeledSequence.is() )
    2084             :             {
    2085          64 :                 Reference< data::XDataSequence > xValues( xLabeledSequence->getValues() );
    2086          64 :                 if( xValues.is() )
    2087          64 :                     nFormat = xValues->getNumberFormatKeyByIndex( nPointIndex );
    2088          64 :             }
    2089             :         }
    2090             : 
    2091         208 :         if (nFormat >= 0 && nOldFormat != nFormat)
    2092           0 :             xSeriesOrPointProp->setPropertyValue(CHART_UNONAME_NUMFMT, uno::makeAny(nFormat));
    2093             :     }
    2094             : 
    2095         220 :     if(nFormat<0)
    2096           0 :         nFormat=0;
    2097         220 :     return nFormat;
    2098             : }
    2099             : 
    2100           0 : sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
    2101             :         const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp,
    2102             :         const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
    2103             : {
    2104           0 :     sal_Int32 nFormat=0;
    2105           0 :     if( !xSeriesOrPointProp.is() )
    2106           0 :         return nFormat;
    2107           0 :     if( !(xSeriesOrPointProp->getPropertyValue("PercentageNumberFormat") >>= nFormat) )
    2108             :     {
    2109           0 :         nFormat = DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier );
    2110             :     }
    2111           0 :     if(nFormat<0)
    2112           0 :         nFormat=0;
    2113           0 :     return nFormat;
    2114             : }
    2115             : 
    2116           0 : awt::Rectangle ExplicitValueProvider::addAxisTitleSizes(
    2117             :             ChartModel& rModel
    2118             :             , const Reference< uno::XInterface >& xChartView
    2119             :             , const awt::Rectangle& rExcludingPositionAndSize )
    2120             : {
    2121           0 :     awt::Rectangle aRet(rExcludingPositionAndSize);
    2122             : 
    2123             :     //add axis title sizes to the diagram size
    2124           0 :     uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, rModel ) );
    2125           0 :     uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, rModel ) );
    2126           0 :     uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, rModel ) );
    2127           0 :     uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, rModel ) );
    2128           0 :     if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() )
    2129             :     {
    2130           0 :         ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView);
    2131           0 :         if( pExplicitValueProvider )
    2132             :         {
    2133             :             //detect whether x axis points into x direction or not
    2134           0 :             if( lcl_getPropertySwapXAndYAxis( rModel.getFirstDiagram() ) )
    2135             :             {
    2136           0 :                 std::swap( xTitle_Height, xTitle_Width );
    2137           0 :                 std::swap( xSecondTitle_Height, xSecondTitle_Width );
    2138             :             }
    2139             : 
    2140           0 :             sal_Int32 nTitleSpaceWidth = 0;
    2141           0 :             sal_Int32 nTitleSpaceHeight = 0;
    2142           0 :             sal_Int32 nSecondTitleSpaceWidth = 0;
    2143           0 :             sal_Int32 nSecondTitleSpaceHeight = 0;
    2144             : 
    2145           0 :             if( xTitle_Height.is() )
    2146             :             {
    2147           0 :                 OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, rModel ) );
    2148           0 :                 nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
    2149           0 :                 if( nTitleSpaceHeight )
    2150           0 :                     nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
    2151             :             }
    2152           0 :             if( xTitle_Width.is() )
    2153             :             {
    2154           0 :                 OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, rModel ) );
    2155           0 :                 nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
    2156           0 :                 if(nTitleSpaceWidth)
    2157           0 :                     nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
    2158             :             }
    2159           0 :             if( xSecondTitle_Height.is() )
    2160             :             {
    2161           0 :                 OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, rModel ) );
    2162           0 :                 nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
    2163           0 :                 if( nSecondTitleSpaceHeight )
    2164           0 :                     nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
    2165             :             }
    2166           0 :             if( xSecondTitle_Width.is() )
    2167             :             {
    2168           0 :                 OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, rModel ) );
    2169           0 :                 nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
    2170           0 :                 if( nSecondTitleSpaceWidth )
    2171           0 :                     nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
    2172             :             }
    2173             : 
    2174           0 :             aRet.X -= nTitleSpaceWidth;
    2175           0 :             aRet.Y -= nSecondTitleSpaceHeight;
    2176           0 :             aRet.Width += nTitleSpaceWidth + nSecondTitleSpaceWidth;
    2177           0 :             aRet.Height += nTitleSpaceHeight + nSecondTitleSpaceHeight;
    2178             :         }
    2179             :     }
    2180           0 :     return aRet;
    2181             : }
    2182             : 
    2183           0 : awt::Rectangle ExplicitValueProvider::substractAxisTitleSizes(
    2184             :             ChartModel& rModel
    2185             :             , const Reference< uno::XInterface >& xChartView
    2186             :             , const awt::Rectangle& rPositionAndSizeIncludingTitles )
    2187             : {
    2188           0 :     awt::Rectangle aRet(rPositionAndSizeIncludingTitles);
    2189             : 
    2190             :     //add axis title sizes to the diagram size
    2191           0 :     uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, rModel ) );
    2192           0 :     uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, rModel ) );
    2193           0 :     uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, rModel ) );
    2194           0 :     uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, rModel ) );
    2195           0 :     if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() )
    2196             :     {
    2197           0 :         ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView);
    2198           0 :         if( pExplicitValueProvider )
    2199             :         {
    2200             :             //detect whether x axis points into x direction or not
    2201           0 :             if( lcl_getPropertySwapXAndYAxis( rModel.getFirstDiagram() ) )
    2202             :             {
    2203           0 :                 std::swap( xTitle_Height, xTitle_Width );
    2204           0 :                 std::swap( xSecondTitle_Height, xSecondTitle_Width );
    2205             :             }
    2206             : 
    2207           0 :             sal_Int32 nTitleSpaceWidth = 0;
    2208           0 :             sal_Int32 nTitleSpaceHeight = 0;
    2209           0 :             sal_Int32 nSecondTitleSpaceWidth = 0;
    2210           0 :             sal_Int32 nSecondTitleSpaceHeight = 0;
    2211             : 
    2212           0 :             if( xTitle_Height.is() )
    2213             :             {
    2214           0 :                 OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, rModel ) );
    2215           0 :                 nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
    2216           0 :                 if( nTitleSpaceHeight )
    2217           0 :                     nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
    2218             :             }
    2219           0 :             if( xTitle_Width.is() )
    2220             :             {
    2221           0 :                 OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, rModel ) );
    2222           0 :                 nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
    2223           0 :                 if(nTitleSpaceWidth)
    2224           0 :                     nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
    2225             :             }
    2226           0 :             if( xSecondTitle_Height.is() )
    2227             :             {
    2228           0 :                 OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, rModel ) );
    2229           0 :                 nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
    2230           0 :                 if( nSecondTitleSpaceHeight )
    2231           0 :                     nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
    2232             :             }
    2233           0 :             if( xSecondTitle_Width.is() )
    2234             :             {
    2235           0 :                 OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, rModel ) );
    2236           0 :                 nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
    2237           0 :                 if( nSecondTitleSpaceWidth )
    2238           0 :                     nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
    2239             :             }
    2240             : 
    2241           0 :             aRet.X += nTitleSpaceWidth;
    2242           0 :             aRet.Y += nSecondTitleSpaceHeight;
    2243           0 :             aRet.Width -= (nTitleSpaceWidth + nSecondTitleSpaceWidth);
    2244           0 :             aRet.Height -= (nTitleSpaceHeight + nSecondTitleSpaceHeight);
    2245             :         }
    2246             :     }
    2247           0 :     return aRet;
    2248             : }
    2249             : 
    2250             : namespace {
    2251             : 
    2252        8962 : inline double lcl_getPageLayoutDistancePercentage()
    2253             : {
    2254        8962 :     return 0.02;
    2255             : }
    2256             : 
    2257        1119 : bool getAvailablePosAndSizeForDiagram(
    2258             :     CreateShapeParam2D& rParam, const awt::Size & rPageSize, const uno::Reference<XDiagram>& xDiagram )
    2259             : {
    2260        1119 :     rParam.mbUseFixedInnerSize = false;
    2261             : 
    2262             :     //@todo: we need a size dependent on the axis labels
    2263        1119 :     sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
    2264        1119 :     sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
    2265        1119 :     rParam.maRemainingSpace.X += nXDistance;
    2266        1119 :     rParam.maRemainingSpace.Width -= 2*nXDistance;
    2267        1119 :     rParam.maRemainingSpace.Y += nYDistance;
    2268        1119 :     rParam.maRemainingSpace.Height -= 2*nYDistance;
    2269             : 
    2270        1119 :     if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
    2271           0 :         return false;
    2272             : 
    2273        1119 :     uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY);
    2274             : 
    2275        1119 :     bool bPosSizeExcludeAxes = false;
    2276        1119 :     if( xProp.is() )
    2277        1053 :         xProp->getPropertyValue( "PosSizeExcludeAxes" ) >>= bPosSizeExcludeAxes;
    2278             : 
    2279             :     //size:
    2280        1119 :     ::com::sun::star::chart2::RelativeSize aRelativeSize;
    2281        1119 :     if( xProp.is() && (xProp->getPropertyValue( "RelativeSize" )>>=aRelativeSize) )
    2282             :     {
    2283         311 :         rParam.maRemainingSpace.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height);
    2284         311 :         rParam.maRemainingSpace.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width);
    2285         311 :         rParam.mbUseFixedInnerSize = bPosSizeExcludeAxes;
    2286             :     }
    2287             : 
    2288             :     //position:
    2289        1119 :     chart2::RelativePosition aRelativePosition;
    2290        1119 :     if( xProp.is() && (xProp->getPropertyValue( "RelativePosition" )>>=aRelativePosition) )
    2291             :     {
    2292             :         //@todo decide whether x is primary or secondary
    2293             : 
    2294             :         //the coordinates re relative to the page
    2295         312 :         double fX = aRelativePosition.Primary*rPageSize.Width;
    2296         312 :         double fY = aRelativePosition.Secondary*rPageSize.Height;
    2297             : 
    2298             :         awt::Point aPos = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
    2299             :             awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY)),
    2300             :             awt::Size(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height),
    2301         312 :             aRelativePosition.Anchor);
    2302             : 
    2303         312 :         rParam.maRemainingSpace.X = aPos.X;
    2304         312 :         rParam.maRemainingSpace.Y = aPos.Y;
    2305             : 
    2306         312 :         rParam.mbUseFixedInnerSize = bPosSizeExcludeAxes;
    2307             :     }
    2308             : 
    2309             :     //ensure that the diagram does not lap out right side or out of bottom
    2310        1119 :     if (rParam.maRemainingSpace.Y + rParam.maRemainingSpace.Height > rPageSize.Height)
    2311           0 :         rParam.maRemainingSpace.Height = rPageSize.Height - rParam.maRemainingSpace.Y;
    2312             : 
    2313        1119 :     if (rParam.maRemainingSpace.X + rParam.maRemainingSpace.Width > rPageSize.Width)
    2314           0 :         rParam.maRemainingSpace.Width = rPageSize.Width - rParam.maRemainingSpace.X;
    2315             : 
    2316        1119 :     return true;
    2317             : }
    2318             : 
    2319             : enum TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z };
    2320             : 
    2321        5595 : void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment
    2322             :                                , awt::Rectangle& rDiagramPlusAxesRect, const awt::Size & rPageSize )
    2323             : {
    2324        5595 :     if(!pVTitle)
    2325       11147 :         return;
    2326             : 
    2327          43 :     awt::Point aNewPosition(0,0);
    2328          43 :     awt::Size aTitleSize = pVTitle->getFinalSize();
    2329          43 :     sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
    2330          43 :     sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
    2331          43 :     switch( eAlignment )
    2332             :     {
    2333             :     case ALIGN_TOP:
    2334           0 :         aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
    2335           0 :                                     , rDiagramPlusAxesRect.Y - aTitleSize.Height/2  - nYDistance );
    2336           0 :         break;
    2337             :     case ALIGN_BOTTOM:
    2338          17 :         aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
    2339          34 :                                     , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2  + nYDistance );
    2340          17 :         break;
    2341             :     case ALIGN_LEFT:
    2342          22 :         aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance
    2343          44 :                                     , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
    2344          22 :         break;
    2345             :     case ALIGN_RIGHT:
    2346           4 :         aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
    2347           8 :                                     , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
    2348           4 :         break;
    2349             :     case ALIGN_Z:
    2350           0 :         aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
    2351           0 :                                     , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height - aTitleSize.Height/2 );
    2352           0 :        break;
    2353             :     default:
    2354           0 :         break;
    2355             :     }
    2356             : 
    2357          43 :     sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2;
    2358          43 :     sal_Int32 nMaxX = rPageSize.Width - aTitleSize.Width/2;
    2359          43 :     sal_Int32 nMinX = aTitleSize.Width/2;
    2360          43 :     sal_Int32 nMinY = aTitleSize.Height/2;
    2361          43 :     if( aNewPosition.Y > nMaxY )
    2362           0 :         aNewPosition.Y = nMaxY;
    2363          43 :     if( aNewPosition.X > nMaxX )
    2364           0 :         aNewPosition.X = nMaxX;
    2365          43 :     if( aNewPosition.Y < nMinY )
    2366           0 :         aNewPosition.Y = nMinY;
    2367          43 :     if( aNewPosition.X < nMinX )
    2368           0 :         aNewPosition.X = nMinX;
    2369             : 
    2370          43 :     pVTitle->changePosition( aNewPosition );
    2371             : }
    2372             : 
    2373        6638 : boost::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType
    2374             :                 , const uno::Reference< drawing::XShapes>& xPageShapes
    2375             :                 , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
    2376             :                 , ChartModel& rModel
    2377             :                 , awt::Rectangle& rRemainingSpace
    2378             :                 , const awt::Size & rPageSize
    2379             :                 , TitleAlignment eAlignment
    2380             :                 , bool& rbAutoPosition )
    2381             : {
    2382        6638 :     boost::shared_ptr<VTitle> apVTitle;
    2383             : 
    2384             :     // #i109336# Improve auto positioning in chart
    2385        6638 :     double fPercentage = lcl_getPageLayoutDistancePercentage();
    2386        6638 :     sal_Int32 nXDistance = static_cast< sal_Int32 >( rPageSize.Width * fPercentage );
    2387        6638 :     sal_Int32 nYDistance = static_cast< sal_Int32 >( rPageSize.Height * fPercentage );
    2388        6638 :     if ( eType == TitleHelper::MAIN_TITLE )
    2389             :     {
    2390        1176 :         sal_Int32 nYOffset = 135;  // 1/100 mm
    2391        1176 :         nYDistance += nYOffset;
    2392             :     }
    2393        5462 :     else if ( eType == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION )
    2394             :     {
    2395        1082 :         sal_Int32 nYOffset = 420;  // 1/100 mm
    2396        1082 :         nYDistance = nYOffset;
    2397             :     }
    2398        4380 :     else if ( eType == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
    2399             :     {
    2400        1082 :         sal_Int32 nXOffset = 450;  // 1/100 mm
    2401        1082 :         nXDistance = nXOffset;
    2402             :     }
    2403             : 
    2404       13276 :     uno::Reference< XTitle > xTitle( TitleHelper::getTitle( eType, rModel ) );
    2405       13276 :     OUString aCompleteString = TitleHelper::getCompleteString(xTitle);
    2406        6638 :     if (aCompleteString.isEmpty())
    2407        5733 :         return apVTitle;
    2408             : 
    2409             :     //create title
    2410         905 :     apVTitle.reset(new VTitle(xTitle));
    2411        1810 :     OUString aCID = ObjectIdentifier::createClassifiedIdentifierForObject(xTitle, rModel);
    2412         905 :     apVTitle->init(xPageShapes, xShapeFactory, aCID);
    2413         905 :     apVTitle->createShapes(awt::Point(0,0), rPageSize);
    2414         905 :     awt::Size aTitleUnrotatedSize = apVTitle->getUnrotatedSize();
    2415         905 :     awt::Size aTitleSize = apVTitle->getFinalSize();
    2416             : 
    2417             :     //position
    2418         905 :     rbAutoPosition = true;
    2419         905 :     awt::Point aNewPosition(0,0);
    2420         905 :     chart2::RelativePosition aRelativePosition;
    2421        1810 :     uno::Reference<beans::XPropertySet> xProp(xTitle, uno::UNO_QUERY);
    2422         905 :     if (xProp.is() && (xProp->getPropertyValue("RelativePosition") >>= aRelativePosition))
    2423             :     {
    2424         593 :         rbAutoPosition = false;
    2425             : 
    2426             :         //@todo decide whether x is primary or secondary
    2427         593 :         double fX = aRelativePosition.Primary*rPageSize.Width;
    2428         593 :         double fY = aRelativePosition.Secondary*rPageSize.Height;
    2429             : 
    2430         593 :         double fAnglePi = apVTitle->getRotationAnglePi();
    2431             :         aNewPosition = RelativePositionHelper::getCenterOfAnchoredObject(
    2432             :                 awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY))
    2433         593 :                 , aTitleUnrotatedSize, aRelativePosition.Anchor, fAnglePi );
    2434             :     }
    2435             :     else //auto position
    2436             :     {
    2437         312 :         switch( eAlignment )
    2438             :         {
    2439             :         case ALIGN_TOP:
    2440         269 :             aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
    2441         538 :                                      , rRemainingSpace.Y + aTitleSize.Height/2 + nYDistance );
    2442         269 :             break;
    2443             :         case ALIGN_BOTTOM:
    2444          17 :             aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
    2445          34 :                                      , rRemainingSpace.Y + rRemainingSpace.Height - aTitleSize.Height/2 - nYDistance );
    2446          17 :             break;
    2447             :         case ALIGN_LEFT:
    2448          22 :             aNewPosition = awt::Point( rRemainingSpace.X + aTitleSize.Width/2 + nXDistance
    2449          44 :                                      , rRemainingSpace.Y + rRemainingSpace.Height/2 );
    2450          22 :             break;
    2451             :         case ALIGN_RIGHT:
    2452           4 :             aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width - aTitleSize.Width/2 - nXDistance
    2453           8 :                                      , rRemainingSpace.Y + rRemainingSpace.Height/2 );
    2454           4 :             break;
    2455             :         default:
    2456           0 :             break;
    2457             : 
    2458             :         }
    2459             :     }
    2460         905 :     apVTitle->changePosition( aNewPosition );
    2461             : 
    2462             :     //remaining space
    2463         905 :     switch( eAlignment )
    2464             :     {
    2465             :         case ALIGN_TOP:
    2466             :             // Push the remaining space down from top.
    2467         862 :             rRemainingSpace.Y += ( aTitleSize.Height + nYDistance );
    2468         862 :             rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
    2469         862 :             break;
    2470             :         case ALIGN_BOTTOM:
    2471             :             // Push the remaining space up from bottom.
    2472          17 :             rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
    2473          17 :             break;
    2474             :         case ALIGN_LEFT:
    2475             :             // Push the remaining space to the right from left edge.
    2476          22 :             rRemainingSpace.X += ( aTitleSize.Width + nXDistance );
    2477          22 :             rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
    2478          22 :             break;
    2479             :         case ALIGN_RIGHT:
    2480             :             // Push the remaining space to the left from right edge.
    2481           4 :             rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
    2482           4 :             break;
    2483             :         default:
    2484           0 :             break;
    2485             :     }
    2486             : 
    2487         905 :     return apVTitle;
    2488             : }
    2489             : 
    2490        1121 : bool lcl_createLegend( const uno::Reference< XLegend > & xLegend
    2491             :                    , const uno::Reference< drawing::XShapes>& xPageShapes
    2492             :                    , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
    2493             :                    , const uno::Reference< uno::XComponentContext > & xContext
    2494             :                    , awt::Rectangle & rRemainingSpace
    2495             :                    , const awt::Size & rPageSize
    2496             :                    , ChartModel& rModel
    2497             :                    , const std::vector< LegendEntryProvider* >& rLegendEntryProviderList
    2498             :                    , sal_Int16 nDefaultWritingMode )
    2499             : {
    2500        1121 :     if (!VLegend::isVisible(xLegend))
    2501         191 :         return false;
    2502             : 
    2503             :     VLegend aVLegend( xLegend, xContext, rLegendEntryProviderList,
    2504         930 :             xPageShapes, xShapeFactory, rModel);
    2505         930 :     aVLegend.setDefaultWritingMode( nDefaultWritingMode );
    2506             :     aVLegend.createShapes( awt::Size( rRemainingSpace.Width, rRemainingSpace.Height ),
    2507         930 :                            rPageSize );
    2508         930 :     aVLegend.changePosition( rRemainingSpace, rPageSize );
    2509         930 :     return true;
    2510             : }
    2511             : 
    2512        1176 : void formatPage(
    2513             :       ChartModel& rChartModel
    2514             :     , const awt::Size& rPageSize
    2515             :     , const uno::Reference< drawing::XShapes >& xTarget
    2516             :     , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
    2517             :     )
    2518             : {
    2519             :     try
    2520             :     {
    2521        1176 :         uno::Reference< beans::XPropertySet > xModelPage( rChartModel.getPageBackground());
    2522        1176 :         if( ! xModelPage.is())
    2523           0 :             return;
    2524             : 
    2525        1176 :         if( !xShapeFactory.is() )
    2526           0 :             return;
    2527             : 
    2528             :         //format page
    2529        2352 :         tPropertyNameValueMap aNameValueMap;
    2530        1176 :         PropertyMapper::getValueMap( aNameValueMap, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), xModelPage );
    2531             : 
    2532        2352 :         OUString aCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );
    2533        1176 :         aNameValueMap.insert( tPropertyNameValueMap::value_type( "Name", uno::makeAny( aCID ) ) ); //CID OUString
    2534             : 
    2535        2352 :         tNameSequence aNames;
    2536        2352 :         tAnySequence aValues;
    2537        1176 :         PropertyMapper::getMultiPropertyListsFromValueMap( aNames, aValues, aNameValueMap );
    2538             : 
    2539        1176 :         AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(xShapeFactory);
    2540             :         pShapeFactory->createRectangle(
    2541        2352 :             xTarget, rPageSize, awt::Point(0, 0), aNames, aValues);
    2542             :     }
    2543           0 :     catch( const uno::Exception & ex )
    2544             :     {
    2545             :         ASSERT_EXCEPTION( ex );
    2546             :     }
    2547             : }
    2548             : 
    2549       33253 : void lcl_removeEmptyGroupShapes( const Reference< drawing::XShapes>& xParent )
    2550             : {
    2551       33253 :     if(!xParent.is())
    2552          55 :         return;
    2553       33253 :     Reference< drawing::XShapeGroup > xParentGroup( xParent, uno::UNO_QUERY );
    2554       33253 :     if( !xParentGroup.is() )
    2555             :     {
    2556          55 :         Reference< drawing::XDrawPage > xPage( xParent, uno::UNO_QUERY );
    2557          55 :         if( !xPage.is() )
    2558          55 :             return;
    2559             :     }
    2560             : 
    2561             :     //iterate from back!
    2562      141721 :     for( sal_Int32 nN = xParent->getCount(); nN--; )
    2563             :     {
    2564       75325 :         uno::Any aAny = xParent->getByIndex( nN );
    2565      150650 :         Reference< drawing::XShapes> xShapes(0);
    2566       75325 :         if( aAny >>= xShapes )
    2567       32134 :             lcl_removeEmptyGroupShapes( xShapes );
    2568       75325 :         if( xShapes.is() && xShapes->getCount()==0 )
    2569             :         {
    2570             :             //remove empty group shape
    2571        6187 :             Reference< drawing::XShapeGroup > xGroup( xShapes, uno::UNO_QUERY );
    2572       12374 :             Reference< drawing::XShape > xShape( xShapes, uno::UNO_QUERY );
    2573        6187 :             if( xGroup.is() )
    2574       12374 :                 xParent->remove( xShape );
    2575             :         }
    2576      108523 :     }
    2577             : }
    2578             : 
    2579             : }
    2580             : 
    2581        1176 : void ChartView::impl_refreshAddIn()
    2582             : {
    2583        1176 :     if( !m_bRefreshAddIn )
    2584        1245 :         return;
    2585             : 
    2586        1107 :     uno::Reference< beans::XPropertySet > xProp( static_cast< ::cppu::OWeakObject* >( &mrChartModel ), uno::UNO_QUERY );
    2587        1107 :     if( xProp.is()) try
    2588             :     {
    2589        1107 :         uno::Reference< util::XRefreshable > xAddIn;
    2590        1107 :         xProp->getPropertyValue( "AddIn" ) >>= xAddIn;
    2591        1107 :         if( xAddIn.is() )
    2592             :         {
    2593           0 :             bool bRefreshAddInAllowed = true;
    2594           0 :             xProp->getPropertyValue( "RefreshAddInAllowed" ) >>= bRefreshAddInAllowed;
    2595           0 :             if( bRefreshAddInAllowed )
    2596           0 :                 xAddIn->refresh();
    2597        1107 :         }
    2598             :     }
    2599           0 :     catch( const uno::Exception& e )
    2600             :     {
    2601             :         ASSERT_EXCEPTION( e );
    2602        1107 :     }
    2603             : }
    2604             : 
    2605             : /**
    2606             :  * Is it a real 3D chart with a true 3D scene or a 3D chart in a 2D scene.
    2607             :  */
    2608        2312 : bool ChartView::isReal3DChart()
    2609             : {
    2610        2312 :     uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
    2611             : 
    2612        2312 :     return ChartHelper::isGL3DDiagram(xDiagram);
    2613             : }
    2614             : 
    2615          19 : static const char* envChartDummyFactory = getenv("CHART_DUMMY_FACTORY");
    2616             : 
    2617        1176 : void ChartView::createShapes()
    2618             : {
    2619        1176 :     osl::ResettableMutexGuard aTimedGuard(maTimeMutex);
    2620        1176 :     if(mrChartModel.isTimeBased())
    2621             :     {
    2622           0 :         maTimeBased.bTimeBased = true;
    2623             :     }
    2624             : 
    2625             :     //make sure add-in is refreshed after creating the shapes
    2626        2352 :     const ::comphelper::ScopeGuard aGuard( boost::bind( &ChartView::impl_refreshAddIn, this ) );
    2627             : 
    2628        1176 :     m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle(0,0,0,0);
    2629        1176 :     impl_deleteCoordinateSystems();
    2630        1176 :     if( m_pDrawModelWrapper )
    2631             :     {
    2632        1176 :         SolarMutexGuard aSolarGuard;
    2633             :         // #i12587# support for shapes in chart
    2634        1176 :         m_pDrawModelWrapper->getSdrModel().EnableUndo( false );
    2635        1176 :         m_pDrawModelWrapper->clearMainDrawPage();
    2636             :     }
    2637             : 
    2638        1176 :     lcl_setDefaultWritingMode( m_pDrawModelWrapper, mrChartModel );
    2639             : 
    2640        1176 :     awt::Size aPageSize = mrChartModel.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
    2641             : 
    2642        1176 :     AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
    2643        1176 :     if(!mxRootShape.is())
    2644         272 :         mxRootShape = pShapeFactory->getOrCreateChartRootShape( m_xDrawPage );
    2645             : 
    2646        1176 :     SdrPage* pPage = ChartView::getSdrPage();
    2647        1176 :     if(pPage) //it is necessary to use the implementation here as the uno page does not provide a propertyset
    2648        1176 :         pPage->SetSize(Size(aPageSize.Width,aPageSize.Height));
    2649             :     else
    2650             :     {
    2651             :         OSL_FAIL("could not set page size correctly");
    2652             :     }
    2653        1176 :     pShapeFactory->setPageSize(mxRootShape, aPageSize);
    2654        1176 :     pShapeFactory->clearPage(mxRootShape);
    2655             : 
    2656             : #if HAVE_FEATURE_DESKTOP
    2657        1176 :     if(isReal3DChart())
    2658             :     {
    2659           0 :         createShapes3D();
    2660        1176 :         return;
    2661             :     }
    2662             :     else
    2663             :     {
    2664        1176 :         m_pGL3DPlotter.reset();
    2665             : 
    2666             :         // hide OpenGL window for now in normal charts
    2667        1176 :         OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
    2668        1176 :         if(pWindow && !envChartDummyFactory)
    2669         833 :             pWindow->Show(false);
    2670             :     }
    2671             : #endif
    2672             : 
    2673        1176 :     createShapes2D(aPageSize);
    2674             : 
    2675             :     // #i12587# support for shapes in chart
    2676        1176 :     if ( m_pDrawModelWrapper )
    2677             :     {
    2678        1176 :         SolarMutexGuard aSolarGuard;
    2679        1176 :         m_pDrawModelWrapper->getSdrModel().EnableUndo( true );
    2680             :     }
    2681             : 
    2682        1176 :     if(maTimeBased.bTimeBased)
    2683             :     {
    2684           0 :         maTimeBased.nFrame++;
    2685        1176 :     }
    2686             : }
    2687             : 
    2688        1119 : void ChartView::render()
    2689             : {
    2690        1119 :     if(!isReal3DChart())
    2691             :     {
    2692        1119 :         AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
    2693        1119 :         OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
    2694        1119 :         if(pWindow)
    2695         776 :             pWindow->setRenderer(mp2DRenderer.get());
    2696        1119 :         bool bRender = pShapeFactory->preRender(mxRootShape, pWindow);
    2697        1119 :         if(bRender)
    2698             :         {
    2699        1119 :             pShapeFactory->render(mxRootShape, pWindow != mp2DRenderer->getOpenGLWindow());
    2700        1119 :             pShapeFactory->postRender(pWindow);
    2701             :         }
    2702             :     }
    2703        1119 : }
    2704             : 
    2705             : // util::XEventListener (base of XCloseListener)
    2706           0 : void SAL_CALL ChartView::disposing( const lang::EventObject& /* rSource */ )
    2707             :         throw(uno::RuntimeException, std::exception)
    2708             : {
    2709           0 : }
    2710             : 
    2711       15972 : void ChartView::impl_updateView( bool bCheckLockedCtrler )
    2712             : {
    2713       15972 :     if( !m_pDrawModelWrapper )
    2714           0 :         return;
    2715             : 
    2716             :     // #i12587# support for shapes in chart
    2717       15972 :     if ( m_bSdrViewIsInEditMode )
    2718             :     {
    2719           0 :         return;
    2720             :     }
    2721             : 
    2722       15972 :     if (bCheckLockedCtrler && mrChartModel.hasControllersLocked())
    2723          29 :         return;
    2724             : 
    2725       15943 :     if( m_bViewDirty && !m_bInViewUpdate )
    2726             :     {
    2727        1107 :         m_bInViewUpdate = true;
    2728             :         //bool bOldRefreshAddIn = m_bRefreshAddIn;
    2729             :         //m_bRefreshAddIn = false;
    2730             :         try
    2731             :         {
    2732        1107 :             impl_notifyModeChangeListener("invalid");
    2733             : 
    2734             :             //prepare draw model
    2735             :             {
    2736        1107 :                 SolarMutexGuard aSolarGuard;
    2737        1107 :                 m_pDrawModelWrapper->lockControllers();
    2738             :             }
    2739             : 
    2740             :             //create chart view
    2741             :             {
    2742        1107 :                 m_bViewDirty = false;
    2743        1107 :                 m_bViewUpdatePending = false;
    2744        1107 :                 createShapes();
    2745             : 
    2746        1107 :                 if( m_bViewDirty )
    2747             :                 {
    2748             :                     //avoid recursions due to add-in
    2749          69 :                     m_bRefreshAddIn = false;
    2750          69 :                     m_bViewDirty = false;
    2751          69 :                     m_bViewUpdatePending = false;
    2752             :                     //delete old chart view
    2753          69 :                     createShapes();
    2754          69 :                     m_bRefreshAddIn = true;
    2755             :                 }
    2756             :             }
    2757             : 
    2758        1107 :             m_bViewDirty = m_bViewUpdatePending;
    2759        1107 :             m_bViewUpdatePending = false;
    2760        1107 :             m_bInViewUpdate = false;
    2761             :         }
    2762           0 :         catch( const uno::Exception& ex)
    2763             :         {
    2764           0 :             m_bViewDirty = m_bViewUpdatePending;
    2765           0 :             m_bViewUpdatePending = false;
    2766           0 :             m_bInViewUpdate = false;
    2767             :             ASSERT_EXCEPTION( ex );
    2768             :         }
    2769             : 
    2770             :         {
    2771        1107 :             SolarMutexGuard aSolarGuard;
    2772        1107 :             m_pDrawModelWrapper->unlockControllers();
    2773             :         }
    2774             : 
    2775        1107 :         impl_notifyModeChangeListener("valid");
    2776             : 
    2777             :         //m_bRefreshAddIn = bOldRefreshAddIn;
    2778             :     }
    2779             : }
    2780             : 
    2781             : // ____ XModifyListener ____
    2782        1792 : void SAL_CALL ChartView::modified( const lang::EventObject& /* aEvent */ )
    2783             :     throw (uno::RuntimeException, std::exception)
    2784             : {
    2785        1792 :     m_bViewDirty = true;
    2786        1792 :     if( m_bInViewUpdate )
    2787          71 :         m_bViewUpdatePending = true;
    2788             : 
    2789        1792 :     impl_notifyModeChangeListener("dirty");
    2790        1792 : }
    2791             : 
    2792             : //SfxListener
    2793       90338 : void ChartView::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
    2794             : {
    2795             :     //#i77362 change notification for changes on additional shapes are missing
    2796       90338 :     if( m_bInViewUpdate )
    2797       90338 :         return;
    2798             : 
    2799             :     // #i12587# support for shapes in chart
    2800           0 :     if ( m_bSdrViewIsInEditMode )
    2801             :     {
    2802           0 :         uno::Reference< view::XSelectionSupplier > xSelectionSupplier( mrChartModel.getCurrentController(), uno::UNO_QUERY );
    2803           0 :         if ( xSelectionSupplier.is() )
    2804             :         {
    2805           0 :             OUString aSelObjCID;
    2806           0 :             uno::Any aSelObj( xSelectionSupplier->getSelection() );
    2807           0 :             aSelObj >>= aSelObjCID;
    2808           0 :             if ( !aSelObjCID.isEmpty() )
    2809             :             {
    2810           0 :                 return;
    2811           0 :             }
    2812           0 :         }
    2813             :     }
    2814             : 
    2815           0 :     const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >(&rHint);
    2816           0 :     if( !pSdrHint )
    2817           0 :         return;
    2818             : 
    2819           0 :     bool bShapeChanged = false;
    2820           0 :     switch( pSdrHint->GetKind() )
    2821             :     {
    2822             :          case HINT_OBJCHG:
    2823           0 :             bShapeChanged = true;
    2824           0 :             break;
    2825             :         case HINT_OBJINSERTED:
    2826           0 :             bShapeChanged = true;
    2827           0 :             break;
    2828             :         case HINT_OBJREMOVED:
    2829           0 :             bShapeChanged = true;
    2830           0 :             break;
    2831             :         case HINT_MODELCLEARED:
    2832           0 :             bShapeChanged = true;
    2833           0 :             break;
    2834             :         case HINT_ENDEDIT:
    2835           0 :             bShapeChanged = true;
    2836           0 :             break;
    2837             :         default:
    2838           0 :             break;
    2839             :     }
    2840             : 
    2841           0 :     if(bShapeChanged)
    2842             :     {
    2843             :         //#i76053# do not send view modified notifications for changes on the hidden page which contains e.g. the symbols for the dialogs
    2844           0 :         if( ChartView::getSdrPage() != pSdrHint->GetPage() )
    2845           0 :             bShapeChanged=false;
    2846             :     }
    2847             : 
    2848           0 :     if(!bShapeChanged)
    2849           0 :         return;
    2850             : 
    2851           0 :     mrChartModel.setModified(sal_True);
    2852             : }
    2853             : 
    2854        4006 : void ChartView::impl_notifyModeChangeListener( const OUString& rNewMode )
    2855             : {
    2856             :     try
    2857             :     {
    2858             :         ::cppu::OInterfaceContainerHelper* pIC = m_aListenerContainer
    2859        4006 :             .getContainer( cppu::UnoType<util::XModeChangeListener>::get());
    2860        4006 :         if( pIC )
    2861             :         {
    2862        2387 :             util::ModeChangeEvent aEvent( static_cast< uno::XWeak* >( this ), rNewMode );
    2863        4774 :             ::cppu::OInterfaceIteratorHelper aIt( *pIC );
    2864        7161 :             while( aIt.hasMoreElements() )
    2865             :             {
    2866        2387 :                 uno::Reference< util::XModeChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
    2867        2387 :                 if( xListener.is() )
    2868        2387 :                     xListener->modeChanged( aEvent );
    2869        4774 :             }
    2870             :         }
    2871             :     }
    2872           0 :     catch( const uno::Exception& ex)
    2873             :     {
    2874             :         ASSERT_EXCEPTION( ex );
    2875             :     }
    2876        4006 : }
    2877             : 
    2878             : // ____ XModeChangeBroadcaster ____
    2879             : 
    2880          17 : void SAL_CALL ChartView::addModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener )
    2881             :     throw (uno::RuntimeException, std::exception)
    2882             : {
    2883             :     m_aListenerContainer.addInterface(
    2884          17 :         cppu::UnoType<util::XModeChangeListener>::get(), xListener );
    2885          17 : }
    2886           1 : void SAL_CALL ChartView::removeModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener )
    2887             :     throw (uno::RuntimeException, std::exception)
    2888             : {
    2889             :     m_aListenerContainer.removeInterface(
    2890           1 :         cppu::UnoType<util::XModeChangeListener>::get(), xListener );
    2891           1 : }
    2892           0 : void SAL_CALL ChartView::addModeChangeApproveListener( const uno::Reference< util::XModeChangeApproveListener >& /* _rxListener */ )
    2893             :     throw (lang::NoSupportException, uno::RuntimeException, std::exception)
    2894             : {
    2895             : 
    2896           0 : }
    2897           0 : void SAL_CALL ChartView::removeModeChangeApproveListener( const uno::Reference< util::XModeChangeApproveListener >& /* _rxListener */ )
    2898             :     throw (lang::NoSupportException, uno::RuntimeException, std::exception)
    2899             : {
    2900             : 
    2901           0 : }
    2902             : 
    2903             : // ____ XUpdatable ____
    2904         872 : void SAL_CALL ChartView::update() throw (uno::RuntimeException, std::exception)
    2905             : {
    2906         872 :     impl_updateView(true);
    2907             : 
    2908             :     //#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this):
    2909             :     //Although in general it is a bad idea to change the model from within the view this is exceptionally the best place to do this special conversion.
    2910             :     //When a view update is requested (what happens for creating the metafile or displaying
    2911             :     //the chart in edit mode or printing) it is most likely that all necessary information are available - like the underlying spreadsheet data for example.
    2912             :     //Those data are important for the correct axis label sizes which are needed during conversion.
    2913         872 :     if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( mrChartModel, true, false ) )
    2914           0 :         impl_updateView();
    2915         872 : }
    2916             : 
    2917           0 : void SAL_CALL ChartView::updateSoft() throw (uno::RuntimeException, std::exception)
    2918             : {
    2919           0 :     update();
    2920           0 : }
    2921             : 
    2922         216 : void SAL_CALL ChartView::updateHard() throw (uno::RuntimeException, std::exception)
    2923             : {
    2924         216 :     impl_updateView(false);
    2925         216 : }
    2926             : 
    2927             : // ____ XPropertySet ____
    2928           0 : Reference< beans::XPropertySetInfo > SAL_CALL ChartView::getPropertySetInfo()
    2929             :     throw (uno::RuntimeException, std::exception)
    2930             : {
    2931             :     OSL_FAIL("not implemented");
    2932           0 :     return 0;
    2933             : }
    2934             : 
    2935         866 : void SAL_CALL ChartView::setPropertyValue( const OUString& rPropertyName
    2936             :                                                      , const Any& rValue )
    2937             :     throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException
    2938             :           , lang::WrappedTargetException, uno::RuntimeException, std::exception)
    2939             : {
    2940         866 :     if( rPropertyName == "Resolution" )
    2941             :     {
    2942         849 :         awt::Size aNewResolution;
    2943         849 :         if( ! (rValue >>= aNewResolution) )
    2944           0 :             throw lang::IllegalArgumentException( "Property 'Resolution' requires value of type awt::Size", 0, 0 );
    2945             : 
    2946         849 :         if( m_aPageResolution.Width!=aNewResolution.Width || m_aPageResolution.Height!=aNewResolution.Height )
    2947             :         {
    2948             :             //set modified only when the new resolution is higher and points were skipped before
    2949          17 :             bool bSetModified = m_bPointsWereSkipped && (m_aPageResolution.Width<aNewResolution.Width || m_aPageResolution.Height<aNewResolution.Height);
    2950             : 
    2951          17 :             m_aPageResolution = aNewResolution;
    2952             : 
    2953          17 :             if( bSetModified )
    2954           0 :                 this->modified( lang::EventObject(  static_cast< uno::XWeak* >( this )  ) );
    2955             :         }
    2956             :     }
    2957          17 :     else if( rPropertyName == "ZoomFactors" )
    2958             :     {
    2959             :         //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
    2960          17 :         uno::Sequence< beans::PropertyValue > aZoomFactors;
    2961          17 :         if( ! (rValue >>= aZoomFactors) )
    2962           0 :             throw lang::IllegalArgumentException( "Property 'ZoomFactors' requires value of type Sequence< PropertyValue >", 0, 0 );
    2963             : 
    2964          17 :         sal_Int32 nFilterArgs = aZoomFactors.getLength();
    2965          17 :         beans::PropertyValue* pDataValues = aZoomFactors.getArray();
    2966         102 :         while( nFilterArgs-- )
    2967             :         {
    2968          68 :             if ( pDataValues->Name == "ScaleXNumerator" )
    2969          17 :                 pDataValues->Value >>= m_nScaleXNumerator;
    2970          51 :             else if ( pDataValues->Name == "ScaleXDenominator" )
    2971          17 :                 pDataValues->Value >>= m_nScaleXDenominator;
    2972          34 :             else if ( pDataValues->Name == "ScaleYNumerator" )
    2973          17 :                 pDataValues->Value >>= m_nScaleYNumerator;
    2974          17 :             else if ( pDataValues->Name == "ScaleYDenominator" )
    2975          17 :                 pDataValues->Value >>= m_nScaleYDenominator;
    2976             : 
    2977          68 :             pDataValues++;
    2978          17 :         }
    2979             :     }
    2980           0 :     else if( rPropertyName == "SdrViewIsInEditMode" )
    2981             :     {
    2982             :         //#i77362 change notification for changes on additional shapes are missing
    2983           0 :         if( ! (rValue >>= m_bSdrViewIsInEditMode) )
    2984           0 :             throw lang::IllegalArgumentException( "Property 'SdrViewIsInEditMode' requires value of type sal_Bool", 0, 0 );
    2985             :     }
    2986             :     else
    2987           0 :         throw beans::UnknownPropertyException( "unknown property was tried to set to chart wizard", 0 );
    2988         866 : }
    2989             : 
    2990           0 : Any SAL_CALL ChartView::getPropertyValue( const OUString& rPropertyName )
    2991             :     throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    2992             : {
    2993           0 :     Any aRet;
    2994           0 :     if( rPropertyName == "Resolution" )
    2995             :     {
    2996           0 :         aRet = uno::makeAny( m_aPageResolution );
    2997             :     }
    2998             :     else
    2999           0 :         throw beans::UnknownPropertyException( "unknown property was tried to get from chart wizard", 0 );
    3000           0 :     return aRet;
    3001             : }
    3002             : 
    3003           0 : void SAL_CALL ChartView::addPropertyChangeListener(
    3004             :     const OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* xListener */ )
    3005             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    3006             : {
    3007             :     OSL_FAIL("not implemented");
    3008           0 : }
    3009           0 : void SAL_CALL ChartView::removePropertyChangeListener(
    3010             :     const OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* aListener */ )
    3011             :     throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    3012             : {
    3013             :     OSL_FAIL("not implemented");
    3014           0 : }
    3015             : 
    3016           0 : void SAL_CALL ChartView::addVetoableChangeListener( const OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
    3017             :     throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    3018             : {
    3019             :     OSL_FAIL("not implemented");
    3020           0 : }
    3021             : 
    3022           0 : void SAL_CALL ChartView::removeVetoableChangeListener( const OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
    3023             :     throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
    3024             : {
    3025             :     OSL_FAIL("not implemented");
    3026           0 : }
    3027             : 
    3028             : // ____ XMultiServiceFactory ____
    3029             : 
    3030        3258 : Reference< uno::XInterface > ChartView::createInstance( const OUString& aServiceSpecifier )
    3031             :     throw (uno::Exception, uno::RuntimeException, std::exception)
    3032             : {
    3033        3258 :     SolarMutexGuard aSolarGuard;
    3034             : 
    3035        3258 :     SdrModel* pModel = ( m_pDrawModelWrapper ? &m_pDrawModelWrapper->getSdrModel() : NULL );
    3036        3258 :     if ( pModel )
    3037             :     {
    3038        3258 :         if ( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
    3039             :         {
    3040         598 :             if ( !m_xDashTable.is() )
    3041             :             {
    3042         321 :                 m_xDashTable = SvxUnoDashTable_createInstance( pModel );
    3043             :             }
    3044         598 :             return m_xDashTable;
    3045             :         }
    3046        2660 :         else if ( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
    3047             :         {
    3048         602 :             if ( !m_xGradientTable.is() )
    3049             :             {
    3050         321 :                 m_xGradientTable = SvxUnoGradientTable_createInstance( pModel );
    3051             :             }
    3052         602 :             return m_xGradientTable;
    3053             :         }
    3054        2058 :         else if ( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
    3055             :         {
    3056         599 :             if ( !m_xHatchTable.is() )
    3057             :             {
    3058         321 :                 m_xHatchTable = SvxUnoHatchTable_createInstance( pModel );
    3059             :             }
    3060         599 :             return m_xHatchTable;
    3061             :         }
    3062        1459 :         else if ( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
    3063             :         {
    3064         597 :             if ( !m_xBitmapTable.is() )
    3065             :             {
    3066         321 :                 m_xBitmapTable = SvxUnoBitmapTable_createInstance( pModel );
    3067             :             }
    3068         597 :             return m_xBitmapTable;
    3069             :         }
    3070         862 :         else if ( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
    3071             :         {
    3072         593 :             if ( !m_xTransGradientTable.is() )
    3073             :             {
    3074         321 :                 m_xTransGradientTable = SvxUnoTransGradientTable_createInstance( pModel );
    3075             :             }
    3076         593 :             return m_xTransGradientTable;
    3077             :         }
    3078         269 :         else if ( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
    3079             :         {
    3080         269 :             if ( !m_xMarkerTable.is() )
    3081             :             {
    3082          95 :                 m_xMarkerTable = SvxUnoMarkerTable_createInstance( pModel );
    3083             :             }
    3084         269 :             return m_xMarkerTable;
    3085             :         }
    3086             :     }
    3087             : 
    3088           0 :     return 0;
    3089             : }
    3090             : 
    3091           0 : Reference< uno::XInterface > ChartView::createInstanceWithArguments( const OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments )
    3092             :     throw (uno::Exception, uno::RuntimeException, std::exception)
    3093             : {
    3094             :     OSL_ENSURE( Arguments.getLength(), "ChartView::createInstanceWithArguments: arguments are ignored" );
    3095             :     (void) Arguments; // avoid warning
    3096           0 :     return createInstance( ServiceSpecifier );
    3097             : }
    3098             : 
    3099           0 : uno::Sequence< OUString > ChartView::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
    3100             : {
    3101           0 :     uno::Sequence< OUString > aServiceNames( 6 );
    3102             : 
    3103           0 :     aServiceNames[0] = "com.sun.star.drawing.DashTable";
    3104           0 :     aServiceNames[1] = "com.sun.star.drawing.GradientTable";
    3105           0 :     aServiceNames[2] = "com.sun.star.drawing.HatchTable";
    3106           0 :     aServiceNames[3] = "com.sun.star.drawing.BitmapTable";
    3107           0 :     aServiceNames[4] = "com.sun.star.drawing.TransparencyGradientTable";
    3108           0 :     aServiceNames[5] = "com.sun.star.drawing.MarkerTable";
    3109             : 
    3110           0 :     return aServiceNames;
    3111             : }
    3112             : 
    3113           0 : OUString ChartView::dump() throw (uno::RuntimeException, std::exception)
    3114             : {
    3115             : #if HAVE_FEATURE_DESKTOP
    3116             :     // Used for unit tests and in chartcontroller only, no need to drag in this when cross-compiling
    3117             :     // for non-desktop
    3118           0 :     impl_updateView();
    3119           0 :     uno::Reference< drawing::XShapes > xShapes( m_xDrawPage, uno::UNO_QUERY_THROW );
    3120           0 :     sal_Int32 n = xShapes->getCount();
    3121           0 :     OUStringBuffer aBuffer;
    3122           0 :     for(sal_Int32 i = 0; i < n; ++i)
    3123             :     {
    3124           0 :         uno::Reference< drawing::XShapes > xShape(xShapes->getByIndex(i), uno::UNO_QUERY);
    3125           0 :         if(xShape.is())
    3126             :         {
    3127           0 :             XShapeDumper dumper;
    3128           0 :             OUString aString = XShapeDumper::dump(mxRootShape);
    3129           0 :             aBuffer.append(aString);
    3130             :         }
    3131             :         else
    3132             :         {
    3133           0 :             uno::Reference< drawing::XShape > xSingleShape(xShapes->getByIndex(i), uno::UNO_QUERY);
    3134           0 :             if(!xSingleShape.is())
    3135           0 :                 continue;
    3136           0 :             XShapeDumper dumper;
    3137           0 :             OUString aString = XShapeDumper::dump(xSingleShape);
    3138           0 :             aBuffer.append(aString);
    3139             :         }
    3140           0 :         aBuffer.append("\n\n");
    3141           0 :     }
    3142             : 
    3143           0 :     return aBuffer.makeStringAndClear();
    3144             : #else
    3145             :     return OUString();
    3146             : #endif
    3147             : }
    3148             : 
    3149          17 : void ChartView::setViewDirty()
    3150             : {
    3151          17 :     osl::ResettableMutexGuard aGuard(maTimeMutex);
    3152          17 :     m_bViewDirty = true;
    3153          17 : }
    3154             : 
    3155           0 : IMPL_LINK_NOARG_TYPED(ChartView, UpdateTimeBased, Timer *, void)
    3156             : {
    3157           0 :     setViewDirty();
    3158           0 :     update();
    3159           0 : }
    3160             : 
    3161        1176 : void ChartView::createShapes2D( const awt::Size& rPageSize )
    3162             : {
    3163        1176 :     AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
    3164             : 
    3165        1176 :     SolarMutexGuard aSolarGuard;
    3166             : 
    3167             :     // todo: it would be nicer to just pass the page m_xDrawPage and format it,
    3168             :     // but the draw page does not support XPropertySet
    3169        1176 :     formatPage( mrChartModel, rPageSize, mxRootShape, m_xShapeFactory );
    3170             : 
    3171        2295 :     CreateShapeParam2D aParam;
    3172        1176 :     aParam.maRemainingSpace.X = 0;
    3173        1176 :     aParam.maRemainingSpace.Y = 0;
    3174        1176 :     aParam.maRemainingSpace.Width = rPageSize.Width;
    3175        1176 :     aParam.maRemainingSpace.Height = rPageSize.Height;
    3176             : 
    3177             :     //create the group shape for diagram and axes first to have title and legends on top of it
    3178        2295 :     uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
    3179        2295 :     OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) ) );//todo: other index if more than one diagram is possible
    3180             :     uno::Reference< drawing::XShapes > xDiagramPlusAxesPlusMarkHandlesGroup_Shapes(
    3181        2295 :             pShapeFactory->createGroup2D(mxRootShape,aDiagramCID) );
    3182             : 
    3183        2352 :     aParam.mxMarkHandles = pShapeFactory->createInvisibleRectangle(
    3184        2352 :         xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0));
    3185        1176 :     AbstractShapeFactory::setShapeName(aParam.mxMarkHandles, "MarkHandles");
    3186             : 
    3187        2352 :     aParam.mxPlotAreaWithAxes = pShapeFactory->createInvisibleRectangle(
    3188        2352 :         xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0, 0));
    3189        1176 :     AbstractShapeFactory::setShapeName(aParam.mxPlotAreaWithAxes, "PlotAreaIncludingAxes");
    3190             : 
    3191        1176 :     aParam.mxDiagramWithAxesShapes = pShapeFactory->createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes);
    3192             : 
    3193        1176 :     bool bAutoPositionDummy = true;
    3194             : 
    3195             :     lcl_createTitle(
    3196             :         TitleHelper::MAIN_TITLE, mxRootShape, m_xShapeFactory, mrChartModel,
    3197        1176 :         aParam.maRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy);
    3198        1176 :     if (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0)
    3199          55 :         return;
    3200             : 
    3201             :     lcl_createTitle(
    3202             :         TitleHelper::SUB_TITLE, mxRootShape, m_xShapeFactory, mrChartModel,
    3203        1121 :         aParam.maRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy );
    3204        1121 :     if (aParam.maRemainingSpace.Width <= 0|| aParam.maRemainingSpace.Height <= 0)
    3205           0 :         return;
    3206             : 
    3207        1121 :     aParam.mpSeriesPlotterContainer.reset(new SeriesPlotterContainer(m_aVCooSysList));
    3208        1121 :     aParam.mpSeriesPlotterContainer->initializeCooSysAndSeriesPlotter( mrChartModel );
    3209        1121 :     if(maTimeBased.bTimeBased && maTimeBased.nFrame != 0)
    3210             :     {
    3211           0 :         SeriesPlottersType& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList();
    3212           0 :         size_t n = rSeriesPlotter.size();
    3213           0 :         for(size_t i = 0; i < n; ++i)
    3214             :         {
    3215           0 :             std::vector<VDataSeries*> aAllNewDataSeries = rSeriesPlotter[i].getAllSeries();
    3216             :             std::vector< VDataSeries* >& rAllOldDataSeries =
    3217           0 :                 maTimeBased.m_aDataSeriesList[i];
    3218           0 :             size_t m = std::min(aAllNewDataSeries.size(), rAllOldDataSeries.size());
    3219           0 :             for(size_t j = 0; j < m; ++j)
    3220             :             {
    3221           0 :                 aAllNewDataSeries[j]->setOldTimeBased(
    3222           0 :                         rAllOldDataSeries[j], (maTimeBased.nFrame % 60)/60.0);
    3223             :             }
    3224           0 :         }
    3225             :     }
    3226             : 
    3227             :     lcl_createLegend(
    3228             :         LegendHelper::getLegend( mrChartModel ), mxRootShape, m_xShapeFactory, m_xCC,
    3229             :         aParam.maRemainingSpace, rPageSize, mrChartModel, aParam.mpSeriesPlotterContainer->getLegendEntryProviderList(),
    3230        1121 :         lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) );
    3231        1121 :     if (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0)
    3232           2 :         return;
    3233             : 
    3234        1119 :     if (!createAxisTitleShapes2D(aParam, rPageSize))
    3235           0 :         return;
    3236             : 
    3237        1119 :     bool bDummy = false;
    3238        1119 :     bool bIsVertical = DiagramHelper::getVertical(xDiagram, bDummy, bDummy);
    3239             : 
    3240        1119 :     if (getAvailablePosAndSizeForDiagram(aParam, rPageSize, mrChartModel.getFirstDiagram()))
    3241             :     {
    3242        1119 :         awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent(aParam, rPageSize);
    3243             : 
    3244        1119 :         if (aParam.mxPlotAreaWithAxes.is())
    3245             :         {
    3246        1119 :             aParam.mxPlotAreaWithAxes->setPosition(awt::Point(aUsedOuterRect.X, aUsedOuterRect.Y));
    3247        1119 :             aParam.mxPlotAreaWithAxes->setSize(awt::Size(aUsedOuterRect.Width, aUsedOuterRect.Height));
    3248             :         }
    3249             : 
    3250             :         //correct axis title position
    3251        1119 :         awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect );
    3252        1119 :         if (aParam.mbAutoPosTitleX)
    3253        1119 :             changePositionOfAxisTitle(aParam.mpVTitleX.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize);
    3254        1119 :         if (aParam.mbAutoPosTitleY)
    3255        1119 :             changePositionOfAxisTitle(aParam.mpVTitleY.get(), ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize);
    3256        1119 :         if (aParam.mbAutoPosTitleZ)
    3257        1119 :             changePositionOfAxisTitle(aParam.mpVTitleZ.get(), ALIGN_Z, aDiagramPlusAxesRect, rPageSize);
    3258        1119 :         if (aParam.mbAutoPosSecondTitleX)
    3259        1119 :             changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? ALIGN_RIGHT : ALIGN_TOP, aDiagramPlusAxesRect, rPageSize);
    3260        1119 :         if (aParam.mbAutoPosSecondTitleY)
    3261        1119 :             changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? ALIGN_TOP : ALIGN_RIGHT, aDiagramPlusAxesRect, rPageSize);
    3262             :     }
    3263             : 
    3264             :     //cleanup: remove all empty group shapes to avoid grey border lines:
    3265        1119 :     lcl_removeEmptyGroupShapes( mxRootShape );
    3266             : 
    3267        1119 :     render();
    3268             : 
    3269        1119 :     if(maTimeBased.bTimeBased && maTimeBased.nFrame % 60 == 0)
    3270             :     {
    3271             :         // create copy of the data for next frame
    3272           0 :         SeriesPlottersType& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList();
    3273           0 :         size_t n = rSeriesPlotter.size();
    3274           0 :         maTimeBased.m_aDataSeriesList.clear();
    3275           0 :         maTimeBased.m_aDataSeriesList.resize(n);
    3276           0 :         for(size_t i = 0; i < n; ++i)
    3277             :         {
    3278           0 :             std::vector<VDataSeries*> aAllNewDataSeries = rSeriesPlotter[i].getAllSeries();
    3279           0 :             std::vector<VDataSeries*>& rAllOldDataSeries = maTimeBased.m_aDataSeriesList[i];
    3280           0 :             size_t m = aAllNewDataSeries.size();
    3281           0 :             for(size_t j = 0; j < m; ++j)
    3282             :             {
    3283           0 :                 rAllOldDataSeries.push_back( aAllNewDataSeries[j]->
    3284           0 :                         createCopyForTimeBased() );
    3285             :             }
    3286           0 :         }
    3287             : 
    3288           0 :         if(maTimeBased.eMode != MANUAL)
    3289             :         {
    3290           0 :             mrChartModel.setTimeBased(true);
    3291           0 :             mrChartModel.getNextTimePoint();
    3292             :         }
    3293             :         else
    3294           0 :             maTimeBased.maTimer.Stop();
    3295             :     }
    3296             : 
    3297        1119 :     if(maTimeBased.bTimeBased && maTimeBased.eMode != MANUAL && !maTimeBased.maTimer.IsActive())
    3298             :     {
    3299           0 :         maTimeBased.maTimer.SetTimeout(15);
    3300           0 :         maTimeBased.maTimer.SetTimeoutHdl(LINK(this, ChartView, UpdateTimeBased));
    3301           0 :         maTimeBased.maTimer.Start();
    3302        1119 :     }
    3303             : }
    3304             : 
    3305        1119 : bool ChartView::createAxisTitleShapes2D( CreateShapeParam2D& rParam, const css::awt::Size& rPageSize )
    3306             : {
    3307        1119 :     uno::Reference<XDiagram> xDiagram = mrChartModel.getFirstDiagram();
    3308             : 
    3309        2238 :     Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
    3310        1119 :     sal_Int32 nDimension = DiagramHelper::getDimension( xDiagram );
    3311             : 
    3312        1119 :     if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 0 ) )
    3313        2164 :         rParam.mpVTitleX = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, mxRootShape, m_xShapeFactory, mrChartModel
    3314        1082 :                 , rParam.maRemainingSpace, rPageSize, ALIGN_BOTTOM, rParam.mbAutoPosTitleX );
    3315        1119 :     if (rParam.maRemainingSpace.Width <= 0 ||rParam.maRemainingSpace.Height <= 0)
    3316           0 :         return false;
    3317             : 
    3318        1119 :     if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 1 ) )
    3319        2164 :         rParam.mpVTitleY = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, mxRootShape, m_xShapeFactory, mrChartModel
    3320        1082 :                 , rParam.maRemainingSpace, rPageSize, ALIGN_LEFT, rParam.mbAutoPosTitleY );
    3321        1119 :     if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
    3322           0 :         return false;
    3323             : 
    3324        1119 :     if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 2 ) )
    3325         230 :         rParam.mpVTitleZ = lcl_createTitle( TitleHelper::Z_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel
    3326         115 :                 , rParam.maRemainingSpace, rPageSize, ALIGN_RIGHT, rParam.mbAutoPosTitleZ );
    3327        1119 :     if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
    3328           0 :         return false;
    3329             : 
    3330        1119 :     bool bDummy = false;
    3331        1119 :     bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
    3332             : 
    3333        1119 :     if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 0 ) )
    3334        2062 :         rParam.mpVTitleSecondX = lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel
    3335        1031 :                 , rParam.maRemainingSpace, rPageSize, bIsVertical? ALIGN_RIGHT : ALIGN_TOP, rParam.mbAutoPosSecondTitleX );
    3336        1119 :     if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
    3337           0 :         return false;
    3338             : 
    3339        1119 :     if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 1 ) )
    3340        2062 :         rParam.mpVTitleSecondY = lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel
    3341        1031 :                 , rParam.maRemainingSpace, rPageSize, bIsVertical? ALIGN_TOP : ALIGN_RIGHT, rParam.mbAutoPosSecondTitleY );
    3342        1119 :     if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
    3343           0 :         return false;
    3344             : 
    3345        2238 :     return true;
    3346             : }
    3347             : 
    3348           0 : void ChartView::createShapes3D()
    3349             : {
    3350           0 :     OpenGLWindow* pWindow = mrChartModel.getOpenGLWindow();
    3351           0 :     if(!pWindow)
    3352           0 :         return;
    3353             : 
    3354           0 :     if( pWindow->GetSizePixel().Width() == 0 || pWindow->GetSizePixel().Height() == 0 )
    3355             :     {
    3356           0 :         awt::Size aPageSize = mrChartModel.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
    3357           0 :         Size aSize = pWindow->LogicToPixel( Size(aPageSize.Width,aPageSize.Height), MapUnit(MAP_100TH_MM) );
    3358           0 :         pWindow->SetSizePixel(aSize);
    3359             :     }
    3360           0 :     pWindow->Show();
    3361           0 :     uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() );
    3362           0 :     uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
    3363           0 :     if( !xCooSysContainer.is())
    3364           0 :         return;
    3365             : 
    3366           0 :     uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
    3367             : 
    3368           0 :     if (aCooSysList.getLength() != 1)
    3369             :         // Supporting multiple coordinates in a truly 3D chart (which implies
    3370             :         // it's a Cartesian coordinate system) is a bit of a challenge, if not
    3371             :         // impossible.
    3372           0 :         return;
    3373             : 
    3374           0 :     uno::Reference<XCoordinateSystem> xCooSys( aCooSysList[0] );
    3375             : 
    3376             :     //iterate through all chart types in the current coordinate system
    3377           0 :     uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
    3378             :     OSL_ASSERT( xChartTypeContainer.is());
    3379           0 :     if( !xChartTypeContainer.is() )
    3380           0 :         return;
    3381             : 
    3382           0 :     uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
    3383           0 :     if (aChartTypeList.getLength() != 1)
    3384             :         // Likewise, we can't really support multiple chart types here.
    3385           0 :         return;
    3386             : 
    3387           0 :     uno::Reference< XChartType > xChartType( aChartTypeList[0] );
    3388             : 
    3389           0 :     if (!m_pGL3DPlotter)
    3390             :     {
    3391           0 :         m_pGL3DPlotter.reset(new GL3DBarChart(xChartType, pWindow));
    3392             :     }
    3393             :     else
    3394             :     {
    3395           0 :         GL3DBarChart* pChart = dynamic_cast<GL3DBarChart*>(m_pGL3DPlotter.get());
    3396           0 :         if (pChart)
    3397           0 :             pChart->setOpenGLWindow(pWindow);
    3398             :     }
    3399             : 
    3400           0 :     uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
    3401             :     OSL_ASSERT( xDataSeriesContainer.is());
    3402           0 :     if( !xDataSeriesContainer.is() )
    3403           0 :         return;
    3404             : 
    3405           0 :     boost::ptr_vector<VDataSeries> aDataSeries;
    3406           0 :     uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
    3407           0 :     for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
    3408             :     {
    3409           0 :         uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], uno::UNO_QUERY );
    3410           0 :         if(!xDataSeries.is())
    3411           0 :             continue;
    3412             : 
    3413           0 :         aDataSeries.push_back(new VDataSeries(xDataSeries));
    3414           0 :     }
    3415             : 
    3416           0 :     boost::scoped_ptr<ExplicitCategoriesProvider> pCatProvider(new ExplicitCategoriesProvider(xCooSys, mrChartModel));
    3417             : 
    3418           0 :     m_pGL3DPlotter->create3DShapes(aDataSeries, *pCatProvider);
    3419             : 
    3420           0 :     m_pGL3DPlotter->render();
    3421             : }
    3422             : 
    3423          17 : void ChartView::updateOpenGLWindow()
    3424             : {
    3425          17 :     if(!isReal3DChart())
    3426          17 :         mp2DRenderer->updateOpenGLWindow();
    3427          17 : }
    3428             : 
    3429             : } //namespace chart
    3430             : 
    3431             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    3432           0 : com_sun_star_comp_chart2_ChartView_get_implementation(css::uno::XComponentContext *context,
    3433             :                                                          css::uno::Sequence<css::uno::Any> const &)
    3434             : {
    3435           0 :     ::chart::ChartModel *pChartModel = new ::chart::ChartModel(context);
    3436           0 :     return cppu::acquire(new ::chart::ChartView(context, *pChartModel));
    3437          57 : }
    3438             : 
    3439             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11