diff options
author | Ingrid Halama [iha] <Ingrid.Halama@oracle.com> | 2010-11-30 01:45:03 +0100 |
---|---|---|
committer | Ingrid Halama [iha] <Ingrid.Halama@oracle.com> | 2010-11-30 01:45:03 +0100 |
commit | edaa216847e59ad93b8b99e95f293f8bb04344cc (patch) | |
tree | 7193a7fdd5a3520b21755c675cb4d3de4e3100cb /chart2/source/tools | |
parent | 0e5566e9ff510bedc9837e12ee37103c553897da (diff) |
chart46: #i25706# implement date axis
Diffstat (limited to 'chart2/source/tools')
-rw-r--r-- | chart2/source/tools/AxisHelper.cxx | 41 | ||||
-rw-r--r-- | chart2/source/tools/ChartTypeHelper.cxx | 25 | ||||
-rw-r--r-- | chart2/source/tools/DiagramHelper.cxx | 194 | ||||
-rw-r--r-- | chart2/source/tools/ExplicitCategoriesProvider.cxx | 139 | ||||
-rwxr-xr-x | chart2/source/tools/InternalData.cxx | 42 | ||||
-rw-r--r-- | chart2/source/tools/InternalDataProvider.cxx | 372 |
6 files changed, 673 insertions, 140 deletions
diff --git a/chart2/source/tools/AxisHelper.cxx b/chart2/source/tools/AxisHelper.cxx index 8cdd24e4dc05..506c0a96295a 100644 --- a/chart2/source/tools/AxisHelper.cxx +++ b/chart2/source/tools/AxisHelper.cxx @@ -38,7 +38,9 @@ #include "servicenames_coosystems.hxx" #include "DataSeriesHelper.hxx" #include "Scaling.hxx" +#include "ChartModelHelper.hxx" +#include <tools/debug.hxx> #include <unotools/saveopt.hxx> #include <com/sun/star/chart/ChartAxisPosition.hpp> @@ -81,6 +83,8 @@ ScaleData AxisHelper::createDefaultScale() { ScaleData aScaleData; aScaleData.AxisType = chart2::AxisType::REALNUMBER; + aScaleData.AutoDateAxis = true; + aScaleData.ShiftedCategoryPosition = false;//this is adapted in the view code currently Sequence< SubIncrement > aSubIncrements(1); aSubIncrements[0] = SubIncrement(); aScaleData.IncrementData.SubIncrements = aSubIncrements; @@ -93,6 +97,9 @@ void AxisHelper::removeExplicitScaling( ScaleData& rScaleData ) uno::Any aEmpty; rScaleData.Minimum = rScaleData.Maximum = rScaleData.Origin = aEmpty; rScaleData.Scaling = 0; + ScaleData aDefaultScale( createDefaultScale() ); + rScaleData.IncrementData = aDefaultScale.IncrementData; + rScaleData.TimeIncrement = aDefaultScale.TimeIncrement; } //static @@ -105,6 +112,39 @@ bool AxisHelper::isLogarithmic( const Reference< XScaling >& xScaling ) return bReturn; } +chart2::ScaleData AxisHelper::getDateCheckedScale( const Reference< chart2::XAxis >& xAxis, const Reference< frame::XModel >& xChartModel ) +{ + DBG_ASSERT(xChartModel.is(),"missing chart model"); + ScaleData aScale = xAxis->getScaleData(); + Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); + if( aScale.AutoDateAxis && aScale.AxisType == AxisType::CATEGORY ) + { + sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0; + AxisHelper::getIndicesForAxis(xAxis, xCooSys, nDimensionIndex, nAxisIndex ); + bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), 2, nDimensionIndex ); + if( bChartTypeAllowsDateAxis ) + aScale.AxisType = AxisType::DATE; + } + if( aScale.AxisType == AxisType::DATE ) + { + ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys,xChartModel ); + if( !aExplicitCategoriesProvider.isDateAxis() ) + aScale.AxisType = AxisType::CATEGORY; + } + return aScale; +} + +void AxisHelper::checkDateAxis( chart2::ScaleData& rScale, ExplicitCategoriesProvider* pExplicitCategoriesProvider, bool bChartTypeAllowsDateAxis ) +{ + if( rScale.AutoDateAxis && rScale.AxisType == AxisType::CATEGORY && bChartTypeAllowsDateAxis ) + rScale.AxisType = AxisType::DATE; + if( rScale.AxisType == AxisType::DATE && (!pExplicitCategoriesProvider || !pExplicitCategoriesProvider->isDateAxis()) ) + { + rScale.AxisType = AxisType::CATEGORY; + removeExplicitScaling( rScale ); + } +} + //static Reference< XAxis > AxisHelper::createAxis( sal_Int32 nDimensionIndex @@ -137,6 +177,7 @@ Reference< XAxis > AxisHelper::createAxis( ScaleData aMainScale = xMainAxis->getScaleData(); aScale.AxisType = aMainScale.AxisType; + aScale.AutoDateAxis = aMainScale.AutoDateAxis; aScale.Categories = aMainScale.Categories; aScale.Orientation = aMainScale.Orientation; diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx index b851a3864b97..cd0a62312387 100644 --- a/chart2/source/tools/ChartTypeHelper.cxx +++ b/chart2/source/tools/ChartTypeHelper.cxx @@ -415,13 +415,34 @@ bool ChartTypeHelper::isSupportingAxisPositioning( const uno::Reference< chart2: return true; } -bool ChartTypeHelper::shiftTicksAtXAxisPerDefault( const uno::Reference< chart2::XChartType >& xChartType ) +bool ChartTypeHelper::isSupportingDateAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 /*nDimensionCount*/, sal_Int32 nDimensionIndex ) +{ + if( nDimensionIndex!=0 ) + return false; + if( xChartType.is() ) + { + sal_Int32 nType = ChartTypeHelper::getAxisType( xChartType, nDimensionIndex ); + if( nType != AxisType::CATEGORY ) + return false; + rtl::OUString aChartTypeName = xChartType->getChartType(); + if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) + return false; + if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) ) + return false; + if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) ) + return false; + } + return true; +} + +bool ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( const uno::Reference< chart2::XChartType >& xChartType ) { if(xChartType.is()) { rtl::OUString aChartTypeName = xChartType->getChartType(); if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) - || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) ) + || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) + || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) ) return true; } return false; diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx index 36afef60a6d4..d19e8819f069 100644 --- a/chart2/source/tools/DiagramHelper.cxx +++ b/chart2/source/tools/DiagramHelper.cxx @@ -46,6 +46,7 @@ #include <com/sun/star/chart/MissingValueTreatment.hpp> #include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/chart/XDiagramPositioning.hpp> +#include <com/sun/star/chart2/XAnyDescriptionAccess.hpp> #include <com/sun/star/chart2/XTitled.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XChartTypeTemplate.hpp> @@ -57,10 +58,15 @@ #include <com/sun/star/chart2/RelativePosition.hpp> #include <com/sun/star/chart2/RelativeSize.hpp> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> + #include <unotools/saveopt.hxx> #include <rtl/math.hxx> -#include <com/sun/star/util/XModifiable.hpp> +// header for class Application +#include <vcl/svapp.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::chart2; @@ -68,7 +74,9 @@ using namespace ::std; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; using ::rtl::OUString; +using ::com::sun::star::chart2::XAnyDescriptionAccess; namespace chart { @@ -880,7 +888,7 @@ bool DiagramHelper::isCategoryDiagram( if( xAxis.is()) { ScaleData aScaleData = xAxis->getScaleData(); - if( aScaleData.AxisType == AxisType::CATEGORY ) + if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE ) return true; } } @@ -919,7 +927,7 @@ void DiagramHelper::setCategoriesToDiagram( { if( bCategoryAxis ) aScaleData.AxisType = AxisType::CATEGORY; - else if( aScaleData.AxisType == AxisType::CATEGORY ) + else if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE ) aScaleData.AxisType = AxisType::REALNUMBER; } xCatAxis->setScaleData( aScaleData ); @@ -1037,6 +1045,186 @@ Sequence< rtl::OUString > DiagramHelper::getExplicitSimpleCategories( return aRet; } +bool DiagramHelper::mayToggleDateCategories( const Reference< XChartDocument >& xChartDoc ) +{ + Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); + if(xChartModel.is()) + { + Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); + if( xCooSys.is() ) + { + Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) ); + if( xAxis.is() ) + { + ScaleData aScale( xAxis->getScaleData() ); + if( aScale.AxisType == chart2::AxisType::DATE || aScale.AxisType == chart2::AxisType::CATEGORY ) + return true; + } + } + } + return false; +} + +namespace +{ +void lcl_switchToDateCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis ) +{ + if( !xAxis.is() ) + return; + if( !xChartDoc.is() ) + return; + + ScaleData aScale( xAxis->getScaleData() ); + if( xChartDoc->hasInternalDataProvider() ) + { + //remove all content the is not of type double and remove multiple level + Reference< XAnyDescriptionAccess > xDataAccess( xChartDoc->getDataProvider(), uno::UNO_QUERY ); + if( xDataAccess.is() ) + { + Sequence< Sequence< Any > > aAnyCategories( xDataAccess->getAnyRowDescriptions() ); + double fTest = 0.0; + double fNan = 0.0; + ::rtl::math::setNan( & fNan ); + sal_Int32 nN = aAnyCategories.getLength(); + for( ; nN--; ) + { + Sequence< Any >& rCat = aAnyCategories[nN]; + if( rCat.getLength() > 1 ) + rCat.realloc(1); + if( rCat.getLength() == 1 ) + { + Any& rAny = rCat[0]; + if( !(rAny>>=fTest) ) + { + rAny = uno::makeAny(fNan); + } + } + } + xDataAccess->setAnyRowDescriptions( aAnyCategories ); + } + //check the numberformat at the axis + Reference< beans::XPropertySet > xAxisProps( xAxis, uno::UNO_QUERY ); + Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartDoc, uno::UNO_QUERY ); + if( xAxisProps.is() && xNumberFormatsSupplier.is() ) + { + sal_Int32 nNumberFormat = -1; + xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nNumberFormat; + + Reference< util::XNumberFormats > xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); + if( xNumberFormats.is() ) + { + Reference< beans::XPropertySet > xKeyProps; + try + { + xKeyProps = xNumberFormats->getByKey( nNumberFormat ); + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + sal_Int32 nType = util::NumberFormat::UNDEFINED; + if( xKeyProps.is() ) + xKeyProps->getPropertyValue( C2U("Type") ) >>= nType; + if( nType!=util::NumberFormat::DATE && nType!=util::NumberFormat::DATETIME ) + { + //set a date format to the axis + sal_Bool bCreate = sal_True; + const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); + Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::DATE, rLocaleDataWrapper.getLocale(), bCreate ); + if( aKeySeq.getLength() ) + { + xAxisProps->setPropertyValue( C2U("NumberFormat"), uno::makeAny(aKeySeq[0]) ); + } + } + } + } + } + if( aScale.AxisType != chart2::AxisType::DATE ) + AxisHelper::removeExplicitScaling( aScale ); + aScale.AxisType = chart2::AxisType::DATE; + xAxis->setScaleData( aScale ); +} + +void lcl_switchToTextCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis ) +{ + if( !xAxis.is() ) + return; + if( !xChartDoc.is() ) + return; + ScaleData aScale( xAxis->getScaleData() ); + if( aScale.AxisType != chart2::AxisType::CATEGORY ) + AxisHelper::removeExplicitScaling( aScale ); + //todo migrate dates to text? + aScale.AxisType = chart2::AxisType::CATEGORY; + aScale.AutoDateAxis = false; + xAxis->setScaleData( aScale ); +} + +} + +void DiagramHelper::switchToDateCategories( const Reference< XChartDocument >& xChartDoc ) +{ + Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); + if(xChartModel.is()) + { + ControllerLockGuard aCtrlLockGuard( xChartModel ); + + Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); + if( xCooSys.is() ) + { + Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) ); + lcl_switchToDateCategories( xChartDoc, xAxis ); + } + } +} + +void DiagramHelper::switchToTextCategories( const Reference< XChartDocument >& xChartDoc ) +{ + Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); + if(xChartModel.is()) + { + ControllerLockGuard aCtrlLockGuard( xChartModel ); + + Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); + if( xCooSys.is() ) + { + Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) ); + lcl_switchToTextCategories( xChartDoc, xAxis ); + } + } +} + +void DiagramHelper::toggleDateCategories( const Reference< XChartDocument >& xChartDoc ) +{ + Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); + if(xChartModel.is()) + { + ControllerLockGuard aCtrlLockGuard( xChartModel ); + + Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); + if( xCooSys.is() ) + { + Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) ); + if( xAxis.is() ) + { + ScaleData aScale( xAxis->getScaleData() ); + if( aScale.AxisType == chart2::AxisType::DATE ) + { + lcl_switchToTextCategories( xChartDoc, xAxis ); + } + else if( aScale.AxisType == chart2::AxisType::CATEGORY ) + { + lcl_switchToDateCategories( xChartDoc, xAxis ); + } + else + { + DBG_ERROR("Cannot toggle Date Categories for this axis type"); + } + } + } + } +} + // static Sequence< Reference< XChartType > > DiagramHelper::getChartTypesFromDiagram( diff --git a/chart2/source/tools/ExplicitCategoriesProvider.cxx b/chart2/source/tools/ExplicitCategoriesProvider.cxx index bd1c1bb79813..5411e94ee18c 100644 --- a/chart2/source/tools/ExplicitCategoriesProvider.cxx +++ b/chart2/source/tools/ExplicitCategoriesProvider.cxx @@ -30,12 +30,18 @@ #include "ExplicitCategoriesProvider.hxx" #include "DiagramHelper.hxx" +#include "ChartTypeHelper.hxx" +#include "AxisHelper.hxx" #include "CommonConverters.hxx" #include "DataSourceHelper.hxx" #include "ChartModelHelper.hxx" #include "ContainerHelper.hxx" #include "macros.hxx" +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> + //............................................................................. namespace chart { @@ -53,7 +59,10 @@ ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2: , const uno::Reference< frame::XModel >& xChartModel ) : m_bDirty(true) , m_xCooSysModel( xCooSysModel ) + , m_xChartModel( xChartModel ) , m_xOriginalCategories() + , m_bIsDateAxis(false) + , m_bIsAutoDate(false) { try { @@ -61,7 +70,12 @@ ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2: { uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) ); if( xAxis.is() ) - m_xOriginalCategories = xAxis->getScaleData().Categories; + { + ScaleData aScale( xAxis->getScaleData() ); + m_xOriginalCategories = aScale.Categories; + m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY); + m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate); + } } if( m_xOriginalCategories.is() ) @@ -134,6 +148,13 @@ ExplicitCategoriesProvider::~ExplicitCategoriesProvider() { } +Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories() +{ + if( m_xOriginalCategories.is() ) + return m_xOriginalCategories->getValues(); + return 0; +} + const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList() { return m_aSplitCategoriesList; @@ -363,21 +384,125 @@ Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories( return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats ); } +struct DatePlusIndexComparator +{ + inline bool operator() ( const DatePlusIndex& aFirst, + const DatePlusIndex& aSecond ) + { + return ( aFirst.fValue < aSecond.fValue ); + } +}; + +bool lcl_isDateFormat( sal_Int32 nNumberFormat, const Reference< util::XNumberFormats >& xNumberFormats ) +{ + bool bIsDate = false; + if( !xNumberFormats.is() ) + return bIsDate; + + Reference< beans::XPropertySet > xKeyProps = xNumberFormats->getByKey( nNumberFormat ); + if( xKeyProps.is() ) + { + sal_Int32 nType = util::NumberFormat::DATETIME; + xKeyProps->getPropertyValue( C2U("Type") ) >>= nType; + bIsDate = (nType==util::NumberFormat::DATE || nType==util::NumberFormat::DATETIME); + } + return bIsDate; +} + +bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier ) +{ + bool bOnlyDatesFound = true; + + if( xDataSequence.is() ) + { + uno::Sequence< uno::Any > aValues = xDataSequence->getData(); + sal_Int32 nCount = aValues.getLength(); + rDateCategories.reserve(nCount); + Reference< util::XNumberFormats > xNumberFormats; + if( xNumberFormatsSupplier.is() ) + xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); + + bool bOwnData = false; + bool bOwnDataAndDateFormat = false; + sal_Int32 nAxisNumberFormat = 0; + Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY ); + Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ); + if( xChartDoc.is() && xCooSysModel.is() ) + { + if( xChartDoc->hasInternalDataProvider() ) + { + bOwnData = true; + Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY ); + if( xAxisProps.is() && (xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nAxisNumberFormat) ) + bOwnDataAndDateFormat = lcl_isDateFormat( nAxisNumberFormat, xNumberFormats ); + } + } + + for(sal_Int32 nN=0;nN<nCount;nN++) + { + bool bIsDate = false; + if( bIsAutoDate ) + { + if( bOwnData ) + bIsDate = bOwnDataAndDateFormat; + else + bIsDate = lcl_isDateFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats ); + } + else + bIsDate = true; + + uno::Any aAny = aValues[nN]; + DatePlusIndex aDatePlusIndex( 1.0, nN ); + if( bIsDate && (aAny >>= aDatePlusIndex.fValue) ) + rDateCategories.push_back( aDatePlusIndex ); + else + { + if( aAny.hasValue() ) + { + OUString aTest; + if( !( (aAny>>=aTest) && !aTest.getLength() ) )//empty string does not count as non date value! + bOnlyDatesFound=false; + } + ::rtl::math::setNan( &aDatePlusIndex.fValue ); + rDateCategories.push_back( aDatePlusIndex ); + } + } + ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() ); + } + + return bOnlyDatesFound; +} + void ExplicitCategoriesProvider::init() { if( m_bDirty ) { m_aExplicitCategories.realloc(0); m_aComplexCats.clear();//not one per index + m_aDateCategories.clear(); if( m_xOriginalCategories.is() ) { if( !hasComplexCategories() ) + { m_aExplicitCategories = DataSequenceToStringSequence(m_xOriginalCategories->getValues()); + if(m_bIsDateAxis) + { + if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) ) + m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) ); + else + m_bIsDateAxis = false; + } + } else + { m_aExplicitCategories = lcl_getExplicitSimpleCategories( SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList ), m_aComplexCats ); + m_bIsDateAxis = false; + } } + else + m_bIsDateAxis=false; if(!m_aExplicitCategories.getLength()) m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel ); m_bDirty = false; @@ -417,6 +542,18 @@ OUString ExplicitCategoriesProvider::getCategoryByIndex( return OUString(); } +bool ExplicitCategoriesProvider::isDateAxis() +{ + init(); + return m_bIsDateAxis; +} + +const std::vector< DatePlusIndex >& ExplicitCategoriesProvider::getDateCategories() +{ + init(); + return m_aDateCategories; +} + //............................................................................. } //namespace chart //............................................................................. diff --git a/chart2/source/tools/InternalData.cxx b/chart2/source/tools/InternalData.cxx index 65fc97a04b38..e9b0cf689768 100755 --- a/chart2/source/tools/InternalData.cxx +++ b/chart2/source/tools/InternalData.cxx @@ -38,6 +38,7 @@ using ::com::sun::star::uno::Sequence; using ::rtl::OUString; +using namespace ::com::sun::star; using namespace ::std; namespace chart @@ -55,10 +56,10 @@ struct lcl_NumberedStringGenerator m_nWildcardLength( rWildcard.getLength()) { } - vector< OUString > operator()() + vector< uno::Any > operator()() { - vector< OUString > aRet(1); - aRet[0] = m_aStub.replaceAt( m_nStubStartIndex, m_nWildcardLength, OUString::valueOf( ++m_nCounter )); + vector< uno::Any > aRet(1); + aRet[0] = uno::makeAny( m_aStub.replaceAt( m_nStubStartIndex, m_nWildcardLength, OUString::valueOf( ++m_nCounter )) ); return aRet; } private: @@ -113,12 +114,12 @@ void InternalData::createDefaultData() m_aRowLabels.clear(); m_aRowLabels.reserve( m_nRowCount ); generate_n( back_inserter( m_aRowLabels ), m_nRowCount, - lcl_NumberedStringGenerator( aRowName, C2U("%ROWNUMBER") )); + lcl_NumberedStringGenerator( aRowName, C2U("%ROWNUMBER") )); m_aColumnLabels.clear(); m_aColumnLabels.reserve( m_nColumnCount ); generate_n( back_inserter( m_aColumnLabels ), m_nColumnCount, - lcl_NumberedStringGenerator( aColName, C2U("%COLUMNNUMBER") )); + lcl_NumberedStringGenerator( aColName, C2U("%COLUMNNUMBER") )); } void InternalData::setData( const Sequence< Sequence< double > >& rDataInRows ) @@ -199,7 +200,7 @@ void InternalData::setRowValues( sal_Int32 nRowIndex, const vector< double > & r m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]= aSlice; } -void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< OUString >& rComplexLabel ) +void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< uno::Any >& rComplexLabel ) { if( nColumnIndex < 0 ) return; @@ -208,10 +209,10 @@ void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< m_aColumnLabels.resize(nColumnIndex+1); enlargeData( nColumnIndex+1, 0 ); } - m_aColumnLabels[nColumnIndex]=rComplexLabel; } -void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< OUString >& rComplexLabel ) + +void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< uno::Any >& rComplexLabel ) { if( nRowIndex < 0 ) return; @@ -220,23 +221,22 @@ void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< OUStri m_aRowLabels.resize(nRowIndex+1); enlargeData( 0, nRowIndex+1 ); } - m_aRowLabels[nRowIndex] = rComplexLabel; } -vector< OUString > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const +vector< uno::Any > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const { if( nColumnIndex < static_cast< sal_Int32 >( m_aColumnLabels.size() ) ) return m_aColumnLabels[nColumnIndex]; else - return vector< OUString >(); + return vector< uno::Any >(); } -vector< OUString > InternalData::getComplexRowLabel( sal_Int32 nRowIndex ) const +vector< uno::Any > InternalData::getComplexRowLabel( sal_Int32 nRowIndex ) const { if( nRowIndex < static_cast< sal_Int32 >( m_aRowLabels.size() ) ) return m_aRowLabels[nRowIndex]; else - return vector< OUString >(); + return vector< uno::Any >(); } void InternalData::swapRowWithNext( sal_Int32 nRowIndex ) @@ -253,7 +253,7 @@ void InternalData::swapRowWithNext( sal_Int32 nRowIndex ) m_aData[nIndex2] = fTemp; } - vector< OUString > aTemp( m_aRowLabels[nRowIndex] ); + vector< uno::Any > aTemp( m_aRowLabels[nRowIndex] ); m_aRowLabels[nRowIndex] = m_aRowLabels[nRowIndex + 1]; m_aRowLabels[nRowIndex + 1] = aTemp; } @@ -273,7 +273,7 @@ void InternalData::swapColumnWithNext( sal_Int32 nColumnIndex ) m_aData[nIndex2] = fTemp; } - vector< OUString > aTemp( m_aColumnLabels[nColumnIndex] ); + vector< uno::Any > aTemp( m_aColumnLabels[nColumnIndex] ); m_aColumnLabels[nColumnIndex] = m_aColumnLabels[nColumnIndex + 1]; m_aColumnLabels[nColumnIndex + 1] = aTemp; } @@ -336,7 +336,7 @@ void InternalData::insertColumn( sal_Int32 nAfterIndex ) // labels if( nAfterIndex < static_cast< sal_Int32 >( m_aColumnLabels.size())) - m_aColumnLabels.insert( m_aColumnLabels.begin() + (nAfterIndex + 1), vector< OUString >(1) ); + m_aColumnLabels.insert( m_aColumnLabels.begin() + (nAfterIndex + 1), vector< uno::Any >(1) ); #if OSL_DEBUG_LEVEL > 2 traceData(); @@ -388,7 +388,7 @@ void InternalData::insertRow( sal_Int32 nAfterIndex ) // labels if( nAfterIndex < static_cast< sal_Int32 >( m_aRowLabels.size())) - m_aRowLabels.insert( m_aRowLabels.begin() + nIndex, vector< OUString> (1)); + m_aRowLabels.insert( m_aRowLabels.begin() + nIndex, vector< uno::Any > (1)); #if OSL_DEBUG_LEVEL > 2 traceData(); @@ -481,7 +481,7 @@ sal_Int32 InternalData::getColumnCount() const return m_nColumnCount; } -void InternalData::setComplexRowLabels( const vector< vector< OUString > >& rNewRowLabels ) +void InternalData::setComplexRowLabels( const vector< vector< uno::Any > >& rNewRowLabels ) { m_aRowLabels = rNewRowLabels; sal_Int32 nNewRowCount = static_cast< sal_Int32 >( m_aRowLabels.size() ); @@ -491,12 +491,12 @@ void InternalData::setComplexRowLabels( const vector< vector< OUString > >& rNew enlargeData( 0, nNewRowCount ); } -vector< vector< OUString > > InternalData::getComplexRowLabels() const +vector< vector< uno::Any > > InternalData::getComplexRowLabels() const { return m_aRowLabels; } -void InternalData::setComplexColumnLabels( const vector< vector< OUString > >& rNewColumnLabels ) +void InternalData::setComplexColumnLabels( const vector< vector< uno::Any > >& rNewColumnLabels ) { m_aColumnLabels = rNewColumnLabels; sal_Int32 nNewColumnCount = static_cast< sal_Int32 >( m_aColumnLabels.size() ); @@ -506,7 +506,7 @@ void InternalData::setComplexColumnLabels( const vector< vector< OUString > >& r enlargeData( nNewColumnCount, 0 ); } -vector< vector< OUString > > InternalData::getComplexColumnLabels() const +vector< vector< uno::Any > > InternalData::getComplexColumnLabels() const { return m_aColumnLabels; } diff --git a/chart2/source/tools/InternalDataProvider.cxx b/chart2/source/tools/InternalDataProvider.cxx index 4abc51be31af..b3f3058d6f05 100644 --- a/chart2/source/tools/InternalDataProvider.cxx +++ b/chart2/source/tools/InternalDataProvider.cxx @@ -93,6 +93,24 @@ static const ::rtl::OUString lcl_aCompleteRange( typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > > lcl_tSequenceMap; +Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq ) +{ + Sequence< OUString > aResult; + aResult.realloc( aAnySeq.getLength() ); + transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(), + aResult.getArray(), CommonFunctors::AnyToString() ); + return aResult; +} + +Sequence< uno::Any > lcl_StringToAnySequence( const Sequence< OUString >& aStringSeq ) +{ + Sequence< uno::Any > aResult; + aResult.realloc( aStringSeq.getLength() ); + transform( aStringSeq.getConstArray(), aStringSeq.getConstArray() + aStringSeq.getLength(), + aResult.getArray(), CommonFunctors::makeAny< OUString >() ); + return aResult; +} + struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void > { void operator() ( const lcl_tSequenceMap::value_type & rMapEntry ) @@ -154,9 +172,9 @@ struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2:: if( xLabel.is() ) { if( m_bDataInColumns ) - m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( xLabel->getTextualData() ) ); + m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) ); else - m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( xLabel->getTextualData() ) ); + m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) ); if( m_bConnectToModel ) { Reference< chart2::data::XDataSequence > xNewLabel( @@ -187,37 +205,37 @@ private: bool m_bDataInColumns; }; -struct lcl_makeAnyFromLevelVector : public ::std::unary_function< vector< OUString >, uno::Any > +struct lcl_copyFromLevel : public ::std::unary_function< vector< uno::Any >, uno::Any > { public: - explicit lcl_makeAnyFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel ) + explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) {} - uno::Any operator() ( const vector< OUString >& rVector ) + uno::Any operator() ( const vector< uno::Any >& rVector ) { - OUString aString; + uno::Any aRet; if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) ) - aString = rVector[m_nLevel]; - return uno::makeAny( aString ); + aRet = rVector[m_nLevel]; + return aRet; } private: sal_Int32 m_nLevel; }; -struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< OUString >, OUString > +struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< uno::Any >, OUString > { public: explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel ) {} - OUString operator() ( const vector< OUString >& rVector ) + OUString operator() ( const vector< uno::Any >& rVector ) { OUString aString; if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) ) - aString = rVector[m_nLevel]; + aString = CommonFunctors::AnyToString()(rVector[m_nLevel]); return aString; } @@ -226,19 +244,39 @@ private: }; -struct lcl_setStringAtLevel : public ::std::binary_function< vector< OUString >, OUString, vector< OUString > > +struct lcl_setAnyAtLevel : public ::std::binary_function< vector< uno::Any >, uno::Any, vector< uno::Any > > +{ +public: + + explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) + {} + + vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue ) + { + vector< uno::Any > aRet( rVector ); + if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) ) + aRet.resize( m_nLevel+1 ); + aRet[ m_nLevel ]=rNewValue; + return aRet; + } + +private: + sal_Int32 m_nLevel; +}; + +struct lcl_setAnyAtLevelFromStringSequence : public ::std::binary_function< vector< uno::Any >, OUString, vector< uno::Any > > { public: - explicit lcl_setStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) + explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel ) {} - vector< OUString > operator() ( const vector< OUString >& rVector, const OUString& rNewText ) + vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue ) { - vector< OUString > aRet( rVector ); + vector< uno::Any > aRet( rVector ); if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) ) aRet.resize( m_nLevel+1 ); - aRet[ m_nLevel ]=rNewText; + aRet[ m_nLevel ]=uno::makeAny(rNewValue); return aRet; } @@ -246,41 +284,41 @@ private: sal_Int32 m_nLevel; }; -struct lcl_insertStringAtLevel : public ::std::unary_function< vector< OUString >, void > +struct lcl_insertAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void > { public: - explicit lcl_insertStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) + explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) {} - void operator() ( vector< OUString >& rVector ) + void operator() ( vector< uno::Any >& rVector ) { if( m_nLevel > static_cast< sal_Int32 >(rVector.size()) ) rVector.resize( m_nLevel ); - vector< OUString >::iterator aIt( rVector.begin() ); + vector< uno::Any >::iterator aIt( rVector.begin() ); for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++) { if( nN==m_nLevel ) break; } - rVector.insert( aIt, OUString() ); + rVector.insert( aIt, uno::Any() ); } private: sal_Int32 m_nLevel; }; -struct lcl_removeStringAtLevel : public ::std::unary_function< vector< OUString >, void > +struct lcl_removeAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void > { public: - explicit lcl_removeStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) + explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) {} - void operator() ( vector< OUString >& rVector ) + void operator() ( vector< uno::Any >& rVector ) { - vector< OUString >::iterator aIt( rVector.begin() ); + vector< uno::Any >::iterator aIt( rVector.begin() ); for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++) { if( nN==m_nLevel ) @@ -295,23 +333,6 @@ private: sal_Int32 m_nLevel; }; -vector< OUString > lcl_AnyToStringVector( const Sequence< uno::Any >& aAnySeq ) -{ - vector< OUString > aStringVec; - transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(), - back_inserter( aStringVec ), CommonFunctors::AnyToString() ); - return aStringVec; -} - -Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq ) -{ - Sequence< OUString > aResult; - aResult.realloc( aAnySeq.getLength() ); - transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(), - aResult.getArray(), CommonFunctors::AnyToString() ); - return aResult; -} - } // anonymous namespace // ================================================================================ @@ -341,9 +362,11 @@ InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocum // categories { - vector< vector< OUString > > aNewCategories;//inner count is level + vector< vector< uno::Any > > aNewCategories;//inner count is level { ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel ); + bool bIsDateAxis = aExplicitCategoriesProvider.isDateAxis(); + const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() ); sal_Int32 nLevelCount = rSplitCategoriesList.getLength(); for( sal_Int32 nL = 0; nL<nLevelCount; nL++ ) @@ -351,16 +374,24 @@ InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocum Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] ); if( !xLDS.is() ) continue; - Reference< chart2::data::XTextualDataSequence > xSeq( xLDS->getValues(), uno::UNO_QUERY ); - Sequence< OUString > aStringSeq; - if( xSeq.is() ) - aStringSeq = xSeq->getTextualData(); // @todo: be able to deal with XDataSequence, too - sal_Int32 nLength = aStringSeq.getLength(); + Sequence< uno::Any > aDataSeq; + Reference< chart2::data::XTextualDataSequence > xTextSeq( xLDS->getValues(), uno::UNO_QUERY ); + if( !bIsDateAxis && xTextSeq.is() ) + { + aDataSeq = lcl_StringToAnySequence( xTextSeq->getTextualData() ); + } + else + { + Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() ); + if( xSeq.is() ) + aDataSeq = xSeq->getData(); + } + sal_Int32 nLength = aDataSeq.getLength(); if( static_cast< sal_Int32 >(aNewCategories.size()) < nLength ) aNewCategories.resize( nLength ); - transform( aNewCategories.begin(), aNewCategories.end(), aStringSeq.getConstArray(), - aNewCategories.begin(), lcl_setStringAtLevel(nL) ); + transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(), + aNewCategories.begin(), lcl_setAnyAtLevel(nL) ); } if( !nLevelCount ) { @@ -369,9 +400,9 @@ InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocum aNewCategories.reserve( nLength ); for( sal_Int32 nN=0; nN<nLength; nN++) { - vector< OUString > aStringVector(1); - aStringVector[0] = aSimplecategories[nN]; - aNewCategories.push_back( aStringVector ); + vector< uno::Any > aVector(1); + aVector[0] = uno::makeAny( aSimplecategories[nN] ); + aNewCategories.push_back( aVector ); } } } @@ -518,14 +549,14 @@ void InternalDataProvider::createDefaultData() namespace { -sal_Int32 lcl_getInnerLevelCount( const vector< vector< OUString > >& rLabels ) +sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels ) { sal_Int32 nCount = 1;//minimum is 1! - vector< vector< OUString > >::const_iterator aLevelIt( rLabels.begin() ); - vector< vector< OUString > >::const_iterator aLevelEnd( rLabels.end() ); + vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() ); + vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() ); for( ;aLevelIt!=aLevelEnd; ++aLevelIt ) { - const vector< ::rtl::OUString >& rCurrentLevelLabels = *aLevelIt; + const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt; nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount ); } return nCount; @@ -549,7 +580,7 @@ Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createData { //return split complex categories if we have any: ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories; - vector< vector< OUString > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); + vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); if( bUseColumns==m_bDataInColumns ) { sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); @@ -731,46 +762,74 @@ Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation if( aRange.match( lcl_aLabelRangePrefix ) ) { sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); - vector< OUString > aComplexLabel = m_bDataInColumns + vector< uno::Any > aComplexLabel = m_bDataInColumns ? m_aInternalData.getComplexColumnLabel( nIndex ) : m_aInternalData.getComplexRowLabel( nIndex ); if( !aComplexLabel.empty() ) - { - aResult.realloc( aComplexLabel.size() ); - transform( aComplexLabel.begin(), aComplexLabel.end(), - aResult.getArray(), CommonFunctors::makeAny< OUString >()); - } + aResult = ContainerHelper::ContainerToSequence(aComplexLabel); } else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) { sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32(); - vector< OUString > aComplexCategory = m_bDataInColumns + vector< uno::Any > aComplexCategory = m_bDataInColumns ? m_aInternalData.getComplexRowLabel( nPointIndex ) : m_aInternalData.getComplexColumnLabel( nPointIndex ); if( !aComplexCategory.empty() ) - { - aResult.realloc( aComplexCategory.size() ); - transform( aComplexCategory.begin(), aComplexCategory.end(), - aResult.getArray(), CommonFunctors::makeAny< OUString >()); - } + aResult = ContainerHelper::ContainerToSequence(aComplexCategory); } else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) { sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32(); - vector< vector< OUString > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); + vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); if( nLevel < lcl_getInnerLevelCount( aCategories ) ) { aResult.realloc( aCategories.size() ); transform( aCategories.begin(), aCategories.end(), - aResult.getArray(), lcl_makeAnyFromLevelVector(nLevel) ); + aResult.getArray(), lcl_copyFromLevel(nLevel) ); } } else if( aRange.equals( lcl_aCategoriesRangeName ) ) { - Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions(); - aResult.realloc( aLabels.getLength() ); - transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(), - aResult.getArray(), CommonFunctors::makeAny< OUString >() ); + bool bReturnText = true; + vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); + sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); + if( nLevelCount == 1 ) + { + sal_Int32 nL=0; + aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) ); + bool bOnlyDatesFound = true; + double fTest = 0.0; + OUString aTest; + for(sal_Int32 nN=aResult.getLength(); nN--;) + { + uno::Any aAny(aResult[nN]); + if( !( aAny >>= fTest) ) + { + if( aAny.hasValue() ) + { + if( (aAny>>=aTest) && !aTest.getLength() ) + { + //empty string does not count as non date value! + aResult[nN] = uno::Any(); + } + else + { + bOnlyDatesFound=false; + break; + } + } + } + } + if( bOnlyDatesFound ) + bReturnText = false; + } + if( bReturnText ) + { + Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions(); + aResult.realloc( aLabels.getLength() ); + transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(), + aResult.getArray(), CommonFunctors::makeAny< OUString >() ); + } } else { @@ -798,38 +857,36 @@ void SAL_CALL InternalDataProvider::setDataByRangeRepresentation( const OUString& aRange, const Sequence< uno::Any >& aNewData ) throw (uno::RuntimeException) { + vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) ); if( aRange.match( lcl_aLabelRangePrefix ) ) { - vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) ); sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); if( m_bDataInColumns ) - m_aInternalData.setComplexColumnLabel( nIndex, aNewStrings ); + m_aInternalData.setComplexColumnLabel( nIndex, aNewVector ); else - m_aInternalData.setComplexRowLabel( nIndex, aNewStrings ); + m_aInternalData.setComplexRowLabel( nIndex, aNewVector ); } else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) { - vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) ); sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); if( m_bDataInColumns ) - m_aInternalData.setComplexRowLabel( nPointIndex, aNewStrings ); + m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector ); else - m_aInternalData.setComplexColumnLabel( nPointIndex, aNewStrings ); + m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector ); } else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) { - vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) ); sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); - vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); + vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); //ensure equal length - if( aNewStrings.size() > aComplexCategories.size() ) - aComplexCategories.resize( aNewStrings.size() ); - else if( aNewStrings.size() < aComplexCategories.size() ) - aNewStrings.resize( aComplexCategories.size() ); + if( aNewVector.size() > aComplexCategories.size() ) + aComplexCategories.resize( aNewVector.size() ); + else if( aNewVector.size() < aComplexCategories.size() ) + aNewVector.resize( aComplexCategories.size() ); - transform( aComplexCategories.begin(), aComplexCategories.end(), aNewStrings.begin(), - aComplexCategories.begin(), lcl_setStringAtLevel(nLevel) ); + transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), + aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) ); if( m_bDataInColumns ) m_aInternalData.setComplexRowLabels( aComplexCategories ); @@ -838,10 +895,14 @@ void SAL_CALL InternalDataProvider::setDataByRangeRepresentation( } else if( aRange.equals( lcl_aCategoriesRangeName ) ) { + vector< vector< uno::Any > > aComplexCategories; + aComplexCategories.resize( aNewVector.size() ); + transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), + aComplexCategories.begin(), lcl_setAnyAtLevel(0) ); if( m_bDataInColumns ) - this->setRowDescriptions( lcl_AnyToStringSequence(aNewData) ); + m_aInternalData.setComplexRowLabels( aComplexCategories ); else - this->setColumnDescriptions( lcl_AnyToStringSequence(aNewData) ); + m_aInternalData.setComplexColumnLabels( aComplexCategories ); } else { @@ -906,8 +967,8 @@ void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error if( nLevel>0 ) { - vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); - ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertStringAtLevel(nLevel) ); + vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); + ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) ); if( m_bDataInColumns ) m_aInternalData.setComplexRowLabels( aComplexCategories ); else @@ -923,8 +984,8 @@ void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error if( nLevel>0 ) { - vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); - ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeStringAtLevel(nLevel) ); + vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); + ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) ); if( m_bDataInColumns ) m_aInternalData.setComplexRowLabels( aComplexCategories ); else @@ -1134,7 +1195,36 @@ OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXM namespace { -Sequence< Sequence< OUString > > lcl_convertComplexVectorToSequence( const vector< vector< OUString > >& rIn ) + +template< class Type > +Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn ) +{ + Sequence< Sequence< Type > > aRet; + sal_Int32 nOuterCount = rIn.size(); + if( nOuterCount ) + { + aRet.realloc(nOuterCount); + for( sal_Int32 nN=0; nN<nOuterCount; nN++) + aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] ); + } + return aRet; +} + +template< class Type > +vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn ) +{ + vector< vector< Type > > aRet; + sal_Int32 nOuterCount = rIn.getLength(); + if( nOuterCount ) + { + aRet.resize(nOuterCount); + for( sal_Int32 nN=0; nN<nOuterCount; nN++) + aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] ); + } + return aRet; +} + +Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn ) { Sequence< Sequence< OUString > > aRet; sal_Int32 nOuterCount = rIn.size(); @@ -1142,17 +1232,17 @@ Sequence< Sequence< OUString > > lcl_convertComplexVectorToSequence( const vecto { aRet.realloc(nOuterCount); for( sal_Int32 nN=0; nN<nOuterCount; nN++) - aRet[nN]=ContainerHelper::ContainerToSequence( rIn[nN] ); + aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) ); } return aRet; } -vector< vector< OUString > > lcl_convertComplexSequenceToVector( const Sequence< Sequence< OUString > >& rIn ) +vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn ) { - vector< vector< OUString > > aRet; + vector< vector< uno::Any > > aRet; sal_Int32 nOuterCount = rIn.getLength(); for( sal_Int32 nN=0; nN<nOuterCount; nN++) - aRet.push_back( ContainerHelper::SequenceToVector( rIn[nN] ) ); + aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) ); return aRet; } @@ -1160,7 +1250,7 @@ class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesPro { public: - explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< ::rtl::OUString > >& rComplexDescriptions ) + explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions ) : m_rComplexDescriptions( rComplexDescriptions ) {} virtual ~SplitCategoriesProvider_ForComplexDescriptions() @@ -1170,7 +1260,7 @@ public: virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const; private: - const ::std::vector< ::std::vector< ::rtl::OUString > >& m_rComplexDescriptions; + const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions; }; sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const @@ -1191,22 +1281,78 @@ uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::g }//anonymous namespace +// ____ XDateCategories ____ +Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException) +{ + double fNan = InternalDataProvider::getNotANumber(); + double fValue = fNan; + vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); + sal_Int32 nCount = aCategories.size(); + Sequence< double > aDoubles( nCount ); + vector< vector< uno::Any > >::iterator aIt( aCategories.begin() ); + vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() ); + for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt ) + { + if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) ) + fValue = fNan; + aDoubles[nN]=fValue; + } + return aDoubles; +} + +void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException) +{ + sal_Int32 nCount = rDates.getLength(); + vector< vector< uno::Any > > aNewCategories; + aNewCategories.reserve(nCount); + vector< uno::Any > aSingleLabel(1); + + for(sal_Int32 nN=0; nN<nCount; ++nN ) + { + aSingleLabel[0]=uno::makeAny(rDates[nN]); + aNewCategories.push_back(aSingleLabel); + } + + if( m_bDataInColumns ) + m_aInternalData.setComplexRowLabels( aNewCategories ); + else + m_aInternalData.setComplexColumnLabels( aNewCategories ); +} + +// ____ XAnyDescriptionAccess ____ +Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException) +{ + return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() ); +} +void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException) +{ + m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) ); +} +Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException) +{ + return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() ); +} +void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException) +{ + m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) ); +} + // ____ XComplexDescriptionAccess ____ Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException) { - return lcl_convertComplexVectorToSequence( m_aInternalData.getComplexRowLabels() ); + return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() ); } void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException) { - m_aInternalData.setComplexRowLabels( lcl_convertComplexSequenceToVector(aRowDescriptions) ); + m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) ); } Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException) { - return lcl_convertComplexVectorToSequence( m_aInternalData.getComplexColumnLabels() ); + return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() ); } void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException) { - m_aInternalData.setComplexColumnLabels( lcl_convertComplexSequenceToVector(aColumnDescriptions) ); + m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) ); } // ____ XChartDataArray ____ @@ -1225,25 +1371,25 @@ void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions ) throw (uno::RuntimeException) { - vector< vector< OUString > > aComplexDescriptions( aRowDescriptions.getLength() ); + vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() ); transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(), - aComplexDescriptions.begin(), lcl_setStringAtLevel(0) ); + aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); m_aInternalData.setComplexRowLabels( aComplexDescriptions ); } void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions ) throw (uno::RuntimeException) { - vector< vector< OUString > > aComplexDescriptions( aColumnDescriptions.getLength() ); + vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() ); transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(), - aComplexDescriptions.begin(), lcl_setStringAtLevel(0) ); + aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); m_aInternalData.setComplexColumnLabels( aComplexDescriptions ); } Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions() throw (uno::RuntimeException) { - vector< vector< OUString > > aComplexLabels( m_aInternalData.getComplexRowLabels() ); + vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() ); SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); } @@ -1251,7 +1397,7 @@ Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions() Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions() throw (uno::RuntimeException) { - vector< vector< OUString > > aComplexLabels( m_aInternalData.getComplexColumnLabels() ); + vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() ); SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); } |