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

Generated by: LCOV version 1.10