chart2/inc/ChartView.hxx | 5 chart2/source/view/axes/Tickmarks.cxx | 20 chart2/source/view/axes/Tickmarks.hxx | 21 chart2/source/view/axes/Tickmarks_Dates.cxx | 10 chart2/source/view/axes/Tickmarks_Dates.hxx | 6 chart2/source/view/axes/Tickmarks_Equidistant.cxx | 8 chart2/source/view/axes/Tickmarks_Equidistant.hxx | 8 chart2/source/view/axes/VAxisBase.cxx | 10 chart2/source/view/axes/VAxisBase.hxx | 4 chart2/source/view/axes/VCartesianAxis.cxx | 56 chart2/source/view/axes/VCartesianAxis.hxx | 8 chart2/source/view/axes/VCartesianGrid.cxx | 14 chart2/source/view/axes/VPolarGrid.cxx | 30 chart2/source/view/axes/VPolarGrid.hxx | 10 chart2/source/view/axes/VPolarRadiusAxis.cxx | 2 chart2/source/view/main/ChartView.cxx | 1926 +++++++++++----------- 16 files changed, 1074 insertions(+), 1064 deletions(-)
New commits: commit 5086abc60cb25e98b9206bbffb5f343b512bfb59 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Oct 9 22:35:12 2014 -0400 Put SeriesPlotterContainer into CreateShapeParam2D. Change-Id: I537c131c0c927d2cbbd7cd44f07e9e4748b8ed6c diff --git a/chart2/inc/ChartView.hxx b/chart2/inc/ChartView.hxx index dc3d495..d155c45 100644 --- a/chart2/inc/ChartView.hxx +++ b/chart2/inc/ChartView.hxx @@ -52,7 +52,6 @@ namespace chart { class VCoordinateSystem; class DrawModelWrapper; -class SeriesPlotterContainer; class VDataSeries; class GL3DPlotterBase; class GL2DRenderer; @@ -222,9 +221,7 @@ private: //methods void render(); - css::awt::Rectangle impl_createDiagramAndContent( - SeriesPlotterContainer& rSeriesPlotterContainer, - const CreateShapeParam2D& rParam, const css::awt::Size& rPageSize ); + css::awt::Rectangle impl_createDiagramAndContent( const CreateShapeParam2D& rParam, const css::awt::Size& rPageSize ); DECL_LINK( UpdateTimeBased, void* ); diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index 9d75323..9078343 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -128,1157 +128,1161 @@ namespace { class theExplicitValueProviderUnoTunnelId : public rtl::Static<UnoTunnelIdInit, theExplicitValueProviderUnoTunnelId> {}; -} +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 +typedef std::map< VCoordinateSystem*, tFullAxisIndex > tCoordinateSystemMap; -struct CreateShapeParam2D +struct AxisUsage { - css::awt::Rectangle maRemainingSpace; + AxisUsage(); + ~AxisUsage(); - boost::shared_ptr<VTitle> mpVTitleX; - boost::shared_ptr<VTitle> mpVTitleY; - boost::shared_ptr<VTitle> mpVTitleZ; + void addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ); + ::std::vector< VCoordinateSystem* > getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ); + sal_Int32 getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex ); - boost::shared_ptr<VTitle> mpVTitleSecondX; - boost::shared_ptr<VTitle> mpVTitleSecondY; + ScaleAutomatism aScaleAutomatism; - css::uno::Reference<css::drawing::XShape> mxMarkHandles; - css::uno::Reference<css::drawing::XShape> mxPlotAreaWithAxes; +private: + tCoordinateSystemMap aCoordinateSystems; + std::map< sal_Int32, sal_Int32 > aMaxIndexPerDimension; +}; - css::uno::Reference<css::drawing::XShapes> mxDiagramWithAxesShapes; +AxisUsage::AxisUsage() + : aScaleAutomatism(AxisHelper::createDefaultScale(),Date( Date::SYSTEM )) +{ +} - bool mbAutoPosTitleX; - bool mbAutoPosTitleY; - bool mbAutoPosTitleZ; +AxisUsage::~AxisUsage() +{ + aCoordinateSystems.clear(); +} - bool mbAutoPosSecondTitleX; - bool mbAutoPosSecondTitleY; +void AxisUsage::addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) +{ + if(!pCooSys) + return; - bool mbUseFixedInnerSize; + tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex ); + tCoordinateSystemMap::const_iterator aFound( aCoordinateSystems.find(pCooSys) ); - CreateShapeParam2D() : - mbAutoPosTitleX(true), - mbAutoPosTitleY(true), - mbAutoPosTitleZ(true), - mbAutoPosSecondTitleX(true), - mbAutoPosSecondTitleY(true), - mbUseFixedInnerSize(false) {} -}; + //use one scale only once for each coordinate system + //main axis are preferred over secondary axis + //value scales are preferred + if(aFound!=aCoordinateSystems.end()) + { + sal_Int32 nFoundAxisIndex = aFound->second.second; + if( nFoundAxisIndex < nAxisIndex ) + return; + sal_Int32 nFoundDimension = aFound->second.first; + if( nFoundDimension ==1 ) + return; + if( nFoundDimension < nDimensionIndex ) + return; + } + aCoordinateSystems[pCooSys] = aFullAxisIndex; -class GL2DRenderer : public IRenderer -{ -public: - GL2DRenderer(ChartView* pView); - virtual ~GL2DRenderer(); + //set maximum scale index + std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex); + if( aIter != aMaxIndexPerDimension.end() ) + { + sal_Int32 nCurrentMaxIndex = aIter->second; + if( nCurrentMaxIndex < nAxisIndex ) + aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex; + } + else + aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex; +} - virtual void update() SAL_OVERRIDE; - virtual void clickedAt(const Point& rPos, sal_uInt16 nButton) SAL_OVERRIDE; - virtual void mouseDragMove(const Point& rBegin, const Point& rEnd, sal_uInt16 nButton) SAL_OVERRIDE; - virtual void scroll(long nDelta) SAL_OVERRIDE; - virtual void contextDestroyed() SAL_OVERRIDE; +::std::vector< VCoordinateSystem* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) +{ + ::std::vector< VCoordinateSystem* > aRet; - const OpenGLWindow* getOpenGLWindow() const; - void updateOpenGLWindow(); -private: - ChartView* mpView; - bool mbContextDestroyed; - OpenGLWindow* mpWindow; -}; + tCoordinateSystemMap::const_iterator aIter; + for( aIter = aCoordinateSystems.begin(); aIter!=aCoordinateSystems.end();++aIter ) + { + if( aIter->second.first != nDimensionIndex ) + continue; + if( aIter->second.second != nAxisIndex ) + continue; + aRet.push_back( aIter->first ); + } -GL2DRenderer::GL2DRenderer(ChartView* pView): - mpView(pView), - mbContextDestroyed(false), - mpWindow(mpView->mrChartModel.getOpenGLWindow()) -{ + return aRet; } -GL2DRenderer::~GL2DRenderer() +sal_Int32 AxisUsage::getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex ) { - if(!mbContextDestroyed && mpWindow) - mpWindow->setRenderer(NULL); + sal_Int32 nRet = -1; + std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex); + if( aIter != aMaxIndexPerDimension.end() ) + nRet = aIter->second; + return nRet; } -void GL2DRenderer::update() +class SeriesPlotterContainer { - mpView->update(); - mpView->render(); -} +public: + SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList ); + ~SeriesPlotterContainer(); -void GL2DRenderer::clickedAt(const Point&, sal_uInt16 ) + void initializeCooSysAndSeriesPlotter( ChartModel& rModel ); + void initAxisUsageList(const Date& rNullDate); + void doAutoScaling( ChartModel& rModel ); + void updateScalesAndIncrementsOnAxes(); + void setScalesFromCooSysToPlotter(); + void setNumberFormatsFromAxes(); + drawing::Direction3D getPreferredAspectRatio(); + + std::vector< VSeriesPlotter* >& getSeriesPlotterList() { return m_aSeriesPlotterList; } + std::vector< VCoordinateSystem* >& getCooSysList() { return m_rVCooSysList; } + std::vector< LegendEntryProvider* > getLegendEntryProviderList(); + + void AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ); + +private: + std::vector< VSeriesPlotter* > m_aSeriesPlotterList; + std::vector< VCoordinateSystem* >& m_rVCooSysList; + ::std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList; + sal_Int32 m_nMaxAxisIndex; + bool m_bChartTypeUsesShiftedCategoryPositionPerDefault; + sal_Int32 m_nDefaultDateNumberFormat; +}; + +SeriesPlotterContainer::SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList ) + : m_rVCooSysList( rVCooSysList ) + , m_nMaxAxisIndex(0) + , m_bChartTypeUsesShiftedCategoryPositionPerDefault(false) + , m_nDefaultDateNumberFormat(0) { } -void GL2DRenderer::mouseDragMove(const Point& , const Point& , sal_uInt16 ) +SeriesPlotterContainer::~SeriesPlotterContainer() { + // - remove plotter from coordinatesystems + for( size_t nC=0; nC < m_rVCooSysList.size(); nC++) + m_rVCooSysList[nC]->clearMinimumAndMaximumSupplierList(); + // - delete all plotter + ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); + const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); + for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) + delete *aPlotterIter; + m_aSeriesPlotterList.clear(); } -void GL2DRenderer::scroll(long ) +std::vector< LegendEntryProvider* > SeriesPlotterContainer::getLegendEntryProviderList() { + std::vector< LegendEntryProvider* > aRet( m_aSeriesPlotterList.size() ); + ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); + const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); + sal_Int32 nN = 0; + for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter, nN++ ) + aRet[nN] = *aPlotterIter; + return aRet; } -void GL2DRenderer::contextDestroyed() +VCoordinateSystem* findInCooSysList( const std::vector< VCoordinateSystem* >& rVCooSysList + , const uno::Reference< XCoordinateSystem >& xCooSys ) { - mbContextDestroyed = true; + for( size_t nC=0; nC < rVCooSysList.size(); nC++) + { + VCoordinateSystem* pVCooSys = rVCooSysList[nC]; + if(pVCooSys->getModel()==xCooSys) + return pVCooSys; + } + return NULL; } -const OpenGLWindow* GL2DRenderer::getOpenGLWindow() const +VCoordinateSystem* lcl_getCooSysForPlotter( const std::vector< VCoordinateSystem* >& rVCooSysList, MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier ) { - return mpWindow; + if(!pMinimumAndMaximumSupplier) + return 0; + for( size_t nC=0; nC < rVCooSysList.size(); nC++) + { + VCoordinateSystem* pVCooSys = rVCooSysList[nC]; + if(pVCooSys->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier )) + return pVCooSys; + } + return 0; } -void GL2DRenderer::updateOpenGLWindow() +VCoordinateSystem* addCooSysToList( std::vector< VCoordinateSystem* >& rVCooSysList + , const uno::Reference< XCoordinateSystem >& xCooSys + , ChartModel& rChartModel ) { - if(mbContextDestroyed) - return; - - OpenGLWindow* pWindow = mpView->mrChartModel.getOpenGLWindow(); - if(pWindow != mpWindow) + VCoordinateSystem* pVCooSys = findInCooSysList( rVCooSysList, xCooSys ); + if( !pVCooSys ) { - if(mpWindow) + pVCooSys = VCoordinateSystem::createCoordinateSystem(xCooSys ); + if(pVCooSys) { - mpWindow->setRenderer(NULL); - } + OUString aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys, rChartModel ) ); + pVCooSys->setParticle(aCooSysParticle); - if(pWindow) - { - pWindow->setRenderer(this); + pVCooSys->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys, rChartModel) ); + + rVCooSysList.push_back( pVCooSys ); } } - mpWindow = pWindow; + return pVCooSys; } -const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId() +void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter( + ChartModel& rChartModel ) { - return theExplicitValueProviderUnoTunnelId::get().getSeq(); -} + sal_Int32 nDiagramIndex = 0;//todo if more than one diagram is supported + uno::Reference< XDiagram > xDiagram( rChartModel.getFirstDiagram() ); + if( !xDiagram.is()) + return; -ExplicitValueProvider* ExplicitValueProvider::getExplicitValueProvider( - const Reference< uno::XInterface >& xChartView ) -{ - ExplicitValueProvider* pExplicitValueProvider=0; + uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject* >( &rChartModel ), uno::UNO_QUERY ); + if( rChartModel.hasInternalDataProvider() && DiagramHelper::isSupportingDateAxis( xDiagram ) ) + m_nDefaultDateNumberFormat=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier ); - Reference< lang::XUnoTunnel > xTunnel( xChartView, uno::UNO_QUERY ); - if( xTunnel.is() ) + sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); + if(!nDimensionCount) { - pExplicitValueProvider = reinterpret_cast<ExplicitValueProvider*>(xTunnel->getSomething( - ExplicitValueProvider::getUnoTunnelId() )); + //@todo handle mixed dimension + nDimensionCount = 2; } - return pExplicitValueProvider; -} -ChartView::ChartView( - uno::Reference<uno::XComponentContext> const & xContext, - ChartModel& rModel) - : m_aMutex() - , m_xCC(xContext) - , mrChartModel(rModel) - , m_xShapeFactory() - , m_xDrawPage() - , m_pDrawModelWrapper() - , m_aListenerContainer( m_aMutex ) - , m_bViewDirty(true) - , m_bInViewUpdate(false) - , m_bViewUpdatePending(false) - , m_bRefreshAddIn(true) - , m_aPageResolution(1000,1000) - , m_bPointsWereSkipped(false) - , m_nScaleXNumerator(1) - , m_nScaleXDenominator(1) - , m_nScaleYNumerator(1) - , m_nScaleYDenominator(1) - , m_bSdrViewIsInEditMode(false) - , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0) - , mp2DRenderer(new GL2DRenderer(this)) -{ - init(); -} - -void ChartView::init() -{ - if( !m_pDrawModelWrapper.get() ) + bool bSortByXValues = false; + bool bConnectBars = false; + bool bGroupBarsPerAxis = true; + bool bIncludeHiddenCells = true; + sal_Int32 nStartingAngle = 90; + sal_Int32 n3DRelativeHeight = 100; + try { - SolarMutexGuard aSolarGuard; - m_pDrawModelWrapper = ::boost::shared_ptr< DrawModelWrapper >( new DrawModelWrapper( m_xCC ) ); - m_xShapeFactory = m_pDrawModelWrapper->getShapeFactory(); - m_xDrawPage = m_pDrawModelWrapper->getMainDrawPage(); - StartListening( m_pDrawModelWrapper->getSdrModel(), false /*bPreventDups*/ ); - } -} - -void SAL_CALL ChartView::initialize( const uno::Sequence< uno::Any >& ) - throw ( uno::Exception, uno::RuntimeException, std::exception) -{ - init(); -} - -ChartView::~ChartView() -{ - maTimeBased.maTimer.Stop(); - // #i120831#. In ChartView::initialize(), m_xShapeFactory is created from SdrModel::getUnoModel() and indirectly - // from SfxBaseModel, it needs call dispose() to make sure SfxBaseModel object is freed correctly. - uno::Reference< lang::XComponent > xComp( m_xShapeFactory, uno::UNO_QUERY); - if ( xComp.is() ) - xComp->dispose(); + uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY_THROW ); + xDiaProp->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= bSortByXValues; + xDiaProp->getPropertyValue( "ConnectBars" ) >>= bConnectBars; + xDiaProp->getPropertyValue( "GroupBarsPerAxis" ) >>= bGroupBarsPerAxis; + xDiaProp->getPropertyValue( "IncludeHiddenCells" ) >>= bIncludeHiddenCells; + xDiaProp->getPropertyValue( "StartingAngle" ) >>= nStartingAngle; - if( m_pDrawModelWrapper.get() ) - { - EndListening( m_pDrawModelWrapper->getSdrModel(), false /*bAllDups*/ ); - SolarMutexGuard aSolarGuard; - m_pDrawModelWrapper.reset(); + if (nDimensionCount == 3) + { + xDiaProp->getPropertyValue( "3DRelativeHeight" ) >>= n3DRelativeHeight; + } } - m_xDrawPage = NULL; - impl_deleteCoordinateSystems(); -} - -void ChartView::impl_deleteCoordinateSystems() -{ - //delete all coordinate systems - ::std::vector< VCoordinateSystem* > aVectorToDeleteObjects; - ::std::swap( aVectorToDeleteObjects, m_aVCooSysList );//#i109770# - ::std::vector< VCoordinateSystem* >::const_iterator aIter = aVectorToDeleteObjects.begin(); - const ::std::vector< VCoordinateSystem* >::const_iterator aEnd = aVectorToDeleteObjects.end(); - for( ; aIter != aEnd; ++aIter ) + catch( const uno::Exception & ex ) { - delete *aIter; + ASSERT_EXCEPTION( ex ); } - aVectorToDeleteObjects.clear(); -} -// datatransfer::XTransferable -namespace -{ -const OUString lcl_aGDIMetaFileMIMEType( - "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ); -const OUString lcl_aGDIMetaFileMIMETypeHighContrast( - "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ); -} // anonymous namespace + //prepare for autoscaling and shape creation + // - create plotter for charttypes (for each first scale group at each plotter, as they are independent) + // - add series to plotter (thus each charttype can provide minimum and maximum values for autoscaling) + // - add plotter to coordinate systems -void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStream - , bool bUseHighContrast ) -{ - if( !m_xDrawPage.is() ) + //iterate through all coordinate systems + uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY ); + OSL_ASSERT( xCooSysContainer.is()); + if( !xCooSysContainer.is()) return; + uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); + uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); + sal_Int32 nGlobalSeriesIndex = 0;//for automatic symbols + for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS ) + { + uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] ); + VCoordinateSystem* pVCooSys = addCooSysToList(m_rVCooSysList,xCooSys,rChartModel); - // creating the graphic exporter - uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( m_xCC ); + //iterate through all chart types in the current coordinate system + uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY ); + OSL_ASSERT( xChartTypeContainer.is()); + if( !xChartTypeContainer.is() ) + continue; + uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() ); + for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT ) + { + uno::Reference< XChartType > xChartType( aChartTypeList[nT] ); + if(3 == nDimensionCount && xChartType->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE)) + { + uno::Reference< beans::XPropertySet > xPropertySet( xChartType, uno::UNO_QUERY ); + if (xPropertySet.is()) + { + try + { + sal_Int32 n3DRelativeHeightOldValue(100); + uno::Any aAny = xPropertySet->getPropertyValue( "3DRelativeHeight" ); + aAny >>= n3DRelativeHeightOldValue; + if (n3DRelativeHeightOldValue != n3DRelativeHeight) + xPropertySet->setPropertyValue( "3DRelativeHeight", uno::makeAny(n3DRelativeHeight) ); + } + catch (const uno::Exception&) { } + } + } - uno::Sequence< beans::PropertyValue > aProps(3); - aProps[0].Name = "FilterName"; - aProps[0].Value <<= OUString("SVM"); + if(nT==0) + m_bChartTypeUsesShiftedCategoryPositionPerDefault = ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( xChartType ); - aProps[1].Name = "OutputStream"; - aProps[1].Value <<= xOutStream; + bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ); + VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning ); + if( !pPlotter ) + continue; - uno::Sequence< beans::PropertyValue > aFilterData(4); - aFilterData[0].Name = "ExportOnlyBackground"; - aFilterData[0].Value <<= sal_False; - aFilterData[1].Name = "HighContrast"; - aFilterData[1].Value <<= bUseHighContrast; + m_aSeriesPlotterList.push_back( pPlotter ); + pPlotter->setNumberFormatsSupplier( xNumberFormatsSupplier ); + pPlotter->setColorScheme( xColorScheme ); + if(pVCooSys) + pPlotter->setExplicitCategoriesProvider( pVCooSys->getExplicitCategoriesProvider() ); + sal_Int32 nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( xDiagram, xChartType ); - aFilterData[2].Name = "Version"; - const sal_Int32 nVersion = SOFFICE_FILEFORMAT_50; - aFilterData[2].Value <<= nVersion; + if(pVCooSys) + pVCooSys->addMinimumAndMaximumSupplier(pPlotter); - aFilterData[3].Name = "CurrentPage"; - aFilterData[3].Value <<= uno::Reference< uno::XInterface >( m_xDrawPage, uno::UNO_QUERY ); + uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY ); + OSL_ASSERT( xDataSeriesContainer.is()); + if( !xDataSeriesContainer.is() ) + continue; - //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100% - { - aFilterData.realloc( aFilterData.getLength()+4 ); - aFilterData[4].Name = "ScaleXNumerator"; - aFilterData[4].Value = uno::makeAny( m_nScaleXNumerator ); - aFilterData[5].Name = "ScaleXDenominator"; - aFilterData[5].Value = uno::makeAny( m_nScaleXDenominator ); - aFilterData[6].Name = "ScaleYNumerator"; - aFilterData[6].Value = uno::makeAny( m_nScaleYNumerator ); - aFilterData[7].Name = "ScaleYDenominator"; - aFilterData[7].Value = uno::makeAny( m_nScaleYDenominator ); - } + sal_Int32 zSlot=-1; + sal_Int32 xSlot=-1; + sal_Int32 ySlot=-1; + uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() ); + for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS ) + { + uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], uno::UNO_QUERY ); + if(!xDataSeries.is()) + continue; + if( !bIncludeHiddenCells && !DataSeriesHelper::hasUnhiddenData(xDataSeries) ) + continue; - aProps[2].Name = "FilterData"; - aProps[2].Value <<= aFilterData; + VDataSeries* pSeries = new VDataSeries( xDataSeries ); - xExporter->setSourceDocument( uno::Reference< lang::XComponent >( m_xDrawPage, uno::UNO_QUERY) ); - if( xExporter->filter( aProps ) ) - { - xOutStream->flush(); - xOutStream->closeOutput(); - uno::Reference< io::XSeekable > xSeekable( xOutStream, uno::UNO_QUERY ); - if( xSeekable.is() ) - xSeekable->seek(0); - } -} + pSeries->setGlobalSeriesIndex(nGlobalSeriesIndex); + nGlobalSeriesIndex++; -uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aFlavor ) - throw (datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception) -{ - bool bHighContrastMetaFile( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast)); - uno::Any aRet; - if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) ) - return aRet; + if( bSortByXValues ) + pSeries->doSortByXValues(); - update(); + pSeries->setConnectBars( bConnectBars ); + pSeries->setGroupBarsPerAxis( bGroupBarsPerAxis ); + pSeries->setStartingAngle( nStartingAngle ); - SvMemoryStream aStream( 1024, 1024 ); - utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream ); + pSeries->setMissingValueTreatment( nMissingValueTreatment ); - uno::Reference< io::XOutputStream > xOutStream( pStreamWrapper ); - uno::Reference< io::XInputStream > xInStream( pStreamWrapper ); - uno::Reference< io::XSeekable > xSeekable( pStreamWrapper ); + OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCS, nT, nS ) ); + pSeries->setParticle(aSeriesParticle); - if( xOutStream.is() ) - { - this->getMetaFile( xOutStream, bHighContrastMetaFile ); + OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) ); + pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole); - if( xInStream.is() && xSeekable.is() ) - { - xSeekable->seek(0); - sal_Int32 nBytesToRead = xInStream->available(); - uno::Sequence< sal_Int8 > aSeq( nBytesToRead ); - xInStream->readBytes( aSeq, nBytesToRead); - aRet <<= aSeq; - xInStream->closeInput(); - } - } + //ignore secondary axis for charttypes that do not suppoert them + if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX && + !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, 1 ) ) + { + pSeries->setAttachedAxisIndex(MAIN_AXIS_INDEX); + } - return aRet; -} -uno::Sequence< datatransfer::DataFlavor > SAL_CALL ChartView::getTransferDataFlavors() - throw (uno::RuntimeException, std::exception) -{ - uno::Sequence< datatransfer::DataFlavor > aRet(2); - - aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType, - "GDIMetaFile", - ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); - aRet[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast, - "GDIMetaFile", - ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); - - return aRet; -} -sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor ) - throw (uno::RuntimeException, std::exception) -{ - return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) || - aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) ); -} - -// ____ XUnoTunnel ___ -::sal_Int64 SAL_CALL ChartView::getSomething( const uno::Sequence< ::sal_Int8 >& aIdentifier ) - throw( uno::RuntimeException, std::exception) -{ - if( aIdentifier.getLength() == 16 && 0 == memcmp( ExplicitValueProvider::getUnoTunnelId().getConstArray(), - aIdentifier.getConstArray(), 16 ) ) - { - ExplicitValueProvider* pProvider = this; - return reinterpret_cast<sal_Int64>(pProvider); - } - return 0; -} - -// lang::XServiceInfo - -APPHELPER_XSERVICEINFO_IMPL(ChartView,CHART_VIEW_SERVICE_IMPLEMENTATION_NAME) - - uno::Sequence< OUString > ChartView -::getSupportedServiceNames_Static() -{ - uno::Sequence< OUString > aSNS( 1 ); - aSNS.getArray()[ 0 ] = CHART_VIEW_SERVICE_NAME; - return aSNS; -} - -::basegfx::B3DHomMatrix createTransformationSceneToScreen( - const ::basegfx::B2IRectangle& rDiagramRectangleWithoutAxes ) -{ - ::basegfx::B3DHomMatrix aM; - aM.scale(double(rDiagramRectangleWithoutAxes.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME - , -double(rDiagramRectangleWithoutAxes.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 ); - aM.translate(double(rDiagramRectangleWithoutAxes.getMinX()) - , double(rDiagramRectangleWithoutAxes.getMinY()+rDiagramRectangleWithoutAxes.getHeight()-1), 0); - return aM; -} - -VCoordinateSystem* findInCooSysList( const std::vector< VCoordinateSystem* >& rVCooSysList - , const uno::Reference< XCoordinateSystem >& xCooSys ) -{ - for( size_t nC=0; nC < rVCooSysList.size(); nC++) - { - VCoordinateSystem* pVCooSys = rVCooSysList[nC]; - if(pVCooSys->getModel()==xCooSys) - return pVCooSys; + StackingDirection eDirection = pSeries->getStackingDirection(); + switch(eDirection) + { + case StackingDirection_NO_STACKING: + xSlot++; ySlot=-1; + if(zSlot<0) + zSlot=0; + break; + case StackingDirection_Y_STACKING: + ySlot++; + if(xSlot<0) + xSlot=0; + if(zSlot<0) + zSlot=0; + break; + case StackingDirection_Z_STACKING: + zSlot++; xSlot=-1; ySlot=-1; + break; + default: + // UNO enums have one additional auto-generated case + break; + } + pPlotter->addSeries( pSeries, zSlot, xSlot, ySlot ); + } + } } - return NULL; -} -VCoordinateSystem* addCooSysToList( std::vector< VCoordinateSystem* >& rVCooSysList - , const uno::Reference< XCoordinateSystem >& xCooSys - , ChartModel& rChartModel ) -{ - VCoordinateSystem* pVCooSys = findInCooSysList( rVCooSysList, xCooSys ); - if( !pVCooSys ) + //transport seriesnames to the coordinatesystems if needed + if( !m_aSeriesPlotterList.empty() ) { - pVCooSys = VCoordinateSystem::createCoordinateSystem(xCooSys ); - if(pVCooSys) + uno::Sequence< OUString > aSeriesNames; + bool bSeriesNamesInitialized = false; + for( size_t nC=0; nC < m_rVCooSysList.size(); nC++) { - OUString aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys, rChartModel ) ); - pVCooSys->setParticle(aCooSysParticle); - - pVCooSys->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys, rChartModel) ); - - rVCooSysList.push_back( pVCooSys ); + VCoordinateSystem* pVCooSys = m_rVCooSysList[nC]; + if(!pVCooSys) + continue; + if( pVCooSys->needSeriesNamesForAxis() ) + { + if(!bSeriesNamesInitialized) + { + VSeriesPlotter* pSeriesPlotter = m_aSeriesPlotterList[0]; + if( pSeriesPlotter ) + aSeriesNames = pSeriesPlotter->getSeriesNames(); + bSeriesNamesInitialized = true; + } + pVCooSys->setSeriesNamesForAxis( aSeriesNames ); + } } } - return pVCooSys; } -VCoordinateSystem* lcl_getCooSysForPlotter( const std::vector< VCoordinateSystem* >& rVCooSysList, MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier ) +void SeriesPlotterContainer::initAxisUsageList(const Date& rNullDate) { - if(!pMinimumAndMaximumSupplier) - return 0; - for( size_t nC=0; nC < rVCooSysList.size(); nC++) + m_aAxisUsageList.clear(); + size_t nC; + for( nC=0; nC < m_rVCooSysList.size(); nC++) { - VCoordinateSystem* pVCooSys = rVCooSysList[nC]; - if(pVCooSys->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier )) - return pVCooSys; + VCoordinateSystem* pVCooSys = m_rVCooSysList[nC]; + for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++) + { + uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel(); + sal_Int32 nDimensionCount = xCooSys->getDimension(); + if( nDimensionIndex >= nDimensionCount ) + continue; + bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), nDimensionCount, nDimensionIndex ); + const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); + for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex) + { + uno::Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) ); + OSL_ASSERT( xAxis.is()); + if( xAxis.is()) + { + if(m_aAxisUsageList.find(xAxis)==m_aAxisUsageList.end()) + { + chart2::ScaleData aSourceScale = xAxis->getScaleData(); + ExplicitCategoriesProvider* pExplicitCategoriesProvider = pVCooSys->getExplicitCategoriesProvider(); + if( nDimensionIndex==0 ) + AxisHelper::checkDateAxis( aSourceScale, pExplicitCategoriesProvider, bChartTypeAllowsDateAxis ); + if( (aSourceScale.AxisType == AxisType::CATEGORY && m_bChartTypeUsesShiftedCategoryPositionPerDefault) + || (aSourceScale.AxisType==AxisType::CATEGORY && pExplicitCategoriesProvider && pExplicitCategoriesProvider->hasComplexCategories() ) + || aSourceScale.AxisType == AxisType::DATE + || aSourceScale.AxisType == AxisType::SERIES ) + aSourceScale.ShiftedCategoryPosition = true; + else + aSourceScale.ShiftedCategoryPosition = false; + m_aAxisUsageList[xAxis].aScaleAutomatism = ScaleAutomatism(aSourceScale,rNullDate); + } + AxisUsage& rAxisUsage = m_aAxisUsageList[xAxis]; + rAxisUsage.addCoordinateSystem(pVCooSys,nDimensionIndex,nAxisIndex); + } + } + } } - return 0; -} -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 -typedef std::map< VCoordinateSystem*, tFullAxisIndex > tCoordinateSystemMap; - -struct AxisUsage -{ - AxisUsage(); - ~AxisUsage(); - - void addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ); - ::std::vector< VCoordinateSystem* > getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ); - sal_Int32 getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex ); - - ScaleAutomatism aScaleAutomatism; - -private: - tCoordinateSystemMap aCoordinateSystems; - std::map< sal_Int32, sal_Int32 > aMaxIndexPerDimension; -}; - -AxisUsage::AxisUsage() - : aScaleAutomatism(AxisHelper::createDefaultScale(),Date( Date::SYSTEM )) -{ -} - -AxisUsage::~AxisUsage() -{ - aCoordinateSystems.clear(); -} - -void AxisUsage::addCoordinateSystem( VCoordinateSystem* pCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) -{ - if(!pCooSys) - return; - - tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex ); - tCoordinateSystemMap::const_iterator aFound( aCoordinateSystems.find(pCooSys) ); - - //use one scale only once for each coordinate system - //main axis are preferred over secondary axis - //value scales are preferred - if(aFound!=aCoordinateSystems.end()) - { - sal_Int32 nFoundAxisIndex = aFound->second.second; - if( nFoundAxisIndex < nAxisIndex ) - return; - sal_Int32 nFoundDimension = aFound->second.first; - if( nFoundDimension ==1 ) - return; - if( nFoundDimension < nDimensionIndex ) - return; - } - aCoordinateSystems[pCooSys] = aFullAxisIndex; + ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); + const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); - //set maximum scale index - std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex); - if( aIter != aMaxIndexPerDimension.end() ) + //init m_nMaxAxisIndex + m_nMaxAxisIndex = 0; + for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++) { - sal_Int32 nCurrentMaxIndex = aIter->second; - if( nCurrentMaxIndex < nAxisIndex ) - aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex; + for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) + { + sal_Int32 nLocalMax = aAxisIter->second.getMaxAxisIndexForDimension( nDimensionIndex ); + if( m_nMaxAxisIndex < nLocalMax ) + m_nMaxAxisIndex = nLocalMax; + } } - else - aMaxIndexPerDimension[nDimensionIndex]=nAxisIndex; } -::std::vector< VCoordinateSystem* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) -{ - ::std::vector< VCoordinateSystem* > aRet; - tCoordinateSystemMap::const_iterator aIter; - for( aIter = aCoordinateSystems.begin(); aIter!=aCoordinateSystems.end();++aIter ) +void SeriesPlotterContainer::setScalesFromCooSysToPlotter() +{ + //set scales to plotter to enable them to provide the preferred scene AspectRatio + ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); + const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); + for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) { - if( aIter->second.first != nDimensionIndex ) - continue; - if( aIter->second.second != nAxisIndex ) - continue; - aRet.push_back( aIter->first ); + VSeriesPlotter* pSeriesPlotter = *aPlotterIter; + VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter ); + if(pVCooSys) + { + pSeriesPlotter->setScales( pVCooSys->getExplicitScales(0,0), pVCooSys->getPropertySwapXAndYAxis() ); + sal_Int32 nMaxAxisIndex = pVCooSys->getMaximumAxisIndexByDimension(1);//only additional value axis are relevant for series plotter + for( sal_Int32 nI=1; nI<=nMaxAxisIndex; nI++ ) + pSeriesPlotter->addSecondaryValueScale( pVCooSys->getExplicitScale(1,nI), nI ); + } } - - return aRet; -} -sal_Int32 AxisUsage::getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex ) -{ - sal_Int32 nRet = -1; - std::map< sal_Int32, sal_Int32 >::const_iterator aIter = aMaxIndexPerDimension.find(nDimensionIndex); - if( aIter != aMaxIndexPerDimension.end() ) - nRet = aIter->second; - return nRet; } -class SeriesPlotterContainer -{ -public: - SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList ); - ~SeriesPlotterContainer(); - - void initializeCooSysAndSeriesPlotter( ChartModel& rModel ); - void initAxisUsageList(const Date& rNullDate); - void doAutoScaling( ChartModel& rModel ); - void updateScalesAndIncrementsOnAxes(); - void setScalesFromCooSysToPlotter(); - void setNumberFormatsFromAxes(); - drawing::Direction3D getPreferredAspectRatio(); - - std::vector< VSeriesPlotter* >& getSeriesPlotterList() { return m_aSeriesPlotterList; } - std::vector< VCoordinateSystem* >& getCooSysList() { return m_rVCooSysList; } - std::vector< LegendEntryProvider* > getLegendEntryProviderList(); - - void AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ); - -private: - std::vector< VSeriesPlotter* > m_aSeriesPlotterList; - std::vector< VCoordinateSystem* >& m_rVCooSysList; - ::std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList; - sal_Int32 m_nMaxAxisIndex; - bool m_bChartTypeUsesShiftedCategoryPositionPerDefault; - sal_Int32 m_nDefaultDateNumberFormat; -}; - -SeriesPlotterContainer::SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList ) - : m_rVCooSysList( rVCooSysList ) - , m_nMaxAxisIndex(0) - , m_bChartTypeUsesShiftedCategoryPositionPerDefault(false) - , m_nDefaultDateNumberFormat(0) +void SeriesPlotterContainer::setNumberFormatsFromAxes() { + //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis + ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); + const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); + for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) + { + VSeriesPlotter* pSeriesPlotter = *aPlotterIter; + VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter ); + if(pVCooSys) + { + AxesNumberFormats aAxesNumberFormats; + uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel(); + sal_Int32 nDimensionCount = xCooSys->getDimension(); + for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nDimensionCount; ++nDimensionIndex) + { + const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); + for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex) + { + try + { + Reference< beans::XPropertySet > xAxisProp( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY ); + if( xAxisProp.is()) + { + sal_Int32 nNumberFormatKey(0); + if( xAxisProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey ) + { + aAxesNumberFormats.setFormat( nNumberFormatKey, nDimensionIndex, nAxisIndex ); + } + else if( nDimensionIndex==0 ) + { + //provide a default date format for date axis with own data + aAxesNumberFormats.setFormat( m_nDefaultDateNumberFormat, nDimensionIndex, nAxisIndex ); + } + } + } + catch( const lang::IndexOutOfBoundsException& e ) + { + ASSERT_EXCEPTION( e ); + } + } + } + pSeriesPlotter->setAxesNumberFormats( aAxesNumberFormats ); + } + } } -SeriesPlotterContainer::~SeriesPlotterContainer() +void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes() { - // - remove plotter from coordinatesystems for( size_t nC=0; nC < m_rVCooSysList.size(); nC++) - m_rVCooSysList[nC]->clearMinimumAndMaximumSupplierList(); - // - delete all plotter - ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); - const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); - for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) - delete *aPlotterIter; - m_aSeriesPlotterList.clear(); -} - -std::vector< LegendEntryProvider* > SeriesPlotterContainer::getLegendEntryProviderList() -{ - std::vector< LegendEntryProvider* > aRet( m_aSeriesPlotterList.size() ); - ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); - const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); - sal_Int32 nN = 0; - for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter, nN++ ) - aRet[nN] = *aPlotterIter; - return aRet; + m_rVCooSysList[nC]->updateScalesAndIncrementsOnAxes(); } -void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter( - ChartModel& rChartModel ) +void SeriesPlotterContainer::doAutoScaling( ChartModel& rChartModel ) { - sal_Int32 nDiagramIndex = 0;//todo if more than one diagram is supported - uno::Reference< XDiagram > xDiagram( rChartModel.getFirstDiagram() ); - if( !xDiagram.is()) - return; + //precondition: need a initialized m_aSeriesPlotterList + //precondition: need a initialized m_aAxisUsageList - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject* >( &rChartModel ), uno::UNO_QUERY ); - if( rChartModel.hasInternalDataProvider() && DiagramHelper::isSupportingDateAxis( xDiagram ) ) - m_nDefaultDateNumberFormat=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier ); + ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); + const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); - sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); - if(!nDimensionCount) + //iterate over the main scales first than secondary axis + size_t nC; + sal_Int32 nAxisIndex=0; + for( nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ ) { - //@todo handle mixed dimension - nDimensionCount = 2; - } - bool bSortByXValues = false; - bool bConnectBars = false; - bool bGroupBarsPerAxis = true; - bool bIncludeHiddenCells = true; - sal_Int32 nStartingAngle = 90; - sal_Int32 n3DRelativeHeight = 100; - try - { - uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY_THROW ); - xDiaProp->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= bSortByXValues; - xDiaProp->getPropertyValue( "ConnectBars" ) >>= bConnectBars; - xDiaProp->getPropertyValue( "GroupBarsPerAxis" ) >>= bGroupBarsPerAxis; - xDiaProp->getPropertyValue( "IncludeHiddenCells" ) >>= bIncludeHiddenCells; - xDiaProp->getPropertyValue( "StartingAngle" ) >>= nStartingAngle; + // - first do autoscale for all x and z scales (because they are treated independent) + for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) + { + AxisUsage& rAxisUsage = (*aAxisIter).second; + ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex); + ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex); - if (nDimensionCount == 3) + for( nC=0; nC < aVCooSysList_X.size(); nC++) + aVCooSysList_X[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,0,nAxisIndex); + for( nC=0; nC < aVCooSysList_Z.size(); nC++) + aVCooSysList_Z[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,2,nAxisIndex); + + ExplicitScaleData aExplicitScale; + ExplicitIncrementData aExplicitIncrement; + rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); + + for( nC=0; nC < aVCooSysList_X.size(); nC++) + aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement ); + for( nC=0; nC < aVCooSysList_Z.size(); nC++) + aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement ); + } + + // - second do autoscale for the dependent y scales (the coordinate systems are prepared with x and z scales already ) + for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) { - xDiaProp->getPropertyValue( "3DRelativeHeight" ) >>= n3DRelativeHeight; + AxisUsage& rAxisUsage = (*aAxisIter).second; + ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex); + ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems(1,nAxisIndex); + ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex); + + if(!aVCooSysList_Y.size()) + continue; + + for( nC=0; nC < aVCooSysList_Y.size(); nC++) + aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,1,nAxisIndex); + + ExplicitScaleData aExplicitScale; + ExplicitIncrementData aExplicitIncrement; + rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); + + for( nC=0; nC < aVCooSysList_X.size(); nC++) + aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement ); + for( nC=0; nC < aVCooSysList_Y.size(); nC++) + aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScale, aExplicitIncrement ); + for( nC=0; nC < aVCooSysList_Z.size(); nC++) + aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement ); } } - catch( const uno::Exception & ex ) - { - ASSERT_EXCEPTION( ex ); - } + AdaptScaleOfYAxisWithoutAttachedSeries( rChartModel ); +} - //prepare for autoscaling and shape creation - // - create plotter for charttypes (for each first scale group at each plotter, as they are independent) - // - add series to plotter (thus each charttype can provide minimum and maximum values for autoscaling) - // - add plotter to coordinate systems +void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ) +{ + //issue #i80518# - //iterate through all coordinate systems - uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY ); - OSL_ASSERT( xCooSysContainer.is()); - if( !xCooSysContainer.is()) - return; - uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); - uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); - sal_Int32 nGlobalSeriesIndex = 0;//for automatic symbols - for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS ) - { - uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] ); - VCoordinateSystem* pVCooSys = addCooSysToList(m_rVCooSysList,xCooSys,rChartModel); + ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); + const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); - //iterate through all chart types in the current coordinate system - uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY ); - OSL_ASSERT( xChartTypeContainer.is()); - if( !xChartTypeContainer.is() ) - continue; - uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() ); - for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT ) + for( sal_Int32 nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ ) + { + for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) { - uno::Reference< XChartType > xChartType( aChartTypeList[nT] ); - if(3 == nDimensionCount && xChartType->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE)) + AxisUsage& rAxisUsage = (*aAxisIter).second; + ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems( 1, nAxisIndex ); + if( !aVCooSysList_Y.size() ) + continue; + + uno::Reference< XDiagram > xDiagram( rModel.getFirstDiagram() ); + if( xDiagram.is() ) { - uno::Reference< beans::XPropertySet > xPropertySet( xChartType, uno::UNO_QUERY ); - if (xPropertySet.is()) + bool bSeriesAttachedToThisAxis = false; + sal_Int32 nAttachedAxisIndex = -1; { - try + ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) ); + ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin(); + for( ; aIter != aSeriesVector.end(); ++aIter ) { - sal_Int32 n3DRelativeHeightOldValue(100); - uno::Any aAny = xPropertySet->getPropertyValue( "3DRelativeHeight" ); - aAny >>= n3DRelativeHeightOldValue; - if (n3DRelativeHeightOldValue != n3DRelativeHeight) - xPropertySet->setPropertyValue( "3DRelativeHeight", uno::makeAny(n3DRelativeHeight) ); + sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter ); + if( nAxisIndex == nCurrentIndex ) + { + bSeriesAttachedToThisAxis = true; + break; + } + else if( nAttachedAxisIndex<0 || nAttachedAxisIndex>nCurrentIndex ) + nAttachedAxisIndex=nCurrentIndex; } - catch (const uno::Exception&) { } } - } - - if(nT==0) - m_bChartTypeUsesShiftedCategoryPositionPerDefault = ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( xChartType ); - - bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ); - VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning ); - if( !pPlotter ) - continue; - - m_aSeriesPlotterList.push_back( pPlotter ); - pPlotter->setNumberFormatsSupplier( xNumberFormatsSupplier ); - pPlotter->setColorScheme( xColorScheme ); - if(pVCooSys) - pPlotter->setExplicitCategoriesProvider( pVCooSys->getExplicitCategoriesProvider() ); - sal_Int32 nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( xDiagram, xChartType ); - - if(pVCooSys) - pVCooSys->addMinimumAndMaximumSupplier(pPlotter); - - uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY ); - OSL_ASSERT( xDataSeriesContainer.is()); - if( !xDataSeriesContainer.is() ) - continue; - sal_Int32 zSlot=-1; - sal_Int32 xSlot=-1; - sal_Int32 ySlot=-1; - uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() ); - for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS ) - { - uno::Reference< XDataSeries > xDataSeries( aSeriesList[nS], uno::UNO_QUERY ); - if(!xDataSeries.is()) - continue; - if( !bIncludeHiddenCells && !DataSeriesHelper::hasUnhiddenData(xDataSeries) ) - continue; + if( !bSeriesAttachedToThisAxis && nAttachedAxisIndex >= 0 ) + { + for( size_t nC = 0; nC < aVCooSysList_Y.size(); ++nC ) + { + aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex( rAxisUsage.aScaleAutomatism, 1, nAttachedAxisIndex ); - VDataSeries* pSeries = new VDataSeries( xDataSeries ); + ExplicitScaleData aExplicitScaleSource = aVCooSysList_Y[nC]->getExplicitScale( 1,nAttachedAxisIndex ); + ExplicitIncrementData aExplicitIncrementSource = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAttachedAxisIndex ); - pSeries->setGlobalSeriesIndex(nGlobalSeriesIndex); - nGlobalSeriesIndex++; + ExplicitScaleData aExplicitScaleDest = aVCooSysList_Y[nC]->getExplicitScale( 1,nAxisIndex );; + ExplicitIncrementData aExplicitIncrementDest = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAxisIndex );; - if( bSortByXValues ) - pSeries->doSortByXValues(); + aExplicitScaleDest.Orientation = aExplicitScaleSource.Orientation; + aExplicitScaleDest.Scaling = aExplicitScaleSource.Scaling; + aExplicitScaleDest.AxisType = aExplicitScaleSource.AxisType; - pSeries->setConnectBars( bConnectBars ); - pSeries->setGroupBarsPerAxis( bGroupBarsPerAxis ); - pSeries->setStartingAngle( nStartingAngle ); + aExplicitIncrementDest.BaseValue = aExplicitIncrementSource.BaseValue; - pSeries->setMissingValueTreatment( nMissingValueTreatment ); + ScaleData aScale( rAxisUsage.aScaleAutomatism.getScale() ); + if( !aScale.Minimum.hasValue() ) + { + bool bNewMinOK = true; + double fMax=0.0; + if( aScale.Maximum >>= fMax ) + bNewMinOK = (aExplicitScaleSource.Minimum <= fMax); + if( bNewMinOK ) + aExplicitScaleDest.Minimum = aExplicitScaleSource.Minimum; + } + else + aExplicitIncrementDest.BaseValue = aExplicitScaleDest.Minimum; - OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCS, nT, nS ) ); - pSeries->setParticle(aSeriesParticle); + if( !aScale.Maximum.hasValue() ) + { + bool bNewMaxOK = true; + double fMin=0.0; + if( aScale.Minimum >>= fMin ) + bNewMaxOK = (fMin <= aExplicitScaleSource.Maximum); + if( bNewMaxOK ) + aExplicitScaleDest.Maximum = aExplicitScaleSource.Maximum; + } + if( !aScale.Origin.hasValue() ) + aExplicitScaleDest.Origin = aExplicitScaleSource.Origin; - OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) ); - pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole); + if( !aScale.IncrementData.Distance.hasValue() ) + aExplicitIncrementDest.Distance = aExplicitIncrementSource.Distance; - //ignore secondary axis for charttypes that do not suppoert them - if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX && - !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, 1 ) ) - { - pSeries->setAttachedAxisIndex(MAIN_AXIS_INDEX); - } + bool bAutoMinorInterval = true; + if( aScale.IncrementData.SubIncrements.getLength() ) + bAutoMinorInterval = !( aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ); + if( bAutoMinorInterval ) + { + if( !aExplicitIncrementDest.SubIncrements.empty() && !aExplicitIncrementSource.SubIncrements.empty() ) + aExplicitIncrementDest.SubIncrements[0].IntervalCount = + aExplicitIncrementSource.SubIncrements[0].IntervalCount; + } - StackingDirection eDirection = pSeries->getStackingDirection(); - switch(eDirection) - { - case StackingDirection_NO_STACKING: - xSlot++; ySlot=-1; - if(zSlot<0) - zSlot=0; - break; - case StackingDirection_Y_STACKING: - ySlot++; - if(xSlot<0) - xSlot=0; - if(zSlot<0) - zSlot=0; - break; - case StackingDirection_Z_STACKING: - zSlot++; xSlot=-1; ySlot=-1; - break; - default: - // UNO enums have one additional auto-generated case - break; + aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScaleDest, aExplicitIncrementDest ); + } } - pPlotter->addSeries( pSeries, zSlot, xSlot, ySlot ); } } } - //transport seriesnames to the coordinatesystems if needed - if( !m_aSeriesPlotterList.empty() ) + if( AxisHelper::isAxisPositioningEnabled() ) { - uno::Sequence< OUString > aSeriesNames; - bool bSeriesNamesInitialized = false; - for( size_t nC=0; nC < m_rVCooSysList.size(); nC++) + //correct origin for y main axis (the origin is where the other main axis crosses) + sal_Int32 nAxisIndex=0; + sal_Int32 nDimensionIndex=1; + for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) { - VCoordinateSystem* pVCooSys = m_rVCooSysList[nC]; - if(!pVCooSys) - continue; - if( pVCooSys->needSeriesNamesForAxis() ) + AxisUsage& rAxisUsage = (*aAxisIter).second; + ::std::vector< VCoordinateSystem* > aVCooSysList = rAxisUsage.getCoordinateSystems(nDimensionIndex,nAxisIndex); + size_t nC; + for( nC=0; nC < aVCooSysList.size(); nC++) { - if(!bSeriesNamesInitialized) + ExplicitScaleData aExplicitScale( aVCooSysList[nC]->getExplicitScale( nDimensionIndex, nAxisIndex ) ); + ExplicitIncrementData aExplicitIncrement( aVCooSysList[nC]->getExplicitIncrement( nDimensionIndex, nAxisIndex ) ); + + Reference< chart2::XCoordinateSystem > xCooSys( aVCooSysList[nC]->getModel() ); + Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) ); + Reference< beans::XPropertySet > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis, xCooSys ), uno::UNO_QUERY ); + + ::com::sun::star::chart::ChartAxisPosition eCrossingMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO ); + if( xCrossingMainAxis.is() ) { - VSeriesPlotter* pSeriesPlotter = m_aSeriesPlotterList[0]; - if( pSeriesPlotter ) - aSeriesNames = pSeriesPlotter->getSeriesNames(); - bSeriesNamesInitialized = true; + xCrossingMainAxis->getPropertyValue("CrossoverPosition") >>= eCrossingMainAxisPos; + if( ::com::sun::star::chart::ChartAxisPosition_VALUE == eCrossingMainAxisPos ) + { + double fValue = 0.0; + xCrossingMainAxis->getPropertyValue("CrossoverValue") >>= fValue; + aExplicitScale.Origin = fValue; + } + else if( ::com::sun::star::chart::ChartAxisPosition_ZERO == eCrossingMainAxisPos ) + aExplicitScale.Origin = 0.0; + else if( ::com::sun::star::chart::ChartAxisPosition_START == eCrossingMainAxisPos ) + aExplicitScale.Origin = aExplicitScale.Minimum; + else if( ::com::sun::star::chart::ChartAxisPosition_END == eCrossingMainAxisPos ) + aExplicitScale.Origin = aExplicitScale.Maximum; } - pVCooSys->setSeriesNamesForAxis( aSeriesNames ); + + aVCooSysList[nC]->setExplicitScaleAndIncrement( nDimensionIndex, nAxisIndex, aExplicitScale, aExplicitIncrement ); } } } } -void SeriesPlotterContainer::initAxisUsageList(const Date& rNullDate) +drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio() { - m_aAxisUsageList.clear(); - size_t nC; - for( nC=0; nC < m_rVCooSysList.size(); nC++) + drawing::Direction3D aPreferredAspectRatio(1.0,1.0,1.0); + + sal_Int32 nPlotterCount=0; + //get a list of all preferred aspect ratios and combine them + //first with special demands wins (less or equal zero <-> arbitrary) + double fx, fy, fz; + fx = fy = fz = -1.0; + ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); + const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); + for( aPlotterIter = m_aSeriesPlotterList.begin(), nPlotterCount=0 + ; aPlotterIter != aPlotterEnd; ++aPlotterIter, ++nPlotterCount ) { - VCoordinateSystem* pVCooSys = m_rVCooSysList[nC]; - for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++) + drawing::Direction3D aSingleRatio( (*aPlotterIter)->getPreferredDiagramAspectRatio() ); + if( fx<0 && aSingleRatio.DirectionX>0 ) + fx = aSingleRatio.DirectionX; + + if( fy<0 && aSingleRatio.DirectionY>0 ) { - uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel(); - sal_Int32 nDimensionCount = xCooSys->getDimension(); - if( nDimensionIndex >= nDimensionCount ) - continue; - bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), nDimensionCount, nDimensionIndex ); - const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); - for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex) - { - uno::Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) ); - OSL_ASSERT( xAxis.is()); - if( xAxis.is()) - { - if(m_aAxisUsageList.find(xAxis)==m_aAxisUsageList.end()) - { - chart2::ScaleData aSourceScale = xAxis->getScaleData(); - ExplicitCategoriesProvider* pExplicitCategoriesProvider = pVCooSys->getExplicitCategoriesProvider(); - if( nDimensionIndex==0 ) - AxisHelper::checkDateAxis( aSourceScale, pExplicitCategoriesProvider, bChartTypeAllowsDateAxis ); - if( (aSourceScale.AxisType == AxisType::CATEGORY && m_bChartTypeUsesShiftedCategoryPositionPerDefault) - || (aSourceScale.AxisType==AxisType::CATEGORY && pExplicitCategoriesProvider && pExplicitCategoriesProvider->hasComplexCategories() ) - || aSourceScale.AxisType == AxisType::DATE - || aSourceScale.AxisType == AxisType::SERIES ) - aSourceScale.ShiftedCategoryPosition = true; - else - aSourceScale.ShiftedCategoryPosition = false; - m_aAxisUsageList[xAxis].aScaleAutomatism = ScaleAutomatism(aSourceScale,rNullDate); - } - AxisUsage& rAxisUsage = m_aAxisUsageList[xAxis]; - rAxisUsage.addCoordinateSystem(pVCooSys,nDimensionIndex,nAxisIndex); - } - } + if( fx>0 && aSingleRatio.DirectionX>0 ) + fy = fx*aSingleRatio.DirectionY/aSingleRatio.DirectionX; + else if( fz>0 && aSingleRatio.DirectionZ>0 ) + fy = fz*aSingleRatio.DirectionY/aSingleRatio.DirectionZ; + else + fy = aSingleRatio.DirectionY; } - } - ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); - const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); - - //init m_nMaxAxisIndex - m_nMaxAxisIndex = 0; - for(sal_Int32 nDimensionIndex=0; nDimensionIndex<3; nDimensionIndex++) - { - for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) + if( fz<0 && aSingleRatio.DirectionZ>0 ) { - sal_Int32 nLocalMax = aAxisIter->second.getMaxAxisIndexForDimension( nDimensionIndex ); - if( m_nMaxAxisIndex < nLocalMax ) - m_nMaxAxisIndex = nLocalMax; + if( fx>0 && aSingleRatio.DirectionX>0 ) + fz = fx*aSingleRatio.DirectionZ/aSingleRatio.DirectionX; + else if( fy>0 && aSingleRatio.DirectionY>0 ) + fz = fy*aSingleRatio.DirectionZ/aSingleRatio.DirectionY; + else + fz = aSingleRatio.DirectionZ; } + + if( fx>0 && fy>0 && fz>0 ) + break; } + aPreferredAspectRatio = drawing::Direction3D(fx, fy, fz); + return aPreferredAspectRatio; +} + +} + +struct CreateShapeParam2D +{ + css::awt::Rectangle maRemainingSpace; + + boost::shared_ptr<SeriesPlotterContainer> mpSeriesPlotterContainer; + + boost::shared_ptr<VTitle> mpVTitleX; + boost::shared_ptr<VTitle> mpVTitleY; + boost::shared_ptr<VTitle> mpVTitleZ; + + boost::shared_ptr<VTitle> mpVTitleSecondX; + boost::shared_ptr<VTitle> mpVTitleSecondY; + + css::uno::Reference<css::drawing::XShape> mxMarkHandles; + css::uno::Reference<css::drawing::XShape> mxPlotAreaWithAxes; + + css::uno::Reference<css::drawing::XShapes> mxDiagramWithAxesShapes; + + bool mbAutoPosTitleX; + bool mbAutoPosTitleY; + bool mbAutoPosTitleZ; + + bool mbAutoPosSecondTitleX; + bool mbAutoPosSecondTitleY; + + bool mbUseFixedInnerSize; + + CreateShapeParam2D() : + mbAutoPosTitleX(true), + mbAutoPosTitleY(true), + mbAutoPosTitleZ(true), + mbAutoPosSecondTitleX(true), + mbAutoPosSecondTitleY(true), + mbUseFixedInnerSize(false) {} +}; + +class GL2DRenderer : public IRenderer +{ +public: + GL2DRenderer(ChartView* pView); + virtual ~GL2DRenderer(); + + virtual void update() SAL_OVERRIDE; + virtual void clickedAt(const Point& rPos, sal_uInt16 nButton) SAL_OVERRIDE; + virtual void mouseDragMove(const Point& rBegin, const Point& rEnd, sal_uInt16 nButton) SAL_OVERRIDE; + virtual void scroll(long nDelta) SAL_OVERRIDE; + virtual void contextDestroyed() SAL_OVERRIDE; + + const OpenGLWindow* getOpenGLWindow() const; + void updateOpenGLWindow(); +private: + ChartView* mpView; + bool mbContextDestroyed; + OpenGLWindow* mpWindow; +}; + +GL2DRenderer::GL2DRenderer(ChartView* pView): + mpView(pView), + mbContextDestroyed(false), + mpWindow(mpView->mrChartModel.getOpenGLWindow()) +{ +} + +GL2DRenderer::~GL2DRenderer() +{ + if(!mbContextDestroyed && mpWindow) + mpWindow->setRenderer(NULL); +} + +void GL2DRenderer::update() +{ + mpView->update(); + mpView->render(); } -void SeriesPlotterContainer::setScalesFromCooSysToPlotter() +void GL2DRenderer::clickedAt(const Point&, sal_uInt16 ) { - //set scales to plotter to enable them to provide the preferred scene AspectRatio - ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); - const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); - for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) - { - VSeriesPlotter* pSeriesPlotter = *aPlotterIter; - VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter ); - if(pVCooSys) - { - pSeriesPlotter->setScales( pVCooSys->getExplicitScales(0,0), pVCooSys->getPropertySwapXAndYAxis() ); - sal_Int32 nMaxAxisIndex = pVCooSys->getMaximumAxisIndexByDimension(1);//only additional value axis are relevant for series plotter - for( sal_Int32 nI=1; nI<=nMaxAxisIndex; nI++ ) - pSeriesPlotter->addSecondaryValueScale( pVCooSys->getExplicitScale(1,nI), nI ); - } - } } -void SeriesPlotterContainer::setNumberFormatsFromAxes() +void GL2DRenderer::mouseDragMove(const Point& , const Point& , sal_uInt16 ) { - //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis - ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); - const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); - for( aPlotterIter = m_aSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; ++aPlotterIter ) - { - VSeriesPlotter* pSeriesPlotter = *aPlotterIter; - VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter ); - if(pVCooSys) - { - AxesNumberFormats aAxesNumberFormats; - uno::Reference< XCoordinateSystem > xCooSys = pVCooSys->getModel(); - sal_Int32 nDimensionCount = xCooSys->getDimension(); - for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nDimensionCount; ++nDimensionIndex) - { - const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); - for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex) - { - try - { - Reference< beans::XPropertySet > xAxisProp( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY ); - if( xAxisProp.is()) - { - sal_Int32 nNumberFormatKey(0); - if( xAxisProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey ) - { - aAxesNumberFormats.setFormat( nNumberFormatKey, nDimensionIndex, nAxisIndex ); - } - else if( nDimensionIndex==0 ) - { - //provide a default date format for date axis with own data - aAxesNumberFormats.setFormat( m_nDefaultDateNumberFormat, nDimensionIndex, nAxisIndex ); - } - } - } - catch( const lang::IndexOutOfBoundsException& e ) - { - ASSERT_EXCEPTION( e ); - } - } - } - pSeriesPlotter->setAxesNumberFormats( aAxesNumberFormats ); - } - } } -void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes() +void GL2DRenderer::scroll(long ) { - for( size_t nC=0; nC < m_rVCooSysList.size(); nC++) - m_rVCooSysList[nC]->updateScalesAndIncrementsOnAxes(); } -void SeriesPlotterContainer::doAutoScaling( ChartModel& rChartModel ) +void GL2DRenderer::contextDestroyed() { - //precondition: need a initialized m_aSeriesPlotterList - //precondition: need a initialized m_aAxisUsageList + mbContextDestroyed = true; +} - ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); - const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); +const OpenGLWindow* GL2DRenderer::getOpenGLWindow() const +{ + return mpWindow; +} - //iterate over the main scales first than secondary axis - size_t nC; - sal_Int32 nAxisIndex=0; - for( nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ ) - { +void GL2DRenderer::updateOpenGLWindow() +{ + if(mbContextDestroyed) + return; - // - first do autoscale for all x and z scales (because they are treated independent) - for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) + OpenGLWindow* pWindow = mpView->mrChartModel.getOpenGLWindow(); + if(pWindow != mpWindow) + { + if(mpWindow) { - AxisUsage& rAxisUsage = (*aAxisIter).second; - ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex); - ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex); - - for( nC=0; nC < aVCooSysList_X.size(); nC++) - aVCooSysList_X[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,0,nAxisIndex); - for( nC=0; nC < aVCooSysList_Z.size(); nC++) - aVCooSysList_Z[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,2,nAxisIndex); - - ExplicitScaleData aExplicitScale; - ExplicitIncrementData aExplicitIncrement; - rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); - - for( nC=0; nC < aVCooSysList_X.size(); nC++) - aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement ); - for( nC=0; nC < aVCooSysList_Z.size(); nC++) - aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement ); + mpWindow->setRenderer(NULL); } - // - second do autoscale for the dependent y scales (the coordinate systems are prepared with x and z scales already ) - for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) + if(pWindow) { - AxisUsage& rAxisUsage = (*aAxisIter).second; - ::std::vector< VCoordinateSystem* > aVCooSysList_X = rAxisUsage.getCoordinateSystems(0,nAxisIndex); - ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems(1,nAxisIndex); - ::std::vector< VCoordinateSystem* > aVCooSysList_Z = rAxisUsage.getCoordinateSystems(2,nAxisIndex); + pWindow->setRenderer(this); + } + } + mpWindow = pWindow; +} - if(!aVCooSysList_Y.size()) - continue; +const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId() +{ + return theExplicitValueProviderUnoTunnelId::get().getSeq(); +} - for( nC=0; nC < aVCooSysList_Y.size(); nC++) - aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex(rAxisUsage.aScaleAutomatism,1,nAxisIndex); +ExplicitValueProvider* ExplicitValueProvider::getExplicitValueProvider( + const Reference< uno::XInterface >& xChartView ) +{ + ExplicitValueProvider* pExplicitValueProvider=0; - ExplicitScaleData aExplicitScale; - ExplicitIncrementData aExplicitIncrement; - rAxisUsage.aScaleAutomatism.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); + Reference< lang::XUnoTunnel > xTunnel( xChartView, uno::UNO_QUERY ); + if( xTunnel.is() ) + { + pExplicitValueProvider = reinterpret_cast<ExplicitValueProvider*>(xTunnel->getSomething( + ExplicitValueProvider::getUnoTunnelId() )); + } + return pExplicitValueProvider; +} - for( nC=0; nC < aVCooSysList_X.size(); nC++) - aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement ); - for( nC=0; nC < aVCooSysList_Y.size(); nC++) - aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScale, aExplicitIncrement ); - for( nC=0; nC < aVCooSysList_Z.size(); nC++) - aVCooSysList_Z[nC]->setExplicitScaleAndIncrement( 2, nAxisIndex, aExplicitScale, aExplicitIncrement ); - } +ChartView::ChartView( + uno::Reference<uno::XComponentContext> const & xContext, + ChartModel& rModel) + : m_aMutex() + , m_xCC(xContext) + , mrChartModel(rModel) + , m_xShapeFactory() + , m_xDrawPage() + , m_pDrawModelWrapper() + , m_aListenerContainer( m_aMutex ) + , m_bViewDirty(true) + , m_bInViewUpdate(false) + , m_bViewUpdatePending(false) + , m_bRefreshAddIn(true) + , m_aPageResolution(1000,1000) + , m_bPointsWereSkipped(false) + , m_nScaleXNumerator(1) + , m_nScaleXDenominator(1) + , m_nScaleYNumerator(1) + , m_nScaleYDenominator(1) + , m_bSdrViewIsInEditMode(false) + , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0) + , mp2DRenderer(new GL2DRenderer(this)) +{ + init(); +} + +void ChartView::init() +{ + if( !m_pDrawModelWrapper.get() ) + { + SolarMutexGuard aSolarGuard; + m_pDrawModelWrapper = ::boost::shared_ptr< DrawModelWrapper >( new DrawModelWrapper( m_xCC ) ); + m_xShapeFactory = m_pDrawModelWrapper->getShapeFactory(); + m_xDrawPage = m_pDrawModelWrapper->getMainDrawPage(); + StartListening( m_pDrawModelWrapper->getSdrModel(), false /*bPreventDups*/ ); } - AdaptScaleOfYAxisWithoutAttachedSeries( rChartModel ); } -void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ) +void SAL_CALL ChartView::initialize( const uno::Sequence< uno::Any >& ) + throw ( uno::Exception, uno::RuntimeException, std::exception) { - //issue #i80518# + init(); +} - ::std::map< uno::Reference< XAxis >, AxisUsage >::iterator aAxisIter = m_aAxisUsageList.begin(); - const ::std::map< uno::Reference< XAxis >, AxisUsage >::const_iterator aAxisEndIter = m_aAxisUsageList.end(); +ChartView::~ChartView() +{ + maTimeBased.maTimer.Stop(); + // #i120831#. In ChartView::initialize(), m_xShapeFactory is created from SdrModel::getUnoModel() and indirectly + // from SfxBaseModel, it needs call dispose() to make sure SfxBaseModel object is freed correctly. + uno::Reference< lang::XComponent > xComp( m_xShapeFactory, uno::UNO_QUERY); + if ( xComp.is() ) + xComp->dispose(); - for( sal_Int32 nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ ) + if( m_pDrawModelWrapper.get() ) { - for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) - { - AxisUsage& rAxisUsage = (*aAxisIter).second; - ::std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems( 1, nAxisIndex ); - if( !aVCooSysList_Y.size() ) - continue; - - uno::Reference< XDiagram > xDiagram( rModel.getFirstDiagram() ); - if( xDiagram.is() ) - { - bool bSeriesAttachedToThisAxis = false; - sal_Int32 nAttachedAxisIndex = -1; - { - ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) ); - ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin(); - for( ; aIter != aSeriesVector.end(); ++aIter ) - { - sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter ); - if( nAxisIndex == nCurrentIndex ) - { - bSeriesAttachedToThisAxis = true; - break; - } - else if( nAttachedAxisIndex<0 || nAttachedAxisIndex>nCurrentIndex ) - nAttachedAxisIndex=nCurrentIndex; - } - } + EndListening( m_pDrawModelWrapper->getSdrModel(), false /*bAllDups*/ ); + SolarMutexGuard aSolarGuard; + m_pDrawModelWrapper.reset(); + } + m_xDrawPage = NULL; + impl_deleteCoordinateSystems(); +} - if( !bSeriesAttachedToThisAxis && nAttachedAxisIndex >= 0 ) - { - for( size_t nC = 0; nC < aVCooSysList_Y.size(); ++nC ) - { - aVCooSysList_Y[nC]->prepareScaleAutomatismForDimensionAndIndex( rAxisUsage.aScaleAutomatism, 1, nAttachedAxisIndex ); +void ChartView::impl_deleteCoordinateSystems() +{ + //delete all coordinate systems + ::std::vector< VCoordinateSystem* > aVectorToDeleteObjects; + ::std::swap( aVectorToDeleteObjects, m_aVCooSysList );//#i109770# + ::std::vector< VCoordinateSystem* >::const_iterator aIter = aVectorToDeleteObjects.begin(); + const ::std::vector< VCoordinateSystem* >::const_iterator aEnd = aVectorToDeleteObjects.end(); + for( ; aIter != aEnd; ++aIter ) + { + delete *aIter; + } + aVectorToDeleteObjects.clear(); +} - ExplicitScaleData aExplicitScaleSource = aVCooSysList_Y[nC]->getExplicitScale( 1,nAttachedAxisIndex ); - ExplicitIncrementData aExplicitIncrementSource = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAttachedAxisIndex ); +// datatransfer::XTransferable +namespace +{ +const OUString lcl_aGDIMetaFileMIMEType( + "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ); +const OUString lcl_aGDIMetaFileMIMETypeHighContrast( + "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ); +} // anonymous namespace - ExplicitScaleData aExplicitScaleDest = aVCooSysList_Y[nC]->getExplicitScale( 1,nAxisIndex );; - ExplicitIncrementData aExplicitIncrementDest = aVCooSysList_Y[nC]->getExplicitIncrement( 1,nAxisIndex );; +void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStream + , bool bUseHighContrast ) +{ + if( !m_xDrawPage.is() ) + return; - aExplicitScaleDest.Orientation = aExplicitScaleSource.Orientation; - aExplicitScaleDest.Scaling = aExplicitScaleSource.Scaling; - aExplicitScaleDest.AxisType = aExplicitScaleSource.AxisType; + // creating the graphic exporter + uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( m_xCC ); - aExplicitIncrementDest.BaseValue = aExplicitIncrementSource.BaseValue; + uno::Sequence< beans::PropertyValue > aProps(3); + aProps[0].Name = "FilterName"; + aProps[0].Value <<= OUString("SVM"); - ScaleData aScale( rAxisUsage.aScaleAutomatism.getScale() ); - if( !aScale.Minimum.hasValue() ) - { - bool bNewMinOK = true; - double fMax=0.0; - if( aScale.Maximum >>= fMax ) - bNewMinOK = (aExplicitScaleSource.Minimum <= fMax); - if( bNewMinOK ) - aExplicitScaleDest.Minimum = aExplicitScaleSource.Minimum; - } - else - aExplicitIncrementDest.BaseValue = aExplicitScaleDest.Minimum; + aProps[1].Name = "OutputStream"; + aProps[1].Value <<= xOutStream; - if( !aScale.Maximum.hasValue() ) - { - bool bNewMaxOK = true; - double fMin=0.0; - if( aScale.Minimum >>= fMin ) - bNewMaxOK = (fMin <= aExplicitScaleSource.Maximum); - if( bNewMaxOK ) - aExplicitScaleDest.Maximum = aExplicitScaleSource.Maximum; - } - if( !aScale.Origin.hasValue() ) - aExplicitScaleDest.Origin = aExplicitScaleSource.Origin; + uno::Sequence< beans::PropertyValue > aFilterData(4); + aFilterData[0].Name = "ExportOnlyBackground"; + aFilterData[0].Value <<= sal_False; + aFilterData[1].Name = "HighContrast"; + aFilterData[1].Value <<= bUseHighContrast; - if( !aScale.IncrementData.Distance.hasValue() ) - aExplicitIncrementDest.Distance = aExplicitIncrementSource.Distance; + aFilterData[2].Name = "Version"; + const sal_Int32 nVersion = SOFFICE_FILEFORMAT_50; + aFilterData[2].Value <<= nVersion; - bool bAutoMinorInterval = true; - if( aScale.IncrementData.SubIncrements.getLength() ) - bAutoMinorInterval = !( aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ); - if( bAutoMinorInterval ) - { - if( !aExplicitIncrementDest.SubIncrements.empty() && !aExplicitIncrementSource.SubIncrements.empty() ) - aExplicitIncrementDest.SubIncrements[0].IntervalCount = - aExplicitIncrementSource.SubIncrements[0].IntervalCount; - } + aFilterData[3].Name = "CurrentPage"; + aFilterData[3].Value <<= uno::Reference< uno::XInterface >( m_xDrawPage, uno::UNO_QUERY ); - aVCooSysList_Y[nC]->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScaleDest, aExplicitIncrementDest ); - } - } - } - } + //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100% + { + aFilterData.realloc( aFilterData.getLength()+4 ); + aFilterData[4].Name = "ScaleXNumerator"; + aFilterData[4].Value = uno::makeAny( m_nScaleXNumerator ); + aFilterData[5].Name = "ScaleXDenominator"; + aFilterData[5].Value = uno::makeAny( m_nScaleXDenominator ); + aFilterData[6].Name = "ScaleYNumerator"; + aFilterData[6].Value = uno::makeAny( m_nScaleYNumerator ); + aFilterData[7].Name = "ScaleYDenominator"; + aFilterData[7].Value = uno::makeAny( m_nScaleYDenominator ); } - if( AxisHelper::isAxisPositioningEnabled() ) + aProps[2].Name = "FilterData"; + aProps[2].Value <<= aFilterData; + + xExporter->setSourceDocument( uno::Reference< lang::XComponent >( m_xDrawPage, uno::UNO_QUERY) ); + if( xExporter->filter( aProps ) ) { - //correct origin for y main axis (the origin is where the other main axis crosses) - sal_Int32 nAxisIndex=0; - sal_Int32 nDimensionIndex=1; - for( aAxisIter = m_aAxisUsageList.begin(); aAxisIter != aAxisEndIter; ++aAxisIter ) - { - AxisUsage& rAxisUsage = (*aAxisIter).second; - ::std::vector< VCoordinateSystem* > aVCooSysList = rAxisUsage.getCoordinateSystems(nDimensionIndex,nAxisIndex); - size_t nC; - for( nC=0; nC < aVCooSysList.size(); nC++) - { - ExplicitScaleData aExplicitScale( aVCooSysList[nC]->getExplicitScale( nDimensionIndex, nAxisIndex ) ); - ExplicitIncrementData aExplicitIncrement( aVCooSysList[nC]->getExplicitIncrement( nDimensionIndex, nAxisIndex ) ); + xOutStream->flush(); + xOutStream->closeOutput(); + uno::Reference< io::XSeekable > xSeekable( xOutStream, uno::UNO_QUERY ); + if( xSeekable.is() ) + xSeekable->seek(0); + } +} - Reference< chart2::XCoordinateSystem > xCooSys( aVCooSysList[nC]->getModel() ); - Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) ); - Reference< beans::XPropertySet > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis, xCooSys ), uno::UNO_QUERY ); +uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aFlavor ) + throw (datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception) +{ + bool bHighContrastMetaFile( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast)); + uno::Any aRet; + if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) ) + return aRet; - ::com::sun::star::chart::ChartAxisPosition eCrossingMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO ); - if( xCrossingMainAxis.is() ) - { - xCrossingMainAxis->getPropertyValue("CrossoverPosition") >>= eCrossingMainAxisPos; - if( ::com::sun::star::chart::ChartAxisPosition_VALUE == eCrossingMainAxisPos ) - { - double fValue = 0.0; - xCrossingMainAxis->getPropertyValue("CrossoverValue") >>= fValue; - aExplicitScale.Origin = fValue; - } - else if( ::com::sun::star::chart::ChartAxisPosition_ZERO == eCrossingMainAxisPos ) - aExplicitScale.Origin = 0.0; - else if( ::com::sun::star::chart::ChartAxisPosition_START == eCrossingMainAxisPos ) - aExplicitScale.Origin = aExplicitScale.Minimum; - else if( ::com::sun::star::chart::ChartAxisPosition_END == eCrossingMainAxisPos ) - aExplicitScale.Origin = aExplicitScale.Maximum; - } + update(); - aVCooSysList[nC]->setExplicitScaleAndIncrement( nDimensionIndex, nAxisIndex, aExplicitScale, aExplicitIncrement ); - } + SvMemoryStream aStream( 1024, 1024 ); + utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream ); + + uno::Reference< io::XOutputStream > xOutStream( pStreamWrapper ); + uno::Reference< io::XInputStream > xInStream( pStreamWrapper ); + uno::Reference< io::XSeekable > xSeekable( pStreamWrapper ); + + if( xOutStream.is() ) + { + this->getMetaFile( xOutStream, bHighContrastMetaFile ); + + if( xInStream.is() && xSeekable.is() ) + { + xSeekable->seek(0); + sal_Int32 nBytesToRead = xInStream->available(); + uno::Sequence< sal_Int8 > aSeq( nBytesToRead ); + xInStream->readBytes( aSeq, nBytesToRead); + aRet <<= aSeq; + xInStream->closeInput(); } } + + return aRet; } +uno::Sequence< datatransfer::DataFlavor > SAL_CALL ChartView::getTransferDataFlavors() + throw (uno::RuntimeException, std::exception) +{ + uno::Sequence< datatransfer::DataFlavor > aRet(2); -drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio() + aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType, + "GDIMetaFile", + ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); + aRet[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast, + "GDIMetaFile", + ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); + + return aRet; +} +sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor ) + throw (uno::RuntimeException, std::exception) { - drawing::Direction3D aPreferredAspectRatio(1.0,1.0,1.0); + return ( aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType) || + aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMETypeHighContrast) ); +} - sal_Int32 nPlotterCount=0; - //get a list of all preferred aspect ratios and combine them - //first with special demands wins (less or equal zero <-> arbitrary) - double fx, fy, fz; - fx = fy = fz = -1.0; - ::std::vector< VSeriesPlotter* >::const_iterator aPlotterIter = m_aSeriesPlotterList.begin(); - const ::std::vector< VSeriesPlotter* >::const_iterator aPlotterEnd = m_aSeriesPlotterList.end(); - for( aPlotterIter = m_aSeriesPlotterList.begin(), nPlotterCount=0 - ; aPlotterIter != aPlotterEnd; ++aPlotterIter, ++nPlotterCount ) +// ____ XUnoTunnel ___ +::sal_Int64 SAL_CALL ChartView::getSomething( const uno::Sequence< ::sal_Int8 >& aIdentifier ) + throw( uno::RuntimeException, std::exception) +{ + if( aIdentifier.getLength() == 16 && 0 == memcmp( ExplicitValueProvider::getUnoTunnelId().getConstArray(), + aIdentifier.getConstArray(), 16 ) ) { - drawing::Direction3D aSingleRatio( (*aPlotterIter)->getPreferredDiagramAspectRatio() ); - if( fx<0 && aSingleRatio.DirectionX>0 ) - fx = aSingleRatio.DirectionX; + ExplicitValueProvider* pProvider = this; + return reinterpret_cast<sal_Int64>(pProvider); + } + return 0; +} - if( fy<0 && aSingleRatio.DirectionY>0 ) - { - if( fx>0 && aSingleRatio.DirectionX>0 ) - fy = fx*aSingleRatio.DirectionY/aSingleRatio.DirectionX; - else if( fz>0 && aSingleRatio.DirectionZ>0 ) - fy = fz*aSingleRatio.DirectionY/aSingleRatio.DirectionZ; - else - fy = aSingleRatio.DirectionY; - } +// lang::XServiceInfo - if( fz<0 && aSingleRatio.DirectionZ>0 ) - { - if( fx>0 && aSingleRatio.DirectionX>0 ) - fz = fx*aSingleRatio.DirectionZ/aSingleRatio.DirectionX; - else if( fy>0 && aSingleRatio.DirectionY>0 ) - fz = fy*aSingleRatio.DirectionZ/aSingleRatio.DirectionY; - else - fz = aSingleRatio.DirectionZ; - } +APPHELPER_XSERVICEINFO_IMPL(ChartView,CHART_VIEW_SERVICE_IMPLEMENTATION_NAME) - if( fx>0 && fy>0 && fz>0 ) - break; - } - aPreferredAspectRatio = drawing::Direction3D(fx, fy, fz); - return aPreferredAspectRatio; + uno::Sequence< OUString > ChartView +::getSupportedServiceNames_Static() +{ + uno::Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[ 0 ] = CHART_VIEW_SERVICE_NAME; + return aSNS; +} + +::basegfx::B3DHomMatrix createTransformationSceneToScreen( + const ::basegfx::B2IRectangle& rDiagramRectangleWithoutAxes ) +{ + ::basegfx::B3DHomMatrix aM; + aM.scale(double(rDiagramRectangleWithoutAxes.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME + , -double(rDiagramRectangleWithoutAxes.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 ); + aM.translate(double(rDiagramRectangleWithoutAxes.getMinX()) + , double(rDiagramRectangleWithoutAxes.getMinY()+rDiagramRectangleWithoutAxes.getHeight()-1), 0); + return aM; } namespace @@ -1432,9 +1436,7 @@ sal_Int16 lcl_getDefaultWritingModeFromPool( const boost::shared_ptr<DrawModelWr } //end anonymous namespace -awt::Rectangle ChartView::impl_createDiagramAndContent( - SeriesPlotterContainer& rSeriesPlotterContainer, - const CreateShapeParam2D& rParam, const awt::Size& rPageSize ) ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits