36#include <unonames.hxx>
38#include <com/sun/star/container/XIndexReplace.hpp>
39#include <com/sun/star/chart2/XInternalDataProvider.hpp>
40#include <com/sun/star/chart2/data/XDataSource.hpp>
41#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
42#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
43#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
55using ::com::sun::star::uno::Reference;
56using ::com::sun::star::uno::Sequence;
63 const Reference< chart2::data::XDataSequence > & xSeq )
66 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
71 xProp->getPropertyValue(
"Role" ) >>= aResult;
73 catch(
const uno::Exception & )
81OUString lcl_getUIRoleName(
85 if( !aResult.isEmpty())
90void lcl_copyDataSequenceProperties(
91 const Reference< chart2::data::XDataSequence > & xOldSequence,
92 const Reference< chart2::data::XDataSequence > & xNewSequence )
94 Reference< beans::XPropertySet > xOldSeqProp( xOldSequence, uno::UNO_QUERY );
95 Reference< beans::XPropertySet > xNewSeqProp( xNewSequence, uno::UNO_QUERY );
99bool lcl_SequenceOfSeriesIsShared(
101 const Reference< chart2::data::XDataSequence > & xValues )
103 bool bResult =
false;
108 OUString aValuesRole( lcl_getRole( xValues ));
109 OUString aValuesRep( xValues->getSourceRangeRepresentation());
110 const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aLSeq( xSeries->getDataSequences2());
111 for( uno::Reference< chart2::data::XLabeledDataSequence >
const & labeledDataSeq : aLSeq )
115 bResult = (aValuesRep == labeledDataSeq->getValues()->getSourceRangeRepresentation());
120 catch(
const uno::Exception & )
127typedef std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > lcl_tSharedSeqVec;
133 lcl_tSharedSeqVec aResult;
135 if( rSeries.size() <= 1 )
138 for( uno::Reference< chart2::data::XLabeledDataSequence >
const & labeledDataSeq : rSeries[0]->getDataSequences2() )
140 Reference< chart2::data::XDataSequence > xValues( labeledDataSeq->getValues());
142 for( std::size_t nSeriesIdx=1; nSeriesIdx<rSeries.size(); ++nSeriesIdx )
144 bShared = lcl_SequenceOfSeriesIsShared( rSeries[nSeriesIdx], xValues );
149 aResult.push_back( labeledDataSeq );
155sal_Int32 lcl_getValuesRepresentationIndex(
158 sal_Int32 nResult = -1;
161 Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues());
164 OUString aRep( xSeq->getSourceRangeRepresentation());
165 nResult = aRep.toInt32();
171struct lcl_RepresentationsOfLSeqMatch
175 (xLSeq->getValues().is() ? xLSeq->getValues()->getSourceRangeRepresentation() : OUString())
180 if (!xLSeq.is() || !xLSeq->getValues().is())
183 return xLSeq->getValues()->getSourceRangeRepresentation() ==
m_aValuesRep;
189struct lcl_RolesOfLSeqMatch
191 explicit lcl_RolesOfLSeqMatch(
const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq ) :
194 bool operator() (
const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq )
204 return !xDiagram->isCategory();
222 OUString aUIRoleName,
225 sal_Int32 nNumberFormatKey ) :
249 m_xChartDocument( xChartDoc ),
260struct lcl_DataSeriesOfHeaderMatches
262 explicit lcl_DataSeriesOfHeaderMatches(
266 bool operator() ( const ::chart::DataBrowserModel::tDataHeader & rHeader )
268 return (
m_xSeries == rHeader.m_xDataSeries);
281 if (!xDataProvider.is())
288 sal_Int32 nStartCol = 0;
294 xSeries =
m_aColumns[nAfterColumnIndex].m_xDataSeries;
296 sal_Int32 nSeriesNumberFormat = 0;
300 xChartType = xDiagram->getChartTypeOfSeries( xSeries );
304 tDataHeaderVector::const_iterator aIt(
306 lcl_DataSeriesOfHeaderMatches( xSeries )));
308 nStartCol = aIt->m_nEndColumn;
317 xChartType = xDiagram->getChartTypeByIndex( 0 );
318 nStartCol = nAfterColumnIndex;
321 if (!xChartType.is())
326 lcl_tSharedSeqVec aSharedSequences = lcl_getSharedSequences( xChartType->getDataSeries2());
331 if (!xNewSeries.is())
335 const std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > & aLSequences = xNewSeries->getDataSequences2();
336 sal_Int32 nSeqIdx = 0;
337 sal_Int32 nSeqSize = aLSequences.size();
338 for (sal_Int32
nIndex = nStartCol; nSeqIdx < nSeqSize; ++nSeqIdx)
340 lcl_tSharedSeqVec::const_iterator aSharedIt(
341 std::find_if( aSharedSequences.begin(), aSharedSequences.end(),
342 lcl_RolesOfLSeqMatch( aLSequences[nSeqIdx] )));
344 if( aSharedIt != aSharedSequences.end())
347 aLSequences[nSeqIdx]->setValues( (*aSharedIt)->getValues());
348 aLSequences[nSeqIdx]->setLabel( (*aSharedIt)->getLabel());
353 xDataProvider->insertSequence(
nIndex - 1 );
357 xDataProvider->createDataSequenceByRangeRepresentation(
358 OUString::number(
nIndex )));
359 lcl_copyDataSequenceProperties(
360 aLSequences[nSeqIdx]->getValues(), xNewSeq );
361 aLSequences[nSeqIdx]->setValues( xNewSeq );
365 xDataProvider->createDataSequenceByRangeRepresentation(
367 OUString::number(
nIndex )));
368 lcl_copyDataSequenceProperties(
369 aLSequences[nSeqIdx]->getLabel(), xNewLabelSeq );
370 aLSequences[nSeqIdx]->setLabel( xNewLabelSeq );
375 if( nSeriesNumberFormat != 0 )
390 if (!xDataProvider.is())
396 if(nAfterColumnIndex<0)
398 OSL_FAIL(
"wrong index for category level insertion" );
404 xDataProvider->insertComplexCategoryLevel( nAfterColumnIndex+1 );
411 OSL_ENSURE(nAtColumnIndex>0,
"wrong index for categories deletion" );
414 if (!xDataProvider.is())
419 xDataProvider->deleteComplexCategoryLevel( nAtColumnIndex );
445 if (!xDataProvider.is() || !xSeries.is())
453 if (!xSeriesCnt.is())
462 std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > aAllDataSeqs =
467 std::vector<sal_Int32> aSequenceIndexesToDelete;
468 const std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > & aSequencesOfDeleted = xSeries->getDataSequences2();
469 for (
auto const & labeledDataSeq : aSequencesOfDeleted)
472 if( std::none_of( aAllDataSeqs.begin(), aAllDataSeqs.end(),
473 lcl_RepresentationsOfLSeqMatch( labeledDataSeq )) )
474 aSequenceIndexesToDelete.push_back( lcl_getValuesRepresentationIndex( labeledDataSeq ) );
480 std::sort( aSequenceIndexesToDelete.begin(), aSequenceIndexesToDelete.end());
481 for( std::vector< sal_Int32 >::reverse_iterator aIt(
482 aSequenceIndexesToDelete.rbegin()); aIt != aSequenceIndexesToDelete.rend(); ++aIt )
485 xDataProvider->deleteSequence( *aIt );
512 if( xDataProvider.is())
513 xDataProvider->swapDataPointWithNextOneForAllSequences( nFirstIndex );
523 if( xDataProvider.is())
524 xDataProvider->insertDataPointForAllSequences( nAfterIndex );
534 if( xDataProvider.is())
535 xDataProvider->deleteDataPointForAllSequences( nAtIndex );
543 assert(!xSeries || pSeries);
546 if( elemHeader.m_xDataSeries == pSeries )
555 tDataColumnVector::size_type
nIndex( nColumn );
564 tDataColumnVector::size_type
nIndex( nAtColumn );
572 tDataColumnVector::size_type
nIndex( nAtColumn );
581 if( nAtRow < aValues.getLength())
582 return aValues[nAtRow];
585 return std::numeric_limits<double>::quiet_NaN();
592 tDataColumnVector::size_type
nIndex( nAtColumn );
601 if( nAtRow < aValues.getLength())
602 aResult = aValues[nAtRow];
612 tDataColumnVector::size_type
nIndex( nAtColumn );
621 if( nAtRow < aValues.getLength())
622 aResult = aValues[nAtRow];
630 tDataColumnVector::size_type
nIndex( nAtColumn );
638 bool bResult =
false;
639 tDataColumnVector::size_type
nIndex( nAtColumn );
652 m_aColumns[
nIndex ].m_xLabeledDataSequence->getLabel(), uno::UNO_QUERY_THROW );
653 xIndexReplace->replaceByIndex( 0, rValue );
658 m_aColumns[
nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY_THROW );
659 xIndexReplace->replaceByIndex( nAtRow, rValue );
667 catch(
const uno::Exception & )
689 return static_cast< sal_Int32
>(
m_aColumns.size());
694 sal_Int32 nResult = 0;
697 if( column.m_xLabeledDataSequence.is())
700 column.m_xLabeledDataSequence->getValues());
703 sal_Int32
nLength( xSeq->getData().getLength());
714 if( nColumnIndex != -1 &&
716 return m_aColumns[ nColumnIndex ].m_aUIRoleName;
722 if (nColumnIndex < 0)
729 return !
m_aColumns[nColumnIndex].m_xDataSeries.is();
734 sal_Int32 nLastTextColumnIndex = -1;
737 if( !column.m_xDataSeries.is() )
738 nLastTextColumnIndex++;
742 return nLastTextColumnIndex+1;
759 xDiagram->getTemplate( xChartTypeManager );
763 sal_Int32 nHeaderStart = 0;
764 sal_Int32 nHeaderEnd = 0;
768 const std::vector< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList = aExplicitCategoriesProvider.
getSplitCategoriesList();
769 sal_Int32 nLevelCount = rSplitCategoriesList.size();
770 for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
773 if( !xCategories.is() )
778 if( lcl_ShowCategoriesAsDataLabel( xDiagram ))
781 aCategories.
m_aUIRoleName = lcl_getUIRoleName( xCategories );
790 const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysSeq( xDiagram->getBaseCoordinateSystems());
793 const std::vector< rtl::Reference< ChartType > > aChartTypes( coords->getChartTypes2());
796 for(
auto const & CT: aChartTypes )
801 const std::vector< rtl::Reference< DataSeries > > & aSeries( xSeriesCnt->getDataSeries2());
802 lcl_tSharedSeqVec aSharedSequences( lcl_getSharedSequences( aSeries ));
803 for (
auto const& sharedSequence : aSharedSequences)
807 aSharedSequence.
m_aUIRoleName = lcl_getUIRoleName(sharedSequence);
818 tDataColumnVector::size_type nStartColIndex =
m_aColumns.size();
822 const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aLSeqs( xSeries->getDataSequences2());
825 nHeaderEnd = nHeaderStart;
828 sal_Int32 nYAxisNumberFormatKey =
830 dataSeries, coords, 1 );
833 for( ; nSeqIdx<static_cast<sal_Int32>(aLSeqs.size()); ++nSeqIdx )
835 sal_Int32 nSequenceNumberFormatKey = nYAxisNumberFormatKey;
838 if( aRole == aRoleForDataLabelNumberFormat )
840 nSequenceNumberFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
843 else if( aRole ==
"values-x" )
844 nSequenceNumberFormatKey = nXAxisNumberFormat;
846 if( std::none_of( aSharedSequences.begin(), aSharedSequences.end(),
847 lcl_RepresentationsOfLSeqMatch( aLSeqs[nSeqIdx] )) )
852 lcl_getUIRoleName( aLSeqs[nSeqIdx] ),
855 nSequenceNumberFormatKey );
860 bool bSwapXAndYAxis =
false;
863 coords->getPropertyValue(
"SwapXAndYAxis" ) >>= bSwapXAndYAxis;
865 catch(
const beans::UnknownPropertyException & ) {}
869 addErrorBarRanges( dataSeries, nYAxisNumberFormatKey, nSeqIdx, nHeaderEnd,
true );
872 addErrorBarRanges( dataSeries, nYAxisNumberFormatKey, nSeqIdx, nHeaderEnd,
false );
881 nHeaderStart = nHeaderEnd;
892 sal_Int32 nNumberFormatKey,
893 sal_Int32 & rInOutSequenceIndex,
894 sal_Int32 & rInOutHeaderEnd,
bool bYError )
898 std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences;
908 if( xErrorLSequence.is())
909 aSequences.push_back( xErrorLSequence );
916 if( xErrorLSequence.is())
917 aSequences.push_back( xErrorLSequence );
921 m_aColumns.emplace_back(xDataSeries, lcl_getUIRoleName(rDataSequence),
922 rDataSequence,
NUMBER, nNumberFormatKey);
923 ++rInOutSequenceIndex;
927 catch(
const uno::Exception & )
rtl::Reference< ::chart::DataSeries > m_xSeries
static rtl::Reference< ::chart::BaseCoordinateSystem > getFirstCoordinateSystem(const rtl::Reference<::chart::ChartModel > &xModel)
static OUString getRoleOfSequenceForDataLabelNumberFormatDetection(const rtl::Reference< ::chart::ChartType > &xChartType)
This guard calls lockControllers at the given Model in the CTOR and unlockControllers in the DTOR.
void removeDataSeriesOrComplexCategoryLevel(sal_Int32 nAtColumnIndex)
Removes a data series to which the data column with index nAtColumnIndex belongs.
sal_Int32 getCategoryColumnCount()
bool setCellAny(sal_Int32 nAtColumn, sal_Int32 nAtRow, const css::uno::Any &aValue)
void addErrorBarRanges(const rtl::Reference<::chart::DataSeries > &xDataSeries, sal_Int32 nNumberFormatKey, sal_Int32 &rInOutSequenceIndex, sal_Int32 &rInOutHeaderEnd, bool bYError)
tDataHeaderVector m_aHeaders
rtl::Reference< ::chart::DataSeries > getDataSeriesByColumn(sal_Int32 nColumn) const
void insertDataSeries(sal_Int32 nAfterColumnIndex)
Inserts a new data series after the data series to which the data column with index nAfterColumnIndex...
void insertDataPointForAllSeries(sal_Int32 nAfterIndex)
std::unique_ptr< DialogModel > m_apDialogModel
void swapDataPointForAllSeries(sal_Int32 nFirstIndex)
sal_uInt32 getNumberFormatKey(sal_Int32 nAtColumn)
tDataHeader getHeaderForSeries(const css::uno::Reference< css::chart2::XDataSeries > &xSeries) const
void swapDataSeries(sal_Int32 nFirstIndex)
Swaps the series to which the data column with index nFirstIndex belongs with the next series (which ...
OUString getRoleOfColumn(sal_Int32 nColumnIndex) const
double getCellNumber(sal_Int32 nAtColumn, sal_Int32 nAtRow)
If getCellType( nAtColumn, nAtRow ) returns TEXT, the result will be Nan.
eCellType getCellType(sal_Int32 nAtColumn) const
void removeDataPointForAllSeries(sal_Int32 nAtIndex)
sal_Int32 getColumnCount() const
void removeComplexCategoryLevel(sal_Int32 nAtColumnIndex)
rtl::Reference<::chart::ChartModel > m_xChartDocument
sal_Int32 getMaxRowCount() const
bool setCellNumber(sal_Int32 nAtColumn, sal_Int32 nAtRow, double fValue)
returns </sal_True> if the number could successfully be set at the given position
css::uno::Any getCellAny(sal_Int32 nAtColumn, sal_Int32 nAtRow)
bool setCellText(sal_Int32 nAtColumn, sal_Int32 nAtRow, const OUString &rText)
returns </sal_True> if the text could successfully be set at the given position
void insertComplexCategoryLevel(sal_Int32 nAfterColumnIndex)
Inserts a new text column for complex categories.
bool isCategoriesColumn(sal_Int32 nColumnIndex) const
tDataColumnVector m_aColumns
DataBrowserModel(const rtl::Reference<::chart::ChartModel > &xChartDoc)
OUString getCellText(sal_Int32 nAtColumn, sal_Int32 nAtRow)
static OUString GetRoleDataLabel()
static OUString ConvertRoleFromInternalToUI(const OUString &rRoleString)
static sal_Int32 GetRoleIndexForSorting(const OUString &rInternalRoleString)
const std::vector< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > & getSplitCategoriesList() const
#define DBG_UNHANDLED_EXCEPTION(...)
OOO_DLLPUBLIC_CHARTTOOLS std::vector< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > getAllDataSequences(const std::vector< rtl::Reference<::chart::DataSeries > > &aSeries)
OOO_DLLPUBLIC_CHARTTOOLS sal_Int32 getNumberFormatKeyFromAxis(const rtl::Reference< ::chart::DataSeries > &xSeries, const rtl::Reference< ::chart::BaseCoordinateSystem > &xCorrespondingCoordinateSystem, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex=-1)
OOO_DLLPUBLIC_CHARTTOOLS OUString getRole(const css::uno::Reference< css::chart2::data::XLabeledDataSequence > &xLabeledDataSequence)
OOO_DLLPUBLIC_CHARTTOOLS css::uno::Reference< css::beans::XPropertySet > getErrorBars(const rtl::Reference< ::chart::DataSeries > &xDataSeries, bool bYError=true)
OOO_DLLPUBLIC_CHARTTOOLS bool usesErrorBarRanges(const rtl::Reference< ::chart::DataSeries > &xDataSeries, bool bYError=true)
OOO_DLLPUBLIC_CHARTTOOLS css::uno::Reference< css::chart2::data::XLabeledDataSequence > getErrorLabeledDataSequenceFromDataSource(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource, bool bPositiveValue, bool bYError=true)
void copyProperties(const Reference< XPropertySet > &_rxSource, const Reference< XPropertySet > &_rxDest)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
bool operator()(const DataBrowserModel::tDataColumn &rLeft, const DataBrowserModel::tDataColumn &rRight)
rtl::Reference< DataSeries > m_xDataSeries
tDataColumn(rtl::Reference< DataSeries > xDataSeries, OUString aUIRoleName, uno::Reference< chart2::data::XLabeledDataSequence > xLabeledDataSequence, eCellType aCellType, sal_Int32 nNumberFormatKey)
uno::Reference< chart2::data::XLabeledDataSequence > m_xLabeledDataSequence
sal_Int32 m_nNumberFormatKey
rtl::Reference< ::chart::ChartTypeTemplate > xChartTypeTemplate
constexpr OUStringLiteral CHART_UNONAME_NUMFMT