diff options
Diffstat (limited to 'chart2/source/view/main/ChartView.cxx')
-rw-r--r-- | chart2/source/view/main/ChartView.cxx | 1791 |
1 files changed, 371 insertions, 1420 deletions
diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index a70738adb906..d01a877040b2 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -19,17 +19,24 @@ #include <config_feature_desktop.h> +#include "SeriesPlotterContainer.hxx" + #include <ChartView.hxx> #include <chartview/DrawModelWrapper.hxx> +#include <Diagram.hxx> +#include <ChartType.hxx> +#include <DataSeries.hxx> #include <NumberFormatterWrapper.hxx> #include <VDiagram.hxx> #include "VTitle.hxx" #include "VButton.hxx" #include <ShapeFactory.hxx> +#include <BaseCoordinateSystem.hxx> #include <VCoordinateSystem.hxx> #include <VSeriesPlotter.hxx> #include <CommonConverters.hxx> #include <TitleHelper.hxx> +#include <Legend.hxx> #include <LegendHelper.hxx> #include "VLegend.hxx" #include <PropertyMapper.hxx> @@ -40,17 +47,22 @@ #include <DiagramHelper.hxx> #include <RelativePositionHelper.hxx> #include <servicenames.hxx> +#include <Axis.hxx> #include <AxisHelper.hxx> +#include "AxisUsage.hxx" #include <AxisIndexDefines.hxx> #include <BaseGFXHelper.hxx> #include <DataSeriesHelper.hxx> #include <DateHelper.hxx> #include <ExplicitCategoriesProvider.hxx> #include <defines.hxx> +#include <comphelper/dumpxmltostring.hxx> #include <unonames.hxx> #include <editeng/frmdiritem.hxx> +#include <editeng/eeitem.hxx> #include <tools/globname.hxx> #include <comphelper/fileformat.h> +#include <comphelper/propertyvalue.hxx> #include <comphelper/scopeguard.hxx> #include <comphelper/servicehelper.hxx> #include <cppuhelper/supportsservice.hxx> @@ -58,29 +70,25 @@ #include <unotools/streamwrap.hxx> #include <svx/svdpage.hxx> #include <svx/unopage.hxx> -#include <svx/unoshape.hxx> +#include <utility> #include <vcl/svapp.hxx> #include <osl/mutex.hxx> #include <svx/unofill.hxx> #include <drawinglayer/XShapeDumper.hxx> +#include <sfx2/objsh.hxx> #include <time.h> -#include <com/sun/star/awt/Size.hpp> #include <com/sun/star/awt/Point.hpp> #include <com/sun/star/chart/ChartAxisPosition.hpp> #include <com/sun/star/chart/TimeUnit.hpp> #include <com/sun/star/chart2/AxisType.hpp> #include <com/sun/star/chart2/StackingDirection.hpp> -#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> -#include <com/sun/star/chart2/XChartTypeContainer.hpp> -#include <com/sun/star/chart2/XDataSeriesContainer.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> #include <com/sun/star/chart2/RelativeSize.hpp> #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp> #include <com/sun/star/chart2/data/PivotTableFieldEntry.hpp> #include <com/sun/star/drawing/GraphicExportFilter.hpp> -#include <com/sun/star/drawing/XShapeGroup.hpp> #include <com/sun/star/embed/Aspects.hpp> #include <com/sun/star/io/XSeekable.hpp> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> @@ -92,910 +100,26 @@ #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> #include <svl/itempool.hxx> -#include <svl/languageoptions.hxx> +#include <svl/ctloptions.hxx> #include <comphelper/classids.hxx> #include <servicenames_charttypes.hxx> #include <rtl/ustring.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/stream.hxx> #include <memory> #include <libxml/xmlwriter.h> -namespace com::sun::star::chart2 { class XChartDocument; } namespace chart { using namespace ::com::sun::star; -using namespace ::com::sun::star::chart2; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; -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; - -/** This class handles a collection of coordinate systems and is used for - * executing some action on all coordinate systems such as - * `prepareAutomaticAxisScaling` and `setExplicitScaleAndIncrement`. - * Moreover it contains the `aAutoScaling` object that is an instance of - * the `ScaleAutomatism` class. The initialization of `aAutoScaling` is - * performed in the `SeriesPlotterContainer::initAxisUsageList` method and is - * used in the `SeriesPlotterContainer::doAutoScaling` for calculating explicit - * scale and increment objects (see `SeriesPlotterContainer::doAutoScaling`). - */ -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 ); - - void prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex ); - void setExplicitScaleAndIncrement( sal_Int32 nDimIndex, sal_Int32 nAxisIndex, const ExplicitScaleData& rScale, const ExplicitIncrementData& rInc ); - - ScaleAutomatism aAutoScaling; - -private: - tCoordinateSystemMap aCoordinateSystems; - std::map< sal_Int32, sal_Int32 > aMaxIndexPerDimension; -}; - -AxisUsage::AxisUsage() - : aAutoScaling(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; - - //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; -} - -std::vector< VCoordinateSystem* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) -{ - std::vector< VCoordinateSystem* > aRet; - - for (auto const& coordinateSystem : aCoordinateSystems) - { - if( coordinateSystem.second.first != nDimensionIndex ) - continue; - if( coordinateSystem.second.second != nAxisIndex ) - continue; - aRet.push_back( coordinateSystem.first ); - } - - 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; -} - -void AxisUsage::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) -{ - std::vector<VCoordinateSystem*> aVCooSysList = getCoordinateSystems(nDimIndex, nAxisIndex); - for (VCoordinateSystem * i : aVCooSysList) - i->prepareAutomaticAxisScaling(rScaleAutomatism, nDimIndex, nAxisIndex); -} - -void AxisUsage::setExplicitScaleAndIncrement( - sal_Int32 nDimIndex, sal_Int32 nAxisIndex, const ExplicitScaleData& rScale, const ExplicitIncrementData& rInc ) -{ - std::vector<VCoordinateSystem*> aVCooSysList = getCoordinateSystems(nDimIndex, nAxisIndex); - for (VCoordinateSystem* i : aVCooSysList) - i->setExplicitScaleAndIncrement(nDimIndex, nAxisIndex, rScale, rInc); -} - -typedef std::vector<std::unique_ptr<VSeriesPlotter> > SeriesPlottersType; - -/** This class is a container of `SeriesPlotter` objects (such as `PieChart` - * instances). It is used for initializing coordinate systems, axes and scales - * of all series plotters which belongs to the container. - */ -class SeriesPlotterContainer -{ -public: - explicit SeriesPlotterContainer( std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList ); - ~SeriesPlotterContainer(); - - /** It is used to set coordinate systems (`m_rVCooSysList`), this method - * is invoked by `ChartView::createShapes2D` before of - * `ChartView::impl_createDiagramAndContent`. - * Coordinate systems are retrieved through the `XCoordinateSystemContainer` - * interface implemented by a diagram object which is provided by the - * `ChartModel` object passed to the method (`rChartModel.getFirstDiagram()`). - * - * It is used for creating series plotters and appending them - * to `m_aSeriesPlotterList`. The created series plotters are initialized - * through data (number formats supplier, color scheme, data series), - * extracted from the chart model or the diagram objects. An exception is - * the explicit category provider that is retrieved through the - * `VCoordinateSystem` object used by the series plotter. - * - * It sets the minimum-maximum supplier for a coordinate system: - * this supplier is the series plotter itself which utilizes the given - * coordinate system. In fact `VSeriesPlotter` has `MinimumMaximumSupplier` - * as one of its base classes. - * Hence, for instance, a `PieChart`, which is a series plotter, is - * a `MinimumMaximumSupplier`, too. - */ - void initializeCooSysAndSeriesPlotter( ChartModel& rModel ); - - /** This method is invoked by `ChartView::impl_createDiagramAndContent`. - * It iterates on every axis of every coordinate systems, and if the axis - * is not yet present in `m_aAxisUsageList` it creates a new `AxisUsage` - * object and initialize its `aAutoScaling` member to the `ScaleData` - * object of the current axis. - */ - void initAxisUsageList(const Date& rNullDate); - - /** - * Perform automatic axis scaling and determine the amount and spacing of - * increments. It assumes that the caller has determined the size of the - * largest axis label text object prior to calling this method. - * - * The new axis scaling data will be stored in the VCoordinateSystem - * objects. The label alignment direction for each axis will also get - * determined during this process, and stored in VAxis. - * - * This method is invoked by `ChartView::impl_createDiagramAndContent` - * soon after `initAxisUsageList`. - * It initializes explicit scale and increment objects for all coordinate - * systems in `m_rVCooSysList`. - * This action is achieved by iterating on the `m_aAxisUsageList` container, - * and performing 3 steps: - * 1- call `VCoordinateSystem::prepareAutomaticAxisScaling` for setting - * scaling parameters of the `aAutoScaling` member (a `ScaleAutomatism` - * object) for the current `AxisUsage` instance - * (see `VCoordinateSystem::prepareAutomaticAxisScaling`); - * 2- calculate the explicit scale and increment objects - * (see ScaleAutomatism::calculateExplicitScaleAndIncrement); - * 3- set the explicit scale and increment objects for each coordinate - * system. - */ - void doAutoScaling( ChartModel& rModel ); - - /** - * After auto-scaling is performed, call this method to set the explicit - * scaling and increment data to all relevant VAxis objects. - */ - void updateScalesAndIncrementsOnAxes(); - - /** - * After auto-scaling is performed, call this method to set the explicit - * scaling data to all the plotters. - */ - void setScalesFromCooSysToPlotter(); - - void setNumberFormatsFromAxes(); - drawing::Direction3D getPreferredAspectRatio(); - - SeriesPlottersType& getSeriesPlotterList() { return m_aSeriesPlotterList; } - std::vector< std::unique_ptr<VCoordinateSystem> >& getCooSysList() { return m_rVCooSysList; } - std::vector< LegendEntryProvider* > getLegendEntryProviderList(); - - void AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ); - - static bool isCategoryPositionShifted( - const chart2::ScaleData& rSourceScale, bool bHasComplexCategories ); - -private: - /** A vector of series plotters. - */ - SeriesPlottersType m_aSeriesPlotterList; - - /** A vector of coordinate systems. - */ - std::vector< std::unique_ptr<VCoordinateSystem> >& m_rVCooSysList; - - /** A map whose key is a `XAxis` interface and the related value is - * an object of `AxisUsage` type. - */ - std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList; - - /** - * Max axis index of all dimensions. Currently this can be either 0 or 1 - * since we only support primary and secondary axes per dimension. The - * value of 0 means all dimensions have only primary axis, while 1 means - * at least one dimension has a secondary axis. - */ - sal_Int32 m_nMaxAxisIndex; - - sal_Int32 m_nDefaultDateNumberFormat; -}; - -SeriesPlotterContainer::SeriesPlotterContainer( std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList ) - : m_rVCooSysList( rVCooSysList ) - , m_nMaxAxisIndex(0) - , m_nDefaultDateNumberFormat(0) -{ -} - -SeriesPlotterContainer::~SeriesPlotterContainer() -{ - // - remove plotter from coordinatesystems - for(auto & nC : m_rVCooSysList) - nC->clearMinimumAndMaximumSupplierList(); -} - -std::vector< LegendEntryProvider* > SeriesPlotterContainer::getLegendEntryProviderList() -{ - std::vector< LegendEntryProvider* > aRet( m_aSeriesPlotterList.size() ); - sal_Int32 nN = 0; - for( const std::unique_ptr<VSeriesPlotter>& aPlotter : m_aSeriesPlotterList) - aRet[nN++] = aPlotter.get(); - return aRet; -} - -VCoordinateSystem* findInCooSysList( const std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList - , const uno::Reference< XCoordinateSystem >& xCooSys ) -{ - for(auto & pVCooSys : rVCooSysList) - { - if(pVCooSys->getModel()==xCooSys) - return pVCooSys.get(); - } - return nullptr; -} - -VCoordinateSystem* lcl_getCooSysForPlotter( const std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList, MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier ) -{ - if(!pMinimumAndMaximumSupplier) - return nullptr; - for(auto & pVCooSys : rVCooSysList) - { - if(pVCooSys->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier )) - return pVCooSys.get(); - } - return nullptr; -} - -VCoordinateSystem* addCooSysToList( std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList - , const uno::Reference< XCoordinateSystem >& xCooSys - , ChartModel& rChartModel ) -{ - VCoordinateSystem* pExistingVCooSys = findInCooSysList( rVCooSysList, xCooSys ); - if( pExistingVCooSys ) - return pExistingVCooSys; - - std::unique_ptr<VCoordinateSystem> pVCooSys = VCoordinateSystem::createCoordinateSystem(xCooSys ); - if(!pVCooSys) - return nullptr; - - OUString aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys, rChartModel ) ); - pVCooSys->setParticle(aCooSysParticle); - - pVCooSys->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys, rChartModel) ); - rVCooSysList.push_back( std::move(pVCooSys) ); - return rVCooSysList.back().get(); -} - -void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter( - ChartModel& rChartModel ) -{ - uno::Reference< XDiagram > xDiagram( rChartModel.getFirstDiagram() ); - if( !xDiagram.is()) - return; - - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject* >( &rChartModel ), uno::UNO_QUERY ); - if( rChartModel.hasInternalDataProvider() && DiagramHelper::isSupportingDateAxis( xDiagram ) ) - m_nDefaultDateNumberFormat=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier ); - - sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); - if(!nDimensionCount) - { - //@todo handle mixed dimension - nDimensionCount = 2; - } - - bool bSortByXValues = false; - bool bConnectBars = false; - bool bGroupBarsPerAxis = true; - bool bIncludeHiddenCells = true; - bool bSecondaryYaxisVisible = 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; - - if (nDimensionCount == 3) - { - xDiaProp->getPropertyValue( "3DRelativeHeight" ) >>= n3DRelativeHeight; - } - } - catch( const uno::Exception & ) - { - DBG_UNHANDLED_EXCEPTION("chart2" ); - } - - //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 - - //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); - // Let's check whether the secondary Y axis is visible - try - { - if (xCooSys->getMaximumAxisIndexByDimension(1) > 0) - { - Reference< beans::XPropertySet > xAxisProp(xCooSys->getAxisByDimension(1, 1), uno::UNO_QUERY); - xAxisProp->getPropertyValue("Show") >>= bSecondaryYaxisVisible; - } - } - catch (const lang::IndexOutOfBoundsException&) - { - TOOLS_WARN_EXCEPTION("chart2", "" ); - } - //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(nDimensionCount == 3 && 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::Any(n3DRelativeHeight) ); - } - catch (const uno::Exception&) { } - } - } - - bool bExcludingPositioning = DiagramHelper::getDiagramPositioningMode( xDiagram ) == DiagramPositioningMode_EXCLUDING; - VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning ); - if( !pPlotter ) - continue; - - m_aSeriesPlotterList.push_back( std::unique_ptr<VSeriesPlotter>(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 > const & xDataSeries = aSeriesList[nS]; - if(!xDataSeries.is()) - continue; - if( !bIncludeHiddenCells && !DataSeriesHelper::hasUnhiddenData(xDataSeries) ) - continue; - - std::unique_ptr<VDataSeries> pSeries(new VDataSeries( xDataSeries )); - - pSeries->setGlobalSeriesIndex(nGlobalSeriesIndex); - nGlobalSeriesIndex++; - - if( bSortByXValues ) - pSeries->doSortByXValues(); - - pSeries->setConnectBars( bConnectBars ); - pSeries->setGroupBarsPerAxis( bGroupBarsPerAxis ); - pSeries->setStartingAngle( nStartingAngle ); - - pSeries->setMissingValueTreatment( nMissingValueTreatment ); - - OUString aSeriesParticle( ObjectIdentifier::createParticleForSeries( 0, nCS, nT, nS ) ); - pSeries->setParticle(aSeriesParticle); - - OUString aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType ) ); - pSeries->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole); - - //ignore secondary axis for charttypes that do not support them - if( pSeries->getAttachedAxisIndex() != MAIN_AXIS_INDEX && - ( !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount ) || - !bSecondaryYaxisVisible ) ) - { - pSeries->setAttachedAxisIndex(MAIN_AXIS_INDEX); - } - - 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( std::move(pSeries), zSlot, xSlot, ySlot ); - } - } - } - - //transport seriesnames to the coordinatesystems if needed - if( m_aSeriesPlotterList.empty() ) - return; - - uno::Sequence< OUString > aSeriesNames; - bool bSeriesNamesInitialized = false; - for(auto & pVCooSys : m_rVCooSysList) - { - if( pVCooSys->needSeriesNamesForAxis() ) - { - if(!bSeriesNamesInitialized) - { - aSeriesNames = m_aSeriesPlotterList[0]->getSeriesNames(); - bSeriesNamesInitialized = true; - } - pVCooSys->setSeriesNamesForAxis( aSeriesNames ); - } - } -} - -bool SeriesPlotterContainer::isCategoryPositionShifted( - const chart2::ScaleData& rSourceScale, bool bHasComplexCategories ) -{ - if (rSourceScale.AxisType == AxisType::CATEGORY) - return bHasComplexCategories || rSourceScale.ShiftedCategoryPosition; - - if (rSourceScale.AxisType == AxisType::DATE) - return rSourceScale.ShiftedCategoryPosition; - - return rSourceScale.AxisType == AxisType::SERIES; -} - -void SeriesPlotterContainer::initAxisUsageList(const Date& rNullDate) -{ - m_aAxisUsageList.clear(); - - // Loop through coordinate systems in the diagram (though for now - // there should only be one coordinate system per diagram). - for (auto & pVCooSys : m_rVCooSysList) - { - uno::Reference<XCoordinateSystem> xCooSys = pVCooSys->getModel(); - sal_Int32 nDimCount = xCooSys->getDimension(); - bool bComplexCategoryAllowed = ChartTypeHelper::isSupportingComplexCategory(AxisHelper::getChartTypeByIndex(xCooSys, 0)); - - for (sal_Int32 nDimIndex = 0; nDimIndex < nDimCount; ++nDimIndex) - { - bool bDateAxisAllowed = ChartTypeHelper::isSupportingDateAxis( - AxisHelper::getChartTypeByIndex(xCooSys, 0), nDimIndex); - - // Each dimension may have primary and secondary axes. - const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex); - for (sal_Int32 nAxisIndex = 0; nAxisIndex <= nMaxAxisIndex; ++nAxisIndex) - { - uno::Reference<XAxis> xAxis = xCooSys->getAxisByDimension(nDimIndex, nAxisIndex); - - if (!xAxis.is()) - continue; - - if (m_aAxisUsageList.find(xAxis) == m_aAxisUsageList.end()) - { - // Create axis usage object for this axis. - - chart2::ScaleData aSourceScale = xAxis->getScaleData(); - ExplicitCategoriesProvider* pCatProvider = pVCooSys->getExplicitCategoriesProvider(); - if (nDimIndex == 0) - AxisHelper::checkDateAxis( aSourceScale, pCatProvider, bDateAxisAllowed ); - - bool bHasComplexCat = pCatProvider && pCatProvider->hasComplexCategories() && bComplexCategoryAllowed; - aSourceScale.ShiftedCategoryPosition = isCategoryPositionShifted(aSourceScale, bHasComplexCat); - - m_aAxisUsageList[xAxis].aAutoScaling = ScaleAutomatism(aSourceScale, rNullDate); - } - - AxisUsage& rAxisUsage = m_aAxisUsageList[xAxis]; - rAxisUsage.addCoordinateSystem(pVCooSys.get(), nDimIndex, nAxisIndex); - } - } - } - - // Determine the highest axis index of all dimensions. - m_nMaxAxisIndex = 0; - for (const auto & pVCooSys : m_rVCooSysList) - { - uno::Reference<XCoordinateSystem> xCooSys = pVCooSys->getModel(); - sal_Int32 nDimCount = xCooSys->getDimension(); - - for (sal_Int32 nDimIndex = 0; nDimIndex < nDimCount; ++nDimIndex) - { - for (auto & axisUsage : m_aAxisUsageList) - { - sal_Int32 nLocalMax = axisUsage.second.getMaxAxisIndexForDimension(nDimIndex); - if (m_nMaxAxisIndex < nLocalMax) - m_nMaxAxisIndex = nLocalMax; - } - } - } -} - -void SeriesPlotterContainer::setScalesFromCooSysToPlotter() -{ - //set scales to plotter to enable them to provide the preferred scene AspectRatio - for( const std::unique_ptr<VSeriesPlotter>& aPlotter : m_aSeriesPlotterList ) - { - VSeriesPlotter* pSeriesPlotter = aPlotter.get(); - 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() -{ - //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis - for( const std::unique_ptr<VSeriesPlotter>& aPlotter : m_aSeriesPlotterList ) - { - VSeriesPlotter* pSeriesPlotter = aPlotter.get(); - VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( m_rVCooSysList, pSeriesPlotter ); - if(pVCooSys) - { - AxesNumberFormats aAxesNumberFormats; - const 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& ) - { - TOOLS_WARN_EXCEPTION("chart2", "" ); - } - } - } - } - } -} - -void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes() -{ - for(auto & nC : m_rVCooSysList) - nC->updateScalesAndIncrementsOnAxes(); -} - -void SeriesPlotterContainer::doAutoScaling( ChartModel& rChartModel ) -{ - if (m_aSeriesPlotterList.empty() || m_aAxisUsageList.empty()) - // We need these two containers populated to do auto-scaling. Bail out. - return; - - //iterate over the main scales first than secondary axis - for (sal_Int32 nAxisIndex = 0; nAxisIndex <= m_nMaxAxisIndex; ++nAxisIndex) - { - // - first do autoscale for all x and z scales (because they are treated independent) - for (auto & axisUsage : m_aAxisUsageList) - { - AxisUsage& rAxisUsage = axisUsage.second; - - rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 0, nAxisIndex); - rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 2, nAxisIndex); - - ExplicitScaleData aExplicitScale; - ExplicitIncrementData aExplicitIncrement; - rAxisUsage.aAutoScaling.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); - - rAxisUsage.setExplicitScaleAndIncrement(0, nAxisIndex, aExplicitScale, aExplicitIncrement); - rAxisUsage.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 (auto & axisUsage : m_aAxisUsageList) - { - AxisUsage& rAxisUsage = axisUsage.second; - - rAxisUsage.prepareAutomaticAxisScaling(rAxisUsage.aAutoScaling, 1, nAxisIndex); - - ExplicitScaleData aExplicitScale; - ExplicitIncrementData aExplicitIncrement; - rAxisUsage.aAutoScaling.calculateExplicitScaleAndIncrement( aExplicitScale, aExplicitIncrement ); - - rAxisUsage.setExplicitScaleAndIncrement(0, nAxisIndex, aExplicitScale, aExplicitIncrement); - rAxisUsage.setExplicitScaleAndIncrement(1, nAxisIndex, aExplicitScale, aExplicitIncrement); - rAxisUsage.setExplicitScaleAndIncrement(2, nAxisIndex, aExplicitScale, aExplicitIncrement); - } - } - AdaptScaleOfYAxisWithoutAttachedSeries( rChartModel ); -} - -void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel& rModel ) -{ - //issue #i80518# - for( sal_Int32 nAxisIndex=0; nAxisIndex<=m_nMaxAxisIndex; nAxisIndex++ ) - { - for (auto & axisUsage : m_aAxisUsageList) - { - AxisUsage& rAxisUsage = axisUsage.second; - std::vector< VCoordinateSystem* > aVCooSysList_Y = rAxisUsage.getCoordinateSystems( 1, nAxisIndex ); - if( aVCooSysList_Y.empty() ) - continue; - - uno::Reference< XDiagram > xDiagram( rModel.getFirstDiagram() ); - if (!xDiagram.is()) - continue; - - bool bSeriesAttachedToThisAxis = false; - sal_Int32 nAttachedAxisIndex = -1; - { - std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) ); - for (auto const& series : aSeriesVector) - { - sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex(series); - if( nAxisIndex == nCurrentIndex ) - { - bSeriesAttachedToThisAxis = true; - break; - } - else if( nAttachedAxisIndex<0 || nAttachedAxisIndex>nCurrentIndex ) - nAttachedAxisIndex=nCurrentIndex; - } - } - - if (bSeriesAttachedToThisAxis || nAttachedAxisIndex < 0) - continue; - - for(VCoordinateSystem* nC : aVCooSysList_Y) - { - nC->prepareAutomaticAxisScaling( rAxisUsage.aAutoScaling, 1, nAttachedAxisIndex ); - - ExplicitScaleData aExplicitScaleSource = nC->getExplicitScale( 1,nAttachedAxisIndex ); - ExplicitIncrementData aExplicitIncrementSource = nC->getExplicitIncrement( 1,nAttachedAxisIndex ); - - ExplicitScaleData aExplicitScaleDest = nC->getExplicitScale( 1,nAxisIndex ); - ExplicitIncrementData aExplicitIncrementDest = nC->getExplicitIncrement( 1,nAxisIndex ); - - aExplicitScaleDest.Orientation = aExplicitScaleSource.Orientation; - aExplicitScaleDest.Scaling = aExplicitScaleSource.Scaling; - aExplicitScaleDest.AxisType = aExplicitScaleSource.AxisType; - - aExplicitIncrementDest.BaseValue = aExplicitIncrementSource.BaseValue; - - ScaleData aScale( rAxisUsage.aAutoScaling.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; - - 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; - - if( !aScale.IncrementData.Distance.hasValue() ) - aExplicitIncrementDest.Distance = aExplicitIncrementSource.Distance; - - bool bAutoMinorInterval = true; - if( aScale.IncrementData.SubIncrements.hasElements() ) - bAutoMinorInterval = !( aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ); - if( bAutoMinorInterval ) - { - if( !aExplicitIncrementDest.SubIncrements.empty() && !aExplicitIncrementSource.SubIncrements.empty() ) - aExplicitIncrementDest.SubIncrements[0].IntervalCount = - aExplicitIncrementSource.SubIncrements[0].IntervalCount; - } - - nC->setExplicitScaleAndIncrement( 1, nAxisIndex, aExplicitScaleDest, aExplicitIncrementDest ); - } - } - } - - if( !AxisHelper::isAxisPositioningEnabled() ) - return; - - //correct origin for y main axis (the origin is where the other main axis crosses) - sal_Int32 nAxisIndex=0; - sal_Int32 nDimensionIndex=1; - for (auto & axisUsage : m_aAxisUsageList) - { - AxisUsage& rAxisUsage = axisUsage.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 ) ); - - 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 ); - - css::chart::ChartAxisPosition eCrossingMainAxisPos( css::chart::ChartAxisPosition_ZERO ); - if( xCrossingMainAxis.is() ) - { - xCrossingMainAxis->getPropertyValue("CrossoverPosition") >>= eCrossingMainAxisPos; - if( eCrossingMainAxisPos == css::chart::ChartAxisPosition_VALUE ) - { - double fValue = 0.0; - xCrossingMainAxis->getPropertyValue("CrossoverValue") >>= fValue; - aExplicitScale.Origin = fValue; - } - else if( eCrossingMainAxisPos == css::chart::ChartAxisPosition_ZERO ) - aExplicitScale.Origin = 0.0; - else if( eCrossingMainAxisPos == css::chart::ChartAxisPosition_START ) - aExplicitScale.Origin = aExplicitScale.Minimum; - else if( eCrossingMainAxisPos == css::chart::ChartAxisPosition_END ) - aExplicitScale.Origin = aExplicitScale.Maximum; - } - - aVCooSysList[nC]->setExplicitScaleAndIncrement( nDimensionIndex, nAxisIndex, aExplicitScale, aExplicitIncrement ); - } - } -} - -drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio() -{ - drawing::Direction3D aPreferredAspectRatio(1.0,1.0,1.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; - for( const std::unique_ptr<VSeriesPlotter>& aPlotter : m_aSeriesPlotterList ) - { - drawing::Direction3D aSingleRatio( aPlotter->getPreferredDiagramAspectRatio() ); - if( fx<0 && aSingleRatio.DirectionX>0 ) - fx = aSingleRatio.DirectionX; - - 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; - } - - 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; - } - - if( fx>0 && fy>0 && fz>0 ) - break; - } - aPreferredAspectRatio = drawing::Direction3D(fx, fy, fz); - return aPreferredAspectRatio; -} - -} - struct CreateShapeParam2D { css::awt::Rectangle maRemainingSpace; @@ -1009,10 +133,10 @@ struct CreateShapeParam2D std::shared_ptr<VTitle> mpVTitleSecondX; std::shared_ptr<VTitle> mpVTitleSecondY; - css::uno::Reference<css::drawing::XShape> mxMarkHandles; - css::uno::Reference<css::drawing::XShape> mxPlotAreaWithAxes; + rtl::Reference<SvxShapeRect> mxMarkHandles; + rtl::Reference<SvxShapeRect> mxPlotAreaWithAxes; - css::uno::Reference<css::drawing::XShapes> mxDiagramWithAxesShapes; + rtl::Reference<SvxShapeGroup> mxDiagramWithAxesShapes; bool mbAutoPosTitleX; bool mbAutoPosTitleY; @@ -1032,21 +156,13 @@ struct CreateShapeParam2D mbUseFixedInnerSize(false) {} }; -const uno::Sequence<sal_Int8>& ExplicitValueProvider::getUnoTunnelId() -{ - return theExplicitValueProviderUnoTunnelId::get().getSeq(); -} + ChartView::ChartView( - uno::Reference<uno::XComponentContext> const & xContext, + uno::Reference<uno::XComponentContext> xContext, ChartModel& rModel) - : m_aMutex() - , m_xCC(xContext) + : m_xCC(std::move(xContext)) , mrChartModel(rModel) - , m_xShapeFactory() - , m_xDrawPage() - , m_pDrawModelWrapper() - , m_aListenerContainer( m_aMutex ) , m_bViewDirty(true) , m_bInViewUpdate(false) , m_bViewUpdatePending(false) @@ -1108,10 +224,10 @@ void ChartView::impl_deleteCoordinateSystems() // 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\"" ); +constexpr OUString lcl_aGDIMetaFileMIMEType( + u"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\""_ustr ); +constexpr OUString lcl_aGDIMetaFileMIMETypeHighContrast( + u"application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\""_ustr ); } // anonymous namespace void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStream @@ -1123,41 +239,25 @@ void ChartView::getMetaFile( const uno::Reference< io::XOutputStream >& xOutStre // creating the graphic exporter uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( m_xCC ); - uno::Sequence< beans::PropertyValue > aProps(3); - aProps[0].Name = "FilterName"; - aProps[0].Value <<= OUString("SVM"); - - aProps[1].Name = "OutputStream"; - aProps[1].Value <<= xOutStream; - - uno::Sequence< beans::PropertyValue > aFilterData(8); - aFilterData[0].Name = "ExportOnlyBackground"; - aFilterData[0].Value <<= false; - aFilterData[1].Name = "HighContrast"; - aFilterData[1].Value <<= bUseHighContrast; - - aFilterData[2].Name = "Version"; - const sal_Int32 nVersion = SOFFICE_FILEFORMAT_50; - aFilterData[2].Value <<= nVersion; - - aFilterData[3].Name = "CurrentPage"; - aFilterData[3].Value <<= uno::Reference< uno::XInterface >( m_xDrawPage, uno::UNO_QUERY ); - - //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100% - aFilterData[4].Name = "ScaleXNumerator"; - aFilterData[4].Value <<= m_nScaleXNumerator; - aFilterData[5].Name = "ScaleXDenominator"; - aFilterData[5].Value <<= m_nScaleXDenominator; - aFilterData[6].Name = "ScaleYNumerator"; - aFilterData[6].Value <<= m_nScaleYNumerator; - aFilterData[7].Name = "ScaleYDenominator"; - aFilterData[7].Value <<= m_nScaleYDenominator; - - - aProps[2].Name = "FilterData"; - aProps[2].Value <<= aFilterData; - - xExporter->setSourceDocument( uno::Reference< lang::XComponent >( m_xDrawPage, uno::UNO_QUERY) ); + uno::Sequence< beans::PropertyValue > aFilterData{ + comphelper::makePropertyValue("ExportOnlyBackground", false), + comphelper::makePropertyValue("HighContrast", bUseHighContrast), + comphelper::makePropertyValue("Version", sal_Int32(SOFFICE_FILEFORMAT_50)), + comphelper::makePropertyValue("CurrentPage", uno::Reference< uno::XInterface >( static_cast<cppu::OWeakObject*>(m_xDrawPage.get()), uno::UNO_QUERY )), + //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100% + comphelper::makePropertyValue("ScaleXNumerator", m_nScaleXNumerator), + comphelper::makePropertyValue("ScaleXDenominator", m_nScaleXDenominator), + comphelper::makePropertyValue("ScaleYNumerator", m_nScaleYNumerator), + comphelper::makePropertyValue("ScaleYDenominator", m_nScaleYDenominator) + }; + + uno::Sequence< beans::PropertyValue > aProps{ + comphelper::makePropertyValue("FilterName", OUString("SVM")), + comphelper::makePropertyValue("OutputStream", xOutStream), + comphelper::makePropertyValue("FilterData", aFilterData) + }; + + xExporter->setSourceDocument( m_xDrawPage ); if( xExporter->filter( aProps ) ) { xOutStream->flush(); @@ -1178,41 +278,26 @@ uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aF update(); SvMemoryStream aStream( 1024, 1024 ); - utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream ); + rtl::Reference<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 ); + this->getMetaFile( pStreamWrapper, bHighContrastMetaFile ); - 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(); - } - } + pStreamWrapper->seek(0); + sal_Int32 nBytesToRead = pStreamWrapper->available(); + uno::Sequence< sal_Int8 > aSeq( nBytesToRead ); + pStreamWrapper->readBytes( aSeq, nBytesToRead); + aRet <<= aSeq; + pStreamWrapper->closeInput(); return aRet; } uno::Sequence< datatransfer::DataFlavor > SAL_CALL ChartView::getTransferDataFlavors() { - uno::Sequence< datatransfer::DataFlavor > aRet(2); - - aRet[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType, - "GDIMetaFile", - cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ); - aRet[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast, - "GDIMetaFile", - cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ); - - return aRet; + return + { + { lcl_aGDIMetaFileMIMEType, "GDIMetaFile", cppu::UnoType<uno::Sequence< sal_Int8 >>::get() }, + { lcl_aGDIMetaFileMIMETypeHighContrast, "GDIMetaFile", cppu::UnoType<uno::Sequence< sal_Int8 >>::get() } + }; } sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor ) { @@ -1220,17 +305,6 @@ sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlav aFlavor.MimeType == lcl_aGDIMetaFileMIMETypeHighContrast ); } -// ____ XUnoTunnel ___ -::sal_Int64 SAL_CALL ChartView::getSomething( const uno::Sequence< ::sal_Int8 >& aIdentifier ) -{ - if( isUnoTunnelId<ExplicitValueProvider>(aIdentifier) ) - { - ExplicitValueProvider* pProvider = this; - return reinterpret_cast<sal_Int64>(pProvider); - } - return 0; -} - // lang::XServiceInfo OUString SAL_CALL ChartView::getImplementationName() @@ -1262,19 +336,19 @@ static ::basegfx::B3DHomMatrix createTransformationSceneToScreen( namespace { -bool lcl_IsPieOrDonut( const uno::Reference< XDiagram >& xDiagram ) +bool lcl_IsPieOrDonut( const rtl::Reference< Diagram >& xDiagram ) { //special treatment for pie charts //the size is checked after complete creation to get the datalabels into the given space //todo: this is just a workaround at the moment for pie and donut labels - return DiagramHelper::isPieOrDonutChart( xDiagram ); + return xDiagram->isPieOrDonutChart(); } void lcl_setDefaultWritingMode( const std::shared_ptr< DrawModelWrapper >& pDrawModelWrapper, ChartModel& rModel) { //get writing mode from parent document: - if( !SvtLanguageOptions().IsCTLFontEnabled() ) + if( !SvtCTLOptions::IsCTLFontEnabled() ) return; try @@ -1397,7 +471,7 @@ void lcl_setDefaultWritingMode( const std::shared_ptr< DrawModelWrapper >& pDraw if( nWritingMode != -1 && nWritingMode != text::WritingMode2::PAGE ) { if( pDrawModelWrapper ) - pDrawModelWrapper->GetItemPool().SetPoolDefaultItem(SvxFrameDirectionItem(static_cast<SvxFrameDirection>(nWritingMode), EE_PARA_WRITINGDIR) ); + pDrawModelWrapper->GetItemPool().SetUserDefaultItem(SvxFrameDirectionItem(static_cast<SvxFrameDirection>(nWritingMode), EE_PARA_WRITINGDIR) ); } } catch( const uno::Exception& ) @@ -1412,7 +486,7 @@ sal_Int16 lcl_getDefaultWritingModeFromPool( const std::shared_ptr<DrawModelWrap if(!pDrawModelWrapper) return nWritingMode; - const SfxPoolItem& rItem = pDrawModelWrapper->GetItemPool().GetDefaultItem(EE_PARA_WRITINGDIR); + const SfxPoolItem& rItem = pDrawModelWrapper->GetItemPool().GetUserOrPoolDefaultItem(EE_PARA_WRITINGDIR); nWritingMode = static_cast<sal_Int16>(static_cast<const SvxFrameDirectionItem&>(rItem).GetValue()); return nWritingMode; @@ -1425,11 +499,11 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D //return the used rectangle awt::Rectangle aUsedOuterRect(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y, 0, 0); - uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() ); + rtl::Reference< Diagram > xDiagram( mrChartModel.getFirstChartDiagram() ); if( !xDiagram.is()) return aUsedOuterRect; - sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); + sal_Int32 nDimensionCount = xDiagram->getDimension(); if(!nDimensionCount) { //@todo handle mixed dimension @@ -1439,26 +513,23 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D basegfx::B2IRectangle aAvailableOuterRect = BaseGFXHelper::makeRectangle(rParam.maRemainingSpace); const std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList( rParam.mpSeriesPlotterContainer->getCooSysList() ); - SeriesPlottersType& rSeriesPlotterList = rParam.mpSeriesPlotterContainer->getSeriesPlotterList(); + auto& rSeriesPlotterList = rParam.mpSeriesPlotterContainer->getSeriesPlotterList(); //create VAxis, so they can give necessary information for automatic scaling - uno::Reference<chart2::XChartDocument> const xChartDoc(&mrChartModel); uno::Reference<util::XNumberFormatsSupplier> const xNumberFormatsSupplier( mrChartModel.getNumberFormatsSupplier()); - size_t nC = 0; - for( nC=0; nC < rVCooSysList.size(); nC++) + + for (auto& rpVCooSys : rVCooSysList) { - VCoordinateSystem* pVCooSys = rVCooSysList[nC].get(); - if(nDimensionCount==3) + if (nDimensionCount == 3) { - uno::Reference<beans::XPropertySet> xSceneProperties( xDiagram, uno::UNO_QUERY ); - CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( xSceneProperties ) ); - CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( xSceneProperties ) ); - CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( xSceneProperties ) ); - pVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos ); + CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( xDiagram ) ); + CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( xDiagram ) ); + CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( xDiagram ) ); + rpVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos ); } - - pVCooSys->createVAxisList(xChartDoc, rPageSize, rParam.maRemainingSpace, rParam.mbUseFixedInnerSize); + rpVCooSys->createVAxisList(&mrChartModel, rPageSize, rParam.maRemainingSpace, + rParam.mbUseFixedInnerSize, rSeriesPlotterList, getComponentContext()); } // - prepare list of all axis and how they are used @@ -1474,11 +545,11 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D drawing::Direction3D aPreferredAspectRatio = rParam.mpSeriesPlotterContainer->getPreferredAspectRatio(); - uno::Reference< drawing::XShapes > xSeriesTargetInFrontOfAxis; - uno::Reference< drawing::XShapes > xSeriesTargetBehindAxis; + rtl::Reference<SvxShapeGroupAnyD> xSeriesTargetInFrontOfAxis; + rtl::Reference<SvxShapeGroupAnyD> xSeriesTargetBehindAxis; VDiagram aVDiagram(xDiagram, aPreferredAspectRatio, nDimensionCount); {//create diagram - aVDiagram.init(rParam.mxDiagramWithAxesShapes, m_xShapeFactory); + aVDiagram.init(rParam.mxDiagramWithAxesShapes); aVDiagram.createShapes( awt::Point(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y), awt::Size(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height)); @@ -1486,29 +557,28 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion(); // It is preferable to use full size than minimum for pie charts if (!rParam.mbUseFixedInnerSize) - aVDiagram.reduceToMimimumSize(); + aVDiagram.reduceToMinimumSize(); } - uno::Reference< drawing::XShapes > xTextTargetShapes = - ShapeFactory::getOrCreateShapeFactory(m_xShapeFactory)->createGroup2D(rParam.mxDiagramWithAxesShapes); + rtl::Reference<SvxShapeGroup> xTextTargetShapes = + ShapeFactory::createGroup2D(rParam.mxDiagramWithAxesShapes); // - create axis and grids for all coordinate systems //init all coordinate systems - for( nC=0; nC < rVCooSysList.size(); nC++) + for (auto& rpVCooSys : rVCooSysList) { - VCoordinateSystem* pVCooSys = rVCooSysList[nC].get(); - pVCooSys->initPlottingTargets(xSeriesTargetInFrontOfAxis,xTextTargetShapes,m_xShapeFactory,xSeriesTargetBehindAxis); + rpVCooSys->initPlottingTargets(xSeriesTargetInFrontOfAxis, xTextTargetShapes, xSeriesTargetBehindAxis); - pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( + rpVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) )); - pVCooSys->initVAxisInList(); + rpVCooSys->initVAxisInList(); } //calculate resulting size respecting axis label layout and fontscaling - uno::Reference< drawing::XShape > xBoundingShape(rParam.mxDiagramWithAxesShapes, uno::UNO_QUERY); + rtl::Reference<SvxShapeGroup> xBoundingShape(rParam.mxDiagramWithAxesShapes); ::basegfx::B2IRectangle aConsumedOuterRect; //use first coosys only so far; todo: calculate for more than one coosys if we have more in future @@ -1519,7 +589,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D VCoordinateSystem* pVCooSys = rVCooSysList[0].get(); pVCooSys->createMaximumAxesLabels(); - aConsumedOuterRect = ShapeFactory::getRectangleOfShape(xBoundingShape); + aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape); ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() ); if (!rParam.mbUseFixedInnerSize) aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect ); @@ -1536,12 +606,14 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D bool bLessSpaceConsumedThanExpected = false; { - aConsumedOuterRect = ShapeFactory::getRectangleOfShape(xBoundingShape); + aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape); if( aConsumedOuterRect.getMinX() > aAvailableOuterRect.getMinX() || aConsumedOuterRect.getMaxX() < aAvailableOuterRect.getMaxX() || aConsumedOuterRect.getMinY() > aAvailableOuterRect.getMinY() || aConsumedOuterRect.getMinY() < aAvailableOuterRect.getMaxY() ) + { bLessSpaceConsumedThanExpected = true; + } } if (bLessSpaceConsumedThanExpected && !rParam.mbUseFixedInnerSize) @@ -1549,20 +621,28 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D aVDiagram.adjustInnerSize( aConsumedOuterRect ); pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) )); + + // Need to re-adjust again if the labels have changed height because of + // text can break. Ideally this shouldn't be needed, but the chart height + // isn't readjusted otherwise. + pVCooSys->createAxesLabels(); + aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape); + aVDiagram.adjustInnerSize(aConsumedOuterRect); + pVCooSys->setTransformationSceneToScreen(B3DHomMatrixToHomogenMatrix( + createTransformationSceneToScreen(aVDiagram.getCurrentRectangle()))); + } 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 } //create axes and grids for the final size - for( nC=0; nC < rVCooSysList.size(); nC++) + for (auto& rpVCooSys : rVCooSysList) { - VCoordinateSystem* pVCooSys = rVCooSysList[nC].get(); - - pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( + rpVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) )); - pVCooSys->createAxesShapes(); - pVCooSys->createGridShapes(); + rpVCooSys->createAxesShapes(); + rpVCooSys->createGridShapes(); } // - create data series for all charttypes @@ -1570,7 +650,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D for( const std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList ) { VSeriesPlotter* pSeriesPlotter = aPlotter.get(); - uno::Reference< drawing::XShapes > xSeriesTarget; + rtl::Reference<SvxShapeGroupAnyD> xSeriesTarget; if( pSeriesPlotter->WantToPlotInFrontOfAxisLine() ) xSeriesTarget = xSeriesTargetInFrontOfAxis; else @@ -1578,9 +658,9 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D xSeriesTarget = xSeriesTargetBehindAxis; OSL_ENSURE( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" ); } - pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,m_xShapeFactory,OUString() ); + pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,OUString() ); pSeriesPlotter->setPageReferenceSize( rPageSize ); - VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, pSeriesPlotter ); + VCoordinateSystem* pVCooSys = SeriesPlotterContainer::getCooSysForPlotter( rVCooSysList, pSeriesPlotter ); if(nDimensionCount==2) pSeriesPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() ); //better performance for big data @@ -1591,6 +671,11 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D } // Do not allow to move data labels in case of pie or donut chart, yet! pSeriesPlotter->setPieLabelsAllowToMove(!bIsPieOrDonut); + // use the pagesize as remaining space if we have a fixed inner size + if( rParam.mbUseFixedInnerSize ) + aAvailableOuterRect = BaseGFXHelper::makeRectangle(awt::Rectangle(0, 0, rPageSize.Width, rPageSize.Height)); + // set the available space for data labels to avoid moving out from chart area + pSeriesPlotter->setAvailableOuterRect(aAvailableOuterRect); pSeriesPlotter->createShapes(); m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped(); } @@ -1600,7 +685,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D { m_bPointsWereSkipped = false; - aConsumedOuterRect = ShapeFactory::getRectangleOfShape(xBoundingShape); + aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape); ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() ); if (!rParam.mbUseFixedInnerSize) aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect ); @@ -1616,17 +701,16 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D ShapeFactory::removeSubShapes( xTextTargetShapes ); //set new transformation - for( nC=0; nC < rVCooSysList.size(); nC++) + for (auto& rpVCooSys : rVCooSysList) { - VCoordinateSystem* pVCooSys = rVCooSysList[nC].get(); - pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( - createTransformationSceneToScreen( aNewInnerRect ) )); + auto aMatrix = createTransformationSceneToScreen(aNewInnerRect); + rpVCooSys->setTransformationSceneToScreen(B3DHomMatrixToHomogenMatrix(aMatrix)); } // - create data series for all charttypes for( std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList ) { - VCoordinateSystem* pVCooSys = lcl_getCooSysForPlotter( rVCooSysList, aPlotter.get() ); + VCoordinateSystem* pVCooSys = SeriesPlotterContainer::getCooSysForPlotter( rVCooSysList, aPlotter.get() ); if(nDimensionCount==2) aPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() ); // Now we can move data labels in case of pie or donut chart! @@ -1660,7 +744,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D else { ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle(); - m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() ); + m_aResultingDiagramRectangleExcludingAxes = BaseGFXHelper::toAwtRectangle(aConsumedInnerRect); } } else @@ -1670,7 +754,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D else { ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle(); - m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() ); + m_aResultingDiagramRectangleExcludingAxes = BaseGFXHelper::toAwtRectangle(aConsumedInnerRect); } } @@ -1680,8 +764,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D awt::Size aSize(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height); bool bPosSizeExcludeAxesProperty = true; - uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY_THROW ); - xDiaProps->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxesProperty; + xDiagram->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxesProperty; if (rParam.mbUseFixedInnerSize || bPosSizeExcludeAxesProperty) { aPos = awt::Point( m_aResultingDiagramRectangleExcludingAxes.X, m_aResultingDiagramRectangleExcludingAxes.Y ); @@ -1695,7 +778,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D } bool ChartView::getExplicitValuesForAxis( - uno::Reference< XAxis > xAxis + rtl::Reference< Axis > xAxis , ExplicitScaleData& rExplicitScale , ExplicitIncrementData& rExplicitIncrement ) { @@ -1706,64 +789,66 @@ bool ChartView::getExplicitValuesForAxis( if(!xAxis.is()) return false; - uno::Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(xAxis, mrChartModel.getFirstDiagram() ) ); - const VCoordinateSystem* pVCooSys = findInCooSysList(m_aVCooSysList,xCooSys); + rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemOfAxis(xAxis, mrChartModel.getFirstChartDiagram() ); + const VCoordinateSystem* pVCooSys = SeriesPlotterContainer::findInCooSysList(m_aVCooSysList, xCooSys); if(!pVCooSys) return false; sal_Int32 nDimensionIndex=-1; sal_Int32 nAxisIndex=-1; - if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) ) + if( !AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) ) + return false; + + rExplicitScale = pVCooSys->getExplicitScale(nDimensionIndex,nAxisIndex); + rExplicitIncrement = pVCooSys->getExplicitIncrement(nDimensionIndex,nAxisIndex); + if( !rExplicitScale.m_bShiftedCategoryPosition ) + return true; + + //remove 'one' from max + if( rExplicitScale.AxisType == css::chart2::AxisType::DATE ) { - rExplicitScale = pVCooSys->getExplicitScale(nDimensionIndex,nAxisIndex); - rExplicitIncrement = pVCooSys->getExplicitIncrement(nDimensionIndex,nAxisIndex); - if( rExplicitScale.ShiftedCategoryPosition ) + Date aMaxDate(rExplicitScale.NullDate); aMaxDate.AddDays(::rtl::math::approxFloor(rExplicitScale.Maximum)); + //for explicit scales with shifted categories we need one interval more + switch( rExplicitScale.TimeResolution ) { - //remove 'one' from max - if( rExplicitScale.AxisType == css::chart2::AxisType::DATE ) - { - Date aMaxDate(rExplicitScale.NullDate); aMaxDate.AddDays(::rtl::math::approxFloor(rExplicitScale.Maximum)); - //for explicit scales with shifted categories we need one interval more - switch( rExplicitScale.TimeResolution ) - { - case css::chart::TimeUnit::DAY: - --aMaxDate; - break; - case css::chart::TimeUnit::MONTH: - aMaxDate = DateHelper::GetDateSomeMonthsAway(aMaxDate,-1); - break; - case css::chart::TimeUnit::YEAR: - aMaxDate = DateHelper::GetDateSomeYearsAway(aMaxDate,-1); - break; - } - rExplicitScale.Maximum = aMaxDate - rExplicitScale.NullDate; - } - else if( rExplicitScale.AxisType == css::chart2::AxisType::CATEGORY ) - rExplicitScale.Maximum -= 1.0; - else if( rExplicitScale.AxisType == css::chart2::AxisType::SERIES ) - rExplicitScale.Maximum -= 1.0; + case css::chart::TimeUnit::DAY: + --aMaxDate; + break; + case css::chart::TimeUnit::MONTH: + aMaxDate = DateHelper::GetDateSomeMonthsAway(aMaxDate,-1); + break; + case css::chart::TimeUnit::YEAR: + aMaxDate = DateHelper::GetDateSomeYearsAway(aMaxDate,-1); + break; } - return true; + rExplicitScale.Maximum = aMaxDate - rExplicitScale.NullDate; } - return false; + else if( rExplicitScale.AxisType == css::chart2::AxisType::CATEGORY ) + rExplicitScale.Maximum -= 1.0; + else if( rExplicitScale.AxisType == css::chart2::AxisType::SERIES ) + rExplicitScale.Maximum -= 1.0; + return true; } SdrPage* ChartView::getSdrPage() { - auto pSvxDrawPage = comphelper::getUnoTunnelImplementation<SvxDrawPage>(m_xDrawPage); - if(pSvxDrawPage) - return pSvxDrawPage->GetSdrPage(); + if(m_xDrawPage) + return m_xDrawPage->GetSdrPage(); return nullptr; } -uno::Reference< drawing::XShape > ChartView::getShapeForCID( const OUString& rObjectCID ) +rtl::Reference< SvxShape > ChartView::getShapeForCID( const OUString& rObjectCID ) { SolarMutexGuard aSolarGuard; SdrObject* pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, this->getSdrPage() ); - if( pObj ) - return uno::Reference< drawing::XShape >( pObj->getUnoShape(), uno::UNO_QUERY); - return nullptr; + if( !pObj ) + return nullptr; + + uno::Reference< drawing::XShape > xShape = pObj->getUnoShape(); + rtl::Reference<SvxShape> xShape2 = dynamic_cast<SvxShape*>(xShape.get()); + assert(xShape2 || !xShape); + return xShape2; } awt::Rectangle ChartView::getDiagramRectangleExcludingAxes() @@ -1777,7 +862,7 @@ awt::Rectangle ChartView::getRectangleOfObject( const OUString& rObjectCID, bool impl_updateView(); awt::Rectangle aRet; - uno::Reference< drawing::XShape > xShape( getShapeForCID(rObjectCID) ); + rtl::Reference< SvxShape > xShape = getShapeForCID(rObjectCID); if(xShape.is()) { //special handling for axis for old api: @@ -1786,21 +871,20 @@ awt::Rectangle ChartView::getRectangleOfObject( const OUString& rObjectCID, bool if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_DIAGRAM ) { SolarMutexGuard aSolarGuard; - SvxShape* pRoot = comphelper::getUnoTunnelImplementation<SvxShape>( xShape ); - if( pRoot ) + SdrObject* pRootSdrObject = xShape->GetSdrObject(); + if( pRootSdrObject ) { - SdrObject* pRootSdrObject = pRoot->GetSdrObject(); - if( pRootSdrObject ) + SdrObjList* pRootList = pRootSdrObject->GetSubList(); + if( pRootList ) { - SdrObjList* pRootList = pRootSdrObject->GetSubList(); - if( pRootList ) + OUString aShapeName = "MarkHandles"; + if( eObjectType == OBJECTTYPE_DIAGRAM ) + aShapeName = "PlotAreaIncludingAxes"; + SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList ); + if( pShape ) { - OUString aShapeName = "MarkHandles"; - if( eObjectType == OBJECTTYPE_DIAGRAM ) - aShapeName = "PlotAreaIncludingAxes"; - SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList ); - if( pShape ) - xShape.set( pShape->getUnoShape(), uno::UNO_QUERY); + xShape = dynamic_cast<SvxShape*>(pShape->getUnoShape().get()); + assert(xShape); } } } @@ -1812,15 +896,11 @@ awt::Rectangle ChartView::getRectangleOfObject( const OUString& rObjectCID, bool if( bSnapRect ) { //for rotated objects the shape size and position differs from the visible rectangle - SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape ); - if( pShape ) + SdrObject* pSdrObject = xShape->GetSdrObject(); + if( pSdrObject ) { - SdrObject* pSdrObject = pShape->GetSdrObject(); - if( pSdrObject ) - { - tools::Rectangle aSnapRect( pSdrObject->GetSnapRect() ); - aRet = awt::Rectangle(aSnapRect.Left(),aSnapRect.Top(),aSnapRect.GetWidth(),aSnapRect.GetHeight()); - } + tools::Rectangle aSnapRect( pSdrObject->GetSnapRect() ); + aRet = awt::Rectangle(aSnapRect.Left(),aSnapRect.Top(),aSnapRect.GetWidth(),aSnapRect.GetHeight()); } } } @@ -1834,170 +914,31 @@ std::shared_ptr< DrawModelWrapper > ChartView::getDrawModelWrapper() namespace { -sal_Int32 lcl_getDiagramTitleSpace() -{ - return 200; //=0,2 cm spacing -} -bool lcl_getPropertySwapXAndYAxis( const uno::Reference< XDiagram >& xDiagram ) -{ - bool bSwapXAndY = false; - - uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY ); - if( xCooSysContainer.is() ) - { - uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); - if( aCooSysList.hasElements() ) - { - uno::Reference<beans::XPropertySet> xProp(aCooSysList[0], uno::UNO_QUERY ); - if( xProp.is()) try - { - xProp->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXAndY; - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("chart2", "" ); - } - } - } - return bSwapXAndY; -} - -} -sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( - const Reference< chart2::XAxis >& xAxis - , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem - , const Reference<chart2::XChartDocument>& xChartDoc) -{ - return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis, xCorrespondingCoordinateSystem, xChartDoc - , true /*bSearchForParallelAxisIfNothingIsFound*/ ); -} +constexpr double constPageLayoutDistancePercentage = 0.02; +constexpr sal_Int32 constPageLayoutFixedDistance = 350; -sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp ) +bool getAvailablePosAndSizeForDiagram( + CreateShapeParam2D& rParam, const awt::Size & rPageSize, rtl::Reference<Diagram> const& xDiagram) { - sal_Int32 nFormat=0; - if( !xSeriesOrPointProp.is() ) - return nFormat; - - try - { - xSeriesOrPointProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nFormat; - } - catch (const beans::UnknownPropertyException&) {} - - if(nFormat<0) - nFormat=0; - return nFormat; -} + uno::Reference<beans::XPropertySet> const& xProp(xDiagram); + rParam.mbUseFixedInnerSize = false; -sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel( - const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, - const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier ) -{ - sal_Int32 nFormat=0; - if( !xSeriesOrPointProp.is() ) - return nFormat; - if( !(xSeriesOrPointProp->getPropertyValue("PercentageNumberFormat") >>= nFormat) ) - { - nFormat = DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier ); - } - if(nFormat<0) - nFormat=0; - return nFormat; -} + //@todo: we need a size dependent on the axis labels + rtl::Reference<ChartType> xChartType; + if (xDiagram) + xChartType = xDiagram->getChartTypeByIndex(0); -awt::Rectangle ExplicitValueProvider::AddSubtractAxisTitleSizes( - ChartModel& rModel - , const Reference< uno::XInterface >& xChartView - , const awt::Rectangle& rPositionAndSize, bool bSubtract ) -{ - awt::Rectangle aRet(rPositionAndSize); + sal_Int32 nXDistance = sal_Int32(rPageSize.Width * constPageLayoutDistancePercentage); + sal_Int32 nYDistance = sal_Int32(rPageSize.Height * constPageLayoutDistancePercentage); - //add axis title sizes to the diagram size - uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, rModel ) ); - uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, rModel ) ); - uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, rModel ) ); - uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, rModel ) ); - if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() ) + // Only pie chart uses fixed size margins + if (xChartType.is() && xChartType->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_PIE) { - ExplicitValueProvider* pExplicitValueProvider = comphelper::getUnoTunnelImplementation<ExplicitValueProvider>(xChartView); - if( pExplicitValueProvider ) - { - //detect whether x axis points into x direction or not - if( lcl_getPropertySwapXAndYAxis( rModel.getFirstDiagram() ) ) - { - std::swap( xTitle_Height, xTitle_Width ); - std::swap( xSecondTitle_Height, xSecondTitle_Width ); - } - - sal_Int32 nTitleSpaceWidth = 0; - sal_Int32 nTitleSpaceHeight = 0; - sal_Int32 nSecondTitleSpaceWidth = 0; - sal_Int32 nSecondTitleSpaceHeight = 0; - - if( xTitle_Height.is() ) - { - OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, rModel ) ); - nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height; - if( nTitleSpaceHeight ) - nTitleSpaceHeight+=lcl_getDiagramTitleSpace(); - } - if( xTitle_Width.is() ) - { - OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, rModel ) ); - nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width; - if(nTitleSpaceWidth) - nTitleSpaceWidth+=lcl_getDiagramTitleSpace(); - } - if( xSecondTitle_Height.is() ) - { - OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, rModel ) ); - nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height; - if( nSecondTitleSpaceHeight ) - nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace(); - } - if( xSecondTitle_Width.is() ) - { - OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, rModel ) ); - nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width; - if( nSecondTitleSpaceWidth ) - nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace(); - } - if( bSubtract ) - { - aRet.X += nTitleSpaceWidth; - aRet.Y += nSecondTitleSpaceHeight; - aRet.Width -= (nTitleSpaceWidth + nSecondTitleSpaceWidth); - aRet.Height -= (nTitleSpaceHeight + nSecondTitleSpaceHeight); - } - else - { - - aRet.X -= nTitleSpaceWidth; - aRet.Y -= nSecondTitleSpaceHeight; - aRet.Width += nTitleSpaceWidth + nSecondTitleSpaceWidth; - aRet.Height += nTitleSpaceHeight + nSecondTitleSpaceHeight; - } - } + nXDistance = constPageLayoutFixedDistance; + nYDistance = constPageLayoutFixedDistance; } - return aRet; -} - -namespace { -double lcl_getPageLayoutDistancePercentage() -{ - return 0.02; -} - -bool getAvailablePosAndSizeForDiagram( - CreateShapeParam2D& rParam, const awt::Size & rPageSize, const uno::Reference< beans::XPropertySet >& xProp) -{ - rParam.mbUseFixedInnerSize = false; - - //@todo: we need a size dependent on the axis labels - sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage()); - sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage()); rParam.maRemainingSpace.X += nXDistance; rParam.maRemainingSpace.Width -= 2*nXDistance; rParam.maRemainingSpace.Y += nYDistance; @@ -2050,7 +991,7 @@ bool getAvailablePosAndSizeForDiagram( return true; } -enum TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z }; +enum class TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z }; void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment , awt::Rectangle const & rDiagramPlusAxesRect, const awt::Size & rPageSize ) @@ -2060,32 +1001,30 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment awt::Point aNewPosition(0,0); awt::Size aTitleSize = pVTitle->getFinalSize(); - sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage()); - sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage()); - switch( eAlignment ) + sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height * constPageLayoutDistancePercentage); + sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width * constPageLayoutDistancePercentage); + switch (eAlignment) { - case ALIGN_TOP: + case TitleAlignment::ALIGN_TOP: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2 , rDiagramPlusAxesRect.Y - aTitleSize.Height/2 - nYDistance ); break; - case ALIGN_BOTTOM: + case TitleAlignment::ALIGN_BOTTOM: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2 , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2 + nYDistance ); break; - case ALIGN_LEFT: + case TitleAlignment::ALIGN_LEFT: aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 ); break; - case ALIGN_RIGHT: + case TitleAlignment::ALIGN_RIGHT: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 ); break; - case ALIGN_Z: + case TitleAlignment::ALIGN_Z: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height - aTitleSize.Height/2 ); break; - default: - break; } sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2; @@ -2105,8 +1044,7 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment } std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType - , const uno::Reference< drawing::XShapes>& xPageShapes - , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory + , const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes , ChartModel& rModel , awt::Rectangle& rRemainingSpace , const awt::Size & rPageSize @@ -2116,7 +1054,7 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType std::shared_ptr<VTitle> apVTitle; // #i109336# Improve auto positioning in chart - double fPercentage = lcl_getPageLayoutDistancePercentage(); + double fPercentage = constPageLayoutDistancePercentage; sal_Int32 nXDistance = static_cast< sal_Int32 >( rPageSize.Width * fPercentage ); sal_Int32 nYDistance = static_cast< sal_Int32 >( rPageSize.Height * fPercentage ); if ( eType == TitleHelper::MAIN_TITLE ) @@ -2132,9 +1070,9 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType nXDistance = 450; // 1/100 mm } - uno::Reference< XTitle > xTitle( TitleHelper::getTitle( eType, rModel ) ); + rtl::Reference< Title > xTitle( TitleHelper::getTitle( eType, rModel ) ); OUString aCompleteString = TitleHelper::getCompleteString(xTitle); - if (aCompleteString.isEmpty()) + if (aCompleteString.isEmpty() || !VTitle::isVisible(xTitle)) return apVTitle; //create title @@ -2159,8 +1097,8 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType bYAxisTitle = true; } apVTitle = std::make_shared<VTitle>(xTitle); - OUString aCID = ObjectIdentifier::createClassifiedIdentifierForObject(xTitle, rModel); - apVTitle->init(xPageShapes, xShapeFactory, aCID); + OUString aCID = ObjectIdentifier::createClassifiedIdentifierForObject(xTitle, &rModel); + apVTitle->init(xPageShapes, aCID); apVTitle->createShapes(awt::Point(0, 0), rPageSize, aTextMaxWidth, bYAxisTitle); awt::Size aTitleUnrotatedSize = apVTitle->getUnrotatedSize(); awt::Size aTitleSize = apVTitle->getFinalSize(); @@ -2169,8 +1107,7 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType rbAutoPosition = true; awt::Point aNewPosition(0,0); chart2::RelativePosition aRelativePosition; - uno::Reference<beans::XPropertySet> xProp(xTitle, uno::UNO_QUERY); - if (xProp.is() && (xProp->getPropertyValue("RelativePosition") >>= aRelativePosition)) + if (xTitle.is() && (xTitle->getPropertyValue("RelativePosition") >>= aRelativePosition)) { rbAutoPosition = false; @@ -2187,23 +1124,23 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType { switch( eAlignment ) { - case ALIGN_TOP: + case TitleAlignment::ALIGN_TOP: aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2 , rRemainingSpace.Y + aTitleSize.Height/2 + nYDistance ); break; - case ALIGN_BOTTOM: + case TitleAlignment::ALIGN_BOTTOM: aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2 , rRemainingSpace.Y + rRemainingSpace.Height - aTitleSize.Height/2 - nYDistance ); break; - case ALIGN_LEFT: + case TitleAlignment::ALIGN_LEFT: aNewPosition = awt::Point( rRemainingSpace.X + aTitleSize.Width/2 + nXDistance , rRemainingSpace.Y + rRemainingSpace.Height/2 ); break; - case ALIGN_RIGHT: + case TitleAlignment::ALIGN_RIGHT: aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width - aTitleSize.Width/2 - nXDistance , rRemainingSpace.Y + rRemainingSpace.Height/2 ); break; - default: + case TitleAlignment::ALIGN_Z: break; } @@ -2213,47 +1150,46 @@ std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType //remaining space switch( eAlignment ) { - case ALIGN_TOP: + case TitleAlignment::ALIGN_TOP: // Push the remaining space down from top. rRemainingSpace.Y += ( aTitleSize.Height + nYDistance ); rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance ); break; - case ALIGN_BOTTOM: + case TitleAlignment::ALIGN_BOTTOM: // Push the remaining space up from bottom. rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance ); break; - case ALIGN_LEFT: + case TitleAlignment::ALIGN_LEFT: // Push the remaining space to the right from left edge. rRemainingSpace.X += ( aTitleSize.Width + nXDistance ); rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance ); break; - case ALIGN_RIGHT: + case TitleAlignment::ALIGN_RIGHT: // Push the remaining space to the left from right edge. rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance ); break; - default: + case TitleAlignment::ALIGN_Z: break; } return apVTitle; } -bool lcl_createLegend( const uno::Reference< XLegend > & xLegend - , const uno::Reference< drawing::XShapes>& xPageShapes - , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory +bool lcl_createLegend( const rtl::Reference< Legend > & xLegend + , const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes , const uno::Reference< uno::XComponentContext > & xContext , awt::Rectangle & rRemainingSpace , const awt::Size & rPageSize , ChartModel& rModel - , const std::vector< LegendEntryProvider* >& rLegendEntryProviderList + , std::vector< LegendEntryProvider* >&& rLegendEntryProviderList , sal_Int16 nDefaultWritingMode ) { if (!VLegend::isVisible(xLegend)) return false; awt::Size rDefaultLegendSize; - VLegend aVLegend( xLegend, xContext, rLegendEntryProviderList, - xPageShapes, xShapeFactory, rModel); + VLegend aVLegend( xLegend, xContext, std::move(rLegendEntryProviderList), + xPageShapes, rModel); aVLegend.setDefaultWritingMode( nDefaultWritingMode ); aVLegend.createShapes( awt::Size( rRemainingSpace.Width, rRemainingSpace.Height ), rPageSize, rDefaultLegendSize ); @@ -2261,8 +1197,7 @@ bool lcl_createLegend( const uno::Reference< XLegend > & xLegend return true; } -void lcl_createButtons(const uno::Reference<drawing::XShapes>& xPageShapes, - const uno::Reference<lang::XMultiServiceFactory>& xShapeFactory, +void lcl_createButtons(const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes, ChartModel& rModel, awt::Rectangle& rRemainingSpace) { @@ -2274,7 +1209,7 @@ void lcl_createButtons(const uno::Reference<drawing::XShapes>& xPageShapes, awt::Size aSize(4000, 700); // size of the button - long x = 0; + tools::Long x = 0; if (xPivotTableDataProvider->getPageFields().hasElements()) { @@ -2283,19 +1218,19 @@ void lcl_createButtons(const uno::Reference<drawing::XShapes>& xPageShapes, const css::uno::Sequence<chart2::data::PivotTableFieldEntry> aPivotFieldEntries = xPivotTableDataProvider->getPageFields(); for (css::chart2::data::PivotTableFieldEntry const & rPageFieldEntry : aPivotFieldEntries) { - std::unique_ptr<VButton> pButton(new VButton); - pButton->init(xPageShapes, xShapeFactory); + VButton aButton; + aButton.init(xPageShapes); awt::Point aNewPosition(rRemainingSpace.X + x + 100, rRemainingSpace.Y + 100); sal_Int32 nDimensionIndex = rPageFieldEntry.DimensionIndex; OUString aFieldOutputDescription = xPivotTableDataProvider->getFieldOutputDescription(nDimensionIndex); - pButton->setLabel(rPageFieldEntry.Name + " | " + aFieldOutputDescription); - pButton->setCID("FieldButton.Page." + OUString::number(nDimensionIndex)); - pButton->setPosition(aNewPosition); - pButton->setSize(aSize); + aButton.setLabel(rPageFieldEntry.Name + " | " + aFieldOutputDescription); + aButton.setCID("FieldButton.Page." + OUString::number(nDimensionIndex)); + aButton.setPosition(aNewPosition); + aButton.setSize(aSize); if (rPageFieldEntry.HasHiddenMembers) - pButton->setArrowColor(Color(0x0000FF)); + aButton.setArrowColor(Color(0x0000FF)); - pButton->createShapes(xModelPage); + aButton.createShapes(xModelPage); x += aSize.Width + 100; } rRemainingSpace.Y += (aSize.Height + 100 + 100); @@ -2311,23 +1246,22 @@ void lcl_createButtons(const uno::Reference<drawing::XShapes>& xPageShapes, const css::uno::Sequence<chart2::data::PivotTableFieldEntry> aPivotFieldEntries = xPivotTableDataProvider->getRowFields(); for (css::chart2::data::PivotTableFieldEntry const & rRowFieldEntry : aPivotFieldEntries) { - - std::unique_ptr<VButton> pButton(new VButton); - pButton->init(xPageShapes, xShapeFactory); + VButton aButton; + aButton.init(xPageShapes); awt::Point aNewPosition(rRemainingSpace.X + x + 100, rRemainingSpace.Y + rRemainingSpace.Height - aSize.Height - 100); - pButton->setLabel(rRowFieldEntry.Name); - pButton->setCID("FieldButton.Row." + OUString::number(rRowFieldEntry.DimensionIndex)); - pButton->setPosition(aNewPosition); - pButton->setSize(aSize); + aButton.setLabel(rRowFieldEntry.Name); + aButton.setCID("FieldButton.Row." + OUString::number(rRowFieldEntry.DimensionIndex)); + aButton.setPosition(aNewPosition); + aButton.setSize(aSize); if ( rRowFieldEntry.Name == "Data" ) { - pButton->setBGColor( Color(0x00F6F6F6) ); - pButton->showArrow( false ); + aButton.setBGColor( Color(0x00F6F6F6) ); + aButton.showArrow( false ); } else if (rRowFieldEntry.HasHiddenMembers) - pButton->setArrowColor(Color(0x0000FF)); - pButton->createShapes(xModelPage); + aButton.setArrowColor(Color(0x0000FF)); + aButton.createShapes(xModelPage); x += aSize.Width + 100; } rRemainingSpace.Height -= (aSize.Height + 100 + 100); @@ -2336,8 +1270,7 @@ void lcl_createButtons(const uno::Reference<drawing::XShapes>& xPageShapes, void formatPage( ChartModel& rChartModel , const awt::Size& rPageSize - , const uno::Reference< drawing::XShapes >& xTarget - , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory + , const rtl::Reference<SvxShapeGroupAnyD>& xTarget ) { try @@ -2346,22 +1279,18 @@ void formatPage( if( ! xModelPage.is()) return; - if( !xShapeFactory.is() ) - return; - //format page tPropertyNameValueMap aNameValueMap; PropertyMapper::getValueMap( aNameValueMap, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), xModelPage ); - OUString aCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ); + OUString aCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, u"" ) ); aNameValueMap.emplace( "Name", uno::Any( aCID ) ); //CID OUString tNameSequence aNames; tAnySequence aValues; PropertyMapper::getMultiPropertyListsFromValueMap( aNames, aValues, aNameValueMap ); - ShapeFactory* pShapeFactory = ShapeFactory::getOrCreateShapeFactory(xShapeFactory); - pShapeFactory->createRectangle( + ShapeFactory::createRectangle( xTarget, rPageSize, awt::Point(0, 0), aNames, aValues); } catch( const uno::Exception & ) @@ -2370,33 +1299,26 @@ void formatPage( } } -void lcl_removeEmptyGroupShapes( const Reference< drawing::XShapes>& xParent ) +void lcl_removeEmptyGroupShapes( const SdrObject& rParent ) { - if(!xParent.is()) + SdrObjList* pObjList = rParent.getChildrenOfSdrObject(); + if (!pObjList || pObjList->GetObjCount() == 0) return; - Reference< drawing::XShapeGroup > xParentGroup( xParent, uno::UNO_QUERY ); - if( !xParentGroup.is() ) - { - Reference< drawing::XDrawPage > xPage( xParent, uno::UNO_QUERY ); - if( !xPage.is() ) - return; - } //iterate from back! - for( sal_Int32 nN = xParent->getCount(); nN--; ) + for(auto nIdx = static_cast<sal_Int32>(pObjList->GetObjCount() - 1); nIdx >= 0; --nIdx) { - uno::Any aAny = xParent->getByIndex( nN ); - Reference< drawing::XShapes> xShapes; - if( aAny >>= xShapes ) - lcl_removeEmptyGroupShapes( xShapes ); - if( xShapes.is() && xShapes->getCount()==0 ) + SdrObject* pChildSdrObject = pObjList->GetObj(nIdx); + SdrObjList* pChildObjList = pChildSdrObject->getChildrenOfSdrObject(); + if (!pChildObjList) + continue; + if (pChildObjList->GetObjCount() == 0) { //remove empty group shape - Reference< drawing::XShapeGroup > xGroup( xShapes, uno::UNO_QUERY ); - Reference< drawing::XShape > xShape( xShapes, uno::UNO_QUERY ); - if( xGroup.is() ) - xParent->remove( xShape ); + pObjList->NbcRemoveObject(nIdx); } + else + lcl_removeEmptyGroupShapes(*pChildSdrObject); } } @@ -2429,13 +1351,11 @@ void ChartView::impl_refreshAddIn() } } -static const char* envChartDummyFactory = getenv("CHART_DUMMY_FACTORY"); - void ChartView::createShapes() { SolarMutexGuard aSolarGuard; - osl::MutexGuard aTimedGuard(maTimeMutex); + std::unique_lock aTimedGuard(maTimeMutex); if(mrChartModel.isTimeBased()) { maTimeBased.bTimeBased = true; @@ -2457,13 +1377,15 @@ void ChartView::createShapes() awt::Size aPageSize = mrChartModel.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ); - ShapeFactory* pShapeFactory = ShapeFactory::getOrCreateShapeFactory(m_xShapeFactory); if(!mxRootShape.is()) - mxRootShape = pShapeFactory->getOrCreateChartRootShape( m_xDrawPage ); + mxRootShape = ShapeFactory::getOrCreateChartRootShape( m_xDrawPage ); - SdrPage* pPage = ChartView::getSdrPage(); - if(pPage) //it is necessary to use the implementation here as the uno page does not provide a propertyset + SdrPage* pPage = getSdrPage(); + + if (pPage) //it is necessary to use the implementation here as the uno page does not provide a propertyset + { pPage->SetSize(Size(aPageSize.Width,aPageSize.Height)); + } else { OSL_FAIL("could not set page size correctly"); @@ -2489,6 +1411,35 @@ void SAL_CALL ChartView::disposing( const lang::EventObject& /* rSource */ ) { } +namespace +{ +// Disables setting the chart's modified state, as well as its parent's (if exists). +// Painting a chart must not set these states. +struct ChartModelDisableSetModified +{ + ChartModel& mrChartModel; + SfxObjectShell* mpParentShell; + bool mbWasUnmodified; + ChartModelDisableSetModified(ChartModel& rChartModel) + : mrChartModel(rChartModel) + , mpParentShell(SfxObjectShell::GetShellFromComponent(rChartModel.getParent())) + , mbWasUnmodified(!rChartModel.isModified()) + { + if (mpParentShell && mpParentShell->IsEnableSetModified()) + mpParentShell->EnableSetModified(false); + else + mpParentShell = nullptr; + } + ~ChartModelDisableSetModified() + { + if (mbWasUnmodified && mrChartModel.isModified()) + mrChartModel.setModified(false); + if (mpParentShell) + mpParentShell->EnableSetModified(true); + } +}; +} + void ChartView::impl_updateView( bool bCheckLockedCtrler ) { if( !m_pDrawModelWrapper ) @@ -2503,7 +1454,7 @@ void ChartView::impl_updateView( bool bCheckLockedCtrler ) if (bCheckLockedCtrler && mrChartModel.hasControllersLocked()) return; - if( !(m_bViewDirty && !m_bInViewUpdate) ) + if( !m_bViewDirty || m_bInViewUpdate ) return; m_bInViewUpdate = true; @@ -2519,6 +1470,9 @@ void ChartView::impl_updateView( bool bCheckLockedCtrler ) m_pDrawModelWrapper->lockControllers(); } + // Rendering the chart must not set its (or its parent) modified status + ChartModelDisableSetModified dontSetModified(mrChartModel); + //create chart view { m_bViewDirty = false; @@ -2635,18 +1589,11 @@ void ChartView::impl_notifyModeChangeListener( const OUString& rNewMode ) { try { - ::cppu::OInterfaceContainerHelper* pIC = m_aListenerContainer - .getContainer( cppu::UnoType<util::XModeChangeListener>::get()); - if( pIC ) + std::unique_lock g(m_aMutex); + if( m_aModeChangeListeners.getLength(g) ) { util::ModeChangeEvent aEvent( static_cast< uno::XWeak* >( this ), rNewMode ); - ::cppu::OInterfaceIteratorHelper aIt( *pIC ); - while( aIt.hasMoreElements() ) - { - uno::Reference< util::XModeChangeListener > xListener( aIt.next(), uno::UNO_QUERY ); - if( xListener.is() ) - xListener->modeChanged( aEvent ); - } + m_aModeChangeListeners.notifyEach( g, &css::util::XModeChangeListener::modeChanged, aEvent); } } catch( const uno::Exception& ) @@ -2659,13 +1606,13 @@ void ChartView::impl_notifyModeChangeListener( const OUString& rNewMode ) void SAL_CALL ChartView::addModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener ) { - m_aListenerContainer.addInterface( - cppu::UnoType<util::XModeChangeListener>::get(), xListener ); + std::unique_lock g(m_aMutex); + m_aModeChangeListeners.addInterface(g, xListener ); } void SAL_CALL ChartView::removeModeChangeListener( const uno::Reference< util::XModeChangeListener >& xListener ) { - m_aListenerContainer.removeInterface( - cppu::UnoType<util::XModeChangeListener>::get(), xListener ); + std::unique_lock g(m_aMutex); + m_aModeChangeListeners.removeInterface(g, xListener ); } void SAL_CALL ChartView::addModeChangeApproveListener( const uno::Reference< util::XModeChangeApproveListener >& /* _rxListener */ ) { @@ -2735,7 +1682,7 @@ void SAL_CALL ChartView::setPropertyValue( const OUString& rPropertyName throw lang::IllegalArgumentException( "Property 'ZoomFactors' requires value of type Sequence< PropertyValue >", nullptr, 0 ); sal_Int32 nFilterArgs = aZoomFactors.getLength(); - beans::PropertyValue* pDataValues = aZoomFactors.getArray(); + const beans::PropertyValue* pDataValues = aZoomFactors.getConstArray(); while( nFilterArgs-- ) { if ( pDataValues->Name == "ScaleXNumerator" ) @@ -2859,38 +1806,40 @@ Reference< uno::XInterface > ChartView::createInstanceWithArguments( const OUStr uno::Sequence< OUString > ChartView::getAvailableServiceNames() { - uno::Sequence< OUString > aServiceNames( 6 ); - - aServiceNames[0] = "com.sun.star.drawing.DashTable"; - aServiceNames[1] = "com.sun.star.drawing.GradientTable"; - aServiceNames[2] = "com.sun.star.drawing.HatchTable"; - aServiceNames[3] = "com.sun.star.drawing.BitmapTable"; - aServiceNames[4] = "com.sun.star.drawing.TransparencyGradientTable"; - aServiceNames[5] = "com.sun.star.drawing.MarkerTable"; + uno::Sequence< OUString > aServiceNames{ "com.sun.star.drawing.DashTable", + "com.sun.star.drawing.GradientTable", + "com.sun.star.drawing.HatchTable", + "com.sun.star.drawing.BitmapTable", + "com.sun.star.drawing.TransparencyGradientTable", + "com.sun.star.drawing.MarkerTable" }; return aServiceNames; } -OUString ChartView::dump() +OUString ChartView::dump(OUString const & kind) { + if (kind.isEmpty()) { + return comphelper::dumpXmlToString([this](auto writer) { return dumpAsXml(writer); }); + } + + // kind == "shapes": #if HAVE_FEATURE_DESKTOP // Used for unit tests and in chartcontroller only, no need to drag in this when cross-compiling // for non-desktop impl_updateView(); - uno::Reference< drawing::XShapes > xShapes( m_xDrawPage, uno::UNO_QUERY_THROW ); - sal_Int32 n = xShapes->getCount(); + sal_Int32 n = m_xDrawPage->getCount(); OUStringBuffer aBuffer; for(sal_Int32 i = 0; i < n; ++i) { - uno::Reference< drawing::XShapes > xShape(xShapes->getByIndex(i), uno::UNO_QUERY); + uno::Reference< drawing::XShapes > xShape(m_xDrawPage->getByIndex(i), uno::UNO_QUERY); if(xShape.is()) { - OUString aString = XShapeDumper::dump(mxRootShape); + OUString aString = XShapeDumper::dump(uno::Reference<drawing::XShapes>(mxRootShape)); aBuffer.append(aString); } else { - uno::Reference< drawing::XShape > xSingleShape(xShapes->getByIndex(i), uno::UNO_QUERY); + uno::Reference< drawing::XShape > xSingleShape(m_xDrawPage->getByIndex(i), uno::UNO_QUERY); if(!xSingleShape.is()) continue; OUString aString = XShapeDumper::dump(xSingleShape); @@ -2907,20 +1856,20 @@ OUString ChartView::dump() void ChartView::dumpAsXml(xmlTextWriterPtr pWriter) const { - xmlTextWriterStartElement(pWriter, BAD_CAST("ChartView")); - xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ChartView")); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this); if (m_pDrawModelWrapper) { m_pDrawModelWrapper->dumpAsXml(pWriter); } - xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterEndElement(pWriter); } void ChartView::setViewDirty() { - osl::MutexGuard aGuard(maTimeMutex); + std::unique_lock aGuard(maTimeMutex); m_bViewDirty = true; } @@ -2932,11 +1881,9 @@ IMPL_LINK_NOARG(ChartView, UpdateTimeBased, Timer *, void) void ChartView::createShapes2D( const awt::Size& rPageSize ) { - ShapeFactory* pShapeFactory = ShapeFactory::getOrCreateShapeFactory(m_xShapeFactory); - // todo: it would be nicer to just pass the page m_xDrawPage and format it, // but the draw page does not support XPropertySet - formatPage( mrChartModel, rPageSize, mxRootShape, m_xShapeFactory ); + formatPage( mrChartModel, rPageSize, mxRootShape ); CreateShapeParam2D aParam; aParam.maRemainingSpace.X = 0; @@ -2945,40 +1892,39 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) aParam.maRemainingSpace.Height = rPageSize.Height; //create the group shape for diagram and axes first to have title and legends on top of it - uno::Reference< XDiagram > xDiagram( mrChartModel.getFirstDiagram() ); - uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY); + rtl::Reference< Diagram > xDiagram( mrChartModel.getFirstChartDiagram() ); bool bHasRelativeSize = false; - if( xProp.is() && xProp->getPropertyValue("RelativeSize").hasValue() ) + if( xDiagram.is() && xDiagram->getPropertyValue("RelativeSize").hasValue() ) bHasRelativeSize = true; OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) ) );//todo: other index if more than one diagram is possible - uno::Reference< drawing::XShapes > xDiagramPlusAxesPlusMarkHandlesGroup_Shapes( - pShapeFactory->createGroup2D(mxRootShape,aDiagramCID) ); + rtl::Reference<SvxShapeGroup> xDiagramPlusAxesPlusMarkHandlesGroup_Shapes = + ShapeFactory::createGroup2D(mxRootShape,aDiagramCID); - aParam.mxMarkHandles = pShapeFactory->createInvisibleRectangle( + aParam.mxMarkHandles = ShapeFactory::createInvisibleRectangle( xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0)); ShapeFactory::setShapeName(aParam.mxMarkHandles, "MarkHandles"); - aParam.mxPlotAreaWithAxes = pShapeFactory->createInvisibleRectangle( + aParam.mxPlotAreaWithAxes = ShapeFactory::createInvisibleRectangle( xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0, 0)); ShapeFactory::setShapeName(aParam.mxPlotAreaWithAxes, "PlotAreaIncludingAxes"); - aParam.mxDiagramWithAxesShapes = pShapeFactory->createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes); + aParam.mxDiagramWithAxesShapes = ShapeFactory::createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes); bool bAutoPositionDummy = true; // create buttons - lcl_createButtons(mxRootShape, m_xShapeFactory, mrChartModel, aParam.maRemainingSpace); + lcl_createButtons(mxRootShape, mrChartModel, aParam.maRemainingSpace); lcl_createTitle( - TitleHelper::MAIN_TITLE, mxRootShape, m_xShapeFactory, mrChartModel, - aParam.maRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy); + TitleHelper::MAIN_TITLE, mxRootShape, mrChartModel, + aParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_TOP, bAutoPositionDummy); if (!bHasRelativeSize && (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0)) return; lcl_createTitle( - TitleHelper::SUB_TITLE, mxRootShape, m_xShapeFactory, mrChartModel, - aParam.maRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy ); + TitleHelper::SUB_TITLE, mxRootShape, mrChartModel, + aParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_TOP, bAutoPositionDummy ); if (!bHasRelativeSize && (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0)) return; @@ -2986,7 +1932,7 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) aParam.mpSeriesPlotterContainer->initializeCooSysAndSeriesPlotter( mrChartModel ); if(maTimeBased.bTimeBased && maTimeBased.nFrame != 0) { - SeriesPlottersType& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList(); + auto& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList(); size_t n = rSeriesPlotter.size(); for(size_t i = 0; i < n; ++i) { @@ -3003,7 +1949,7 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) } lcl_createLegend( - LegendHelper::getLegend( mrChartModel ), mxRootShape, m_xShapeFactory, m_xCC, + LegendHelper::getLegend( mrChartModel ), mxRootShape, getComponentContext(), aParam.maRemainingSpace, rPageSize, mrChartModel, aParam.mpSeriesPlotterContainer->getLegendEntryProviderList(), lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) ); @@ -3014,9 +1960,9 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) return; bool bDummy = false; - bool bIsVertical = DiagramHelper::getVertical(xDiagram, bDummy, bDummy); + bool bIsVertical = xDiagram && xDiagram->getVertical(bDummy, bDummy); - if (getAvailablePosAndSizeForDiagram(aParam, rPageSize, xProp)) + if (getAvailablePosAndSizeForDiagram(aParam, rPageSize, xDiagram)) { awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent(aParam, rPageSize); @@ -3029,24 +1975,24 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) //correct axis title position awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect ); if (aParam.mbAutoPosTitleX) - changePositionOfAxisTitle(aParam.mpVTitleX.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleX.get(), TitleAlignment::ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize); if (aParam.mbAutoPosTitleY) - changePositionOfAxisTitle(aParam.mpVTitleY.get(), ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleY.get(), TitleAlignment::ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize); if (aParam.mbAutoPosTitleZ) - changePositionOfAxisTitle(aParam.mpVTitleZ.get(), ALIGN_Z, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleZ.get(), TitleAlignment::ALIGN_Z, aDiagramPlusAxesRect, rPageSize); if (aParam.mbAutoPosSecondTitleX) - changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? ALIGN_RIGHT : ALIGN_TOP, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, aDiagramPlusAxesRect, rPageSize); if (aParam.mbAutoPosSecondTitleY) - changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? ALIGN_TOP : ALIGN_RIGHT, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, aDiagramPlusAxesRect, rPageSize); } //cleanup: remove all empty group shapes to avoid grey border lines: - lcl_removeEmptyGroupShapes( mxRootShape ); + lcl_removeEmptyGroupShapes( *mxRootShape->GetSdrObject() ); if(maTimeBased.bTimeBased && maTimeBased.nFrame % 60 == 0) { // create copy of the data for next frame - SeriesPlottersType& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList(); + auto& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList(); size_t n = rSeriesPlotter.size(); maTimeBased.m_aDataSeriesList.clear(); maTimeBased.m_aDataSeriesList.resize(n); @@ -3075,41 +2021,46 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) bool ChartView::createAxisTitleShapes2D( CreateShapeParam2D& rParam, const css::awt::Size& rPageSize, bool bHasRelativeSize ) { - uno::Reference<XDiagram> xDiagram = mrChartModel.getFirstDiagram(); + rtl::Reference<Diagram> xDiagram = mrChartModel.getFirstChartDiagram(); - Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ); - sal_Int32 nDimension = DiagramHelper::getDimension( xDiagram ); + rtl::Reference< ChartType > xChartType; + sal_Int32 nDimension = 0; + if (xDiagram) + { + xChartType = xDiagram->getChartTypeByIndex( 0 ); + nDimension = xDiagram->getDimension(); + } if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 0 ) ) - rParam.mpVTitleX = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, mxRootShape, m_xShapeFactory, mrChartModel - , rParam.maRemainingSpace, rPageSize, ALIGN_BOTTOM, rParam.mbAutoPosTitleX ); + rParam.mpVTitleX = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, mxRootShape, mrChartModel + , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_BOTTOM, rParam.mbAutoPosTitleX ); if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)) return false; if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 1 ) ) - rParam.mpVTitleY = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, mxRootShape, m_xShapeFactory, mrChartModel - , rParam.maRemainingSpace, rPageSize, ALIGN_LEFT, rParam.mbAutoPosTitleY ); + rParam.mpVTitleY = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, mxRootShape, mrChartModel + , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_LEFT, rParam.mbAutoPosTitleY ); if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)) return false; if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 2 ) ) - rParam.mpVTitleZ = lcl_createTitle( TitleHelper::Z_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel - , rParam.maRemainingSpace, rPageSize, ALIGN_RIGHT, rParam.mbAutoPosTitleZ ); + rParam.mpVTitleZ = lcl_createTitle( TitleHelper::Z_AXIS_TITLE, mxRootShape, mrChartModel + , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_RIGHT, rParam.mbAutoPosTitleZ ); if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)) return false; bool bDummy = false; - bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy ); + bool bIsVertical = xDiagram && xDiagram->getVertical( bDummy, bDummy ); if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension ) ) - rParam.mpVTitleSecondX = lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel - , rParam.maRemainingSpace, rPageSize, bIsVertical? ALIGN_RIGHT : ALIGN_TOP, rParam.mbAutoPosSecondTitleX ); + rParam.mpVTitleSecondX = lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, mxRootShape, mrChartModel + , rParam.maRemainingSpace, rPageSize, bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, rParam.mbAutoPosSecondTitleX ); if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)) return false; if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension ) ) - rParam.mpVTitleSecondY = lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, mxRootShape, m_xShapeFactory, mrChartModel - , rParam.maRemainingSpace, rPageSize, bIsVertical? ALIGN_TOP : ALIGN_RIGHT, rParam.mbAutoPosSecondTitleY ); + rParam.mpVTitleSecondY = lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, mxRootShape, mrChartModel + , rParam.maRemainingSpace, rPageSize, bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, rParam.mbAutoPosSecondTitleY ); if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)) return false; @@ -3122,7 +2073,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_chart2_ChartView_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence<css::uno::Any> const &) { - ::chart::ChartModel *pChartModel = new ::chart::ChartModel(context); + rtl::Reference<::chart::ChartModel> pChartModel = new ::chart::ChartModel(context); return cppu::acquire(new ::chart::ChartView(context, *pChartModel)); } |