1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "DialogModel.hxx"
21 #include <RangeSelectionHelper.hxx>
22 #include <DataSeriesHelper.hxx>
23 #include <DataSourceHelper.hxx>
24 #include <DiagramHelper.hxx>
25 #include <strings.hrc>
27 #include <ControllerLockGuard.hxx>
28 #include <ChartTypeHelper.hxx>
29 #include <ThreeDHelper.hxx>
30 #include <ChartModel.hxx>
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include <com/sun/star/chart2/AxisType.hpp>
34 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
35 #include <com/sun/star/chart2/XChartDocument.hpp>
36 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
37 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
38 #include <com/sun/star/chart2/data/XDataSink.hpp>
39 #include <comphelper/sequence.hxx>
40 #include <tools/diagnose_ex.h>
42 #include <rtl/ustring.hxx>
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::chart2
;
52 using ::com::sun::star::uno::Reference
;
53 using ::com::sun::star::uno::Sequence
;
57 constexpr OUStringLiteral
lcl_aLabelRole( u
"label" );
59 struct lcl_ChartTypeToSeriesCnt
61 Reference
< XDataSeriesContainer
> operator() (
62 const Reference
< XChartType
> & xChartType
)
64 return Reference
< XDataSeriesContainer
>::query( xChartType
);
68 OUString
lcl_ConvertRole( const OUString
& rRoleString
)
70 OUString
aResult( rRoleString
);
72 typedef std::map
< OUString
, OUString
> tTranslationMap
;
73 static const tTranslationMap aTranslationMap
=
75 { "categories", ::chart::SchResId( STR_DATA_ROLE_CATEGORIES
) },
76 { "error-bars-x", ::chart::SchResId( STR_DATA_ROLE_X_ERROR
) },
77 { "error-bars-x-positive", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE
) },
78 { "error-bars-x-negative", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE
) },
79 { "error-bars-y", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR
) },
80 { "error-bars-y-positive", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE
) },
81 { "error-bars-y-negative", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE
) },
82 { "label", ::chart::SchResId( STR_DATA_ROLE_LABEL
) },
83 { "values-first", ::chart::SchResId( STR_DATA_ROLE_FIRST
) },
84 { "values-last", ::chart::SchResId( STR_DATA_ROLE_LAST
) },
85 { "values-max", ::chart::SchResId( STR_DATA_ROLE_MAX
) },
86 { "values-min", ::chart::SchResId( STR_DATA_ROLE_MIN
) },
87 { "values-x", ::chart::SchResId( STR_DATA_ROLE_X
) },
88 { "values-y", ::chart::SchResId( STR_DATA_ROLE_Y
) },
89 { "values-size", ::chart::SchResId( STR_DATA_ROLE_SIZE
) },
90 { "FillColor", ::chart::SchResId( STR_PROPERTY_ROLE_FILLCOLOR
) },
91 { "BorderColor", ::chart::SchResId( STR_PROPERTY_ROLE_BORDERCOLOR
) },
94 tTranslationMap::const_iterator
aIt( aTranslationMap
.find( rRoleString
));
95 if( aIt
!= aTranslationMap
.end())
97 aResult
= (*aIt
).second
;
102 typedef std::map
< OUString
, sal_Int32
> lcl_tRoleIndexMap
;
104 lcl_tRoleIndexMap
lcl_createRoleIndexMap()
106 lcl_tRoleIndexMap aMap
;
107 sal_Int32 nIndex
= 0;
109 aMap
[ "label" ] = ++nIndex
;
110 aMap
[ "categories" ] = ++nIndex
;
111 aMap
[ "values-x" ] = ++nIndex
;
112 aMap
[ "values-y" ] = ++nIndex
;
113 aMap
[ "error-bars-x" ] = ++nIndex
;
114 aMap
[ "error-bars-x-positive" ] = ++nIndex
;
115 aMap
[ "error-bars-x-negative" ] = ++nIndex
;
116 aMap
[ "error-bars-y" ] = ++nIndex
;
117 aMap
[ "error-bars-y-positive" ] = ++nIndex
;
118 aMap
[ "error-bars-y-negative" ] = ++nIndex
;
119 aMap
[ "values-first" ] = ++nIndex
;
120 aMap
[ "values-min" ] = ++nIndex
;
121 aMap
[ "values-max" ] = ++nIndex
;
122 aMap
[ "values-last" ] = ++nIndex
;
123 aMap
[ "values-size" ] = ++nIndex
;
128 struct lcl_DataSeriesContainerAppend
130 typedef Reference
< XDataSeriesContainer
> value_type
;
131 typedef std::vector
< ::chart::DialogModel::tSeriesWithChartTypeByName
> tContainerType
;
133 explicit lcl_DataSeriesContainerAppend( tContainerType
* rCnt
)
137 lcl_DataSeriesContainerAppend
& operator= ( const value_type
& xVal
)
143 const Sequence
< Reference
< XDataSeries
> > aSeq( xVal
->getDataSeries());
144 OUString
aRole( "values-y" );
145 Reference
< XChartType
> xCT( xVal
, uno::UNO_QUERY
);
147 aRole
= xCT
->getRoleOfSequenceForSeriesLabel();
148 for( Reference
< XDataSeries
> const & dataSeries
: aSeq
)
150 m_rDestCnt
->push_back(
151 ::chart::DialogModel::tSeriesWithChartTypeByName(
152 ::chart::DataSeriesHelper::getDataSeriesLabel( dataSeries
, aRole
),
153 std::make_pair( dataSeries
, xCT
)));
157 catch( const uno::Exception
& )
159 DBG_UNHANDLED_EXCEPTION("chart2");
164 // Implement output operator requirements as required by std::copy (and
165 // implement prefix increment in terms of postfix increment to avoid unused
166 // member function warnings for the latter in the common case where
167 // std::copy would not actually need it):
168 lcl_DataSeriesContainerAppend
& operator* () { return *this; }
169 lcl_DataSeriesContainerAppend
& operator++ () { return operator++(0); }
170 lcl_DataSeriesContainerAppend
& operator++ (int) { return *this; }
173 tContainerType
* m_rDestCnt
;
176 struct lcl_RolesWithRangeAppend
178 typedef Reference
< data::XLabeledDataSequence
> value_type
;
179 typedef ::chart::DialogModel::tRolesWithRanges tContainerType
;
181 explicit lcl_RolesWithRangeAppend( tContainerType
* rCnt
,
182 const OUString
& aLabelRole
)
183 : m_rDestCnt( rCnt
),
184 m_aRoleForLabelSeq( aLabelRole
)
187 lcl_RolesWithRangeAppend
& operator= ( const value_type
& xVal
)
194 Reference
< data::XDataSequence
> xSeq( xVal
->getValues());
198 Reference
< beans::XPropertySet
> xProp( xSeq
, uno::UNO_QUERY_THROW
);
199 if( xProp
->getPropertyValue( "Role" ) >>= aRole
)
201 m_rDestCnt
->emplace(aRole
, xSeq
->getSourceRangeRepresentation());
203 if( aRole
== m_aRoleForLabelSeq
)
205 Reference
< data::XDataSequence
> xLabelSeq( xVal
->getLabel());
209 lcl_aLabelRole
, xLabelSeq
->getSourceRangeRepresentation());
216 catch( const uno::Exception
& )
218 DBG_UNHANDLED_EXCEPTION("chart2");
223 // Implement output operator requirements as required by std::copy (and
224 // implement prefix increment in terms of postfix increment to avoid unused
225 // member function warnings for the latter in the common case where
226 // std::copy would not actually need it):
227 lcl_RolesWithRangeAppend
& operator* () { return *this; }
228 lcl_RolesWithRangeAppend
& operator++ () { return operator++(0); }
229 lcl_RolesWithRangeAppend
& operator++ (int) { return *this; }
232 tContainerType
* m_rDestCnt
;
233 OUString m_aRoleForLabelSeq
;
240 template<> struct iterator_traits
<lcl_DataSeriesContainerAppend
>
242 typedef std::output_iterator_tag iterator_category
;
243 typedef Reference
< XDataSeriesContainer
> value_type
;
244 typedef value_type
& reference
;
247 template<> struct iterator_traits
<lcl_RolesWithRangeAppend
>
249 typedef std::output_iterator_tag iterator_category
;
250 typedef Reference
< data::XLabeledDataSequence
> value_type
;
251 typedef value_type
& reference
;
257 void lcl_SetSequenceRole(
258 const Reference
< data::XDataSequence
> & xSeq
,
259 const OUString
& rRole
)
261 Reference
< beans::XPropertySet
> xProp( xSeq
, uno::UNO_QUERY
);
263 xProp
->setPropertyValue( "Role" , uno::Any( rRole
));
266 Sequence
< OUString
> lcl_CopyExcludingValuesFirst(
267 Sequence
< OUString
> const & i_aInput
)
269 Sequence
< OUString
> aOutput( i_aInput
.getLength());
270 auto pOutput
= aOutput
.getArray();
271 int nSourceIndex
, nDestIndex
;
272 for( nSourceIndex
= nDestIndex
= 0; nSourceIndex
< i_aInput
.getLength(); nSourceIndex
++ )
274 if( i_aInput
[nSourceIndex
] == "values-first" )
276 aOutput
.realloc( aOutput
.getLength() - 1 );
277 pOutput
= aOutput
.getArray();
281 pOutput
[nDestIndex
] = i_aInput
[nSourceIndex
];
288 Reference
< XDataSeries
> lcl_CreateNewSeries(
289 const Reference
< uno::XComponentContext
> & xContext
,
290 const Reference
< XChartType
> & xChartType
,
291 sal_Int32 nNewSeriesIndex
,
292 sal_Int32 nTotalNumberOfSeriesInCTGroup
,
293 const Reference
< XDiagram
> & xDiagram
,
294 const Reference
< XChartTypeTemplate
> & xTemplate
,
295 bool bCreateDataCachedSequences
)
297 // create plain series
298 Reference
< XDataSeries
> xResult(
299 xContext
->getServiceManager()->createInstanceWithContext(
300 "com.sun.star.chart2.DataSeries" ,
301 xContext
), uno::UNO_QUERY
);
304 Reference
< beans::XPropertySet
> xResultProp( xResult
, uno::UNO_QUERY
);
305 if( xResultProp
.is())
307 // @deprecated: correct default color should be found by view
308 // without setting it as hard attribute
309 Reference
< XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
310 if( xColorScheme
.is())
311 xResultProp
->setPropertyValue( "Color" , uno::Any( xColorScheme
->getColorByIndex( nNewSeriesIndex
)));
313 sal_Int32 nGroupIndex
=0;
316 Sequence
< Reference
< XChartType
> > aCTs(
317 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram
));
318 for( ; nGroupIndex
<aCTs
.getLength(); ++nGroupIndex
)
319 if( aCTs
[nGroupIndex
] == xChartType
)
321 if( nGroupIndex
== aCTs
.getLength())
324 xTemplate
->applyStyle( xResult
, nGroupIndex
, nNewSeriesIndex
, nTotalNumberOfSeriesInCTGroup
);
327 if( bCreateDataCachedSequences
)
329 // set chart type specific roles
330 Reference
< data::XDataSink
> xSink( xResult
, uno::UNO_QUERY
);
331 if( xChartType
.is() && xSink
.is())
333 std::vector
< Reference
< data::XLabeledDataSequence
> > aNewSequences
;
334 const OUString aRoleOfSeqForSeriesLabel
= xChartType
->getRoleOfSequenceForSeriesLabel();
335 const OUString
aLabel(::chart::SchResId(STR_DATA_UNNAMED_SERIES
));
336 Sequence
< OUString
> aPossibleRoles( xChartType
->getSupportedMandatoryRoles());
337 Sequence
< OUString
> aPossibleOptRoles( xChartType
->getSupportedOptionalRoles());
339 //special handling for candlestick type
342 Reference
< XDataInterpreter
> xInterpreter( xTemplate
->getDataInterpreter());
343 if( xInterpreter
.is())
345 sal_Int32 nStockVariant
;
346 if( xInterpreter
->getChartTypeSpecificData("stock variant") >>= nStockVariant
)
348 if( nStockVariant
== 0 || nStockVariant
== 2) {
349 //delete "values-first" role
350 aPossibleRoles
= lcl_CopyExcludingValuesFirst(aPossibleRoles
);
351 aPossibleOptRoles
= lcl_CopyExcludingValuesFirst(aPossibleOptRoles
);
357 const Sequence
< OUString
> aRoles( aPossibleRoles
);
358 const Sequence
< OUString
> aOptRoles( aPossibleOptRoles
);
360 for(OUString
const & role
: aRoles
)
362 if( role
== lcl_aLabelRole
)
364 Reference
< data::XDataSequence
> xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
365 lcl_SetSequenceRole( xSeq
, role
);
366 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
367 if( role
== aRoleOfSeqForSeriesLabel
)
369 Reference
< data::XDataSequence
> xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel
));
370 lcl_SetSequenceRole( xLabel
, lcl_aLabelRole
);
371 aNewSequences
.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq
, xLabel
));
374 aNewSequences
.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq
));
377 for(OUString
const & role
: aOptRoles
)
379 if( role
== lcl_aLabelRole
)
381 Reference
< data::XDataSequence
> xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
382 lcl_SetSequenceRole( xSeq
, role
);
383 aNewSequences
.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq
));
386 xSink
->setData( comphelper::containerToSequence( aNewSequences
));
393 struct lcl_addSeriesNumber
395 sal_Int32
operator() ( sal_Int32 nCurrentNumber
, const Reference
< XDataSeriesContainer
> & xCnt
) const
398 return nCurrentNumber
+ (xCnt
->getDataSeries().getLength());
399 return nCurrentNumber
;
403 } // anonymous namespace
408 DialogModelTimeBasedInfo::DialogModelTimeBasedInfo():
415 DialogModel::DialogModel(
416 const Reference
< XChartDocument
> & xChartDocument
,
417 const Reference
< uno::XComponentContext
> & xContext
) :
418 m_xChartDocument( xChartDocument
),
419 m_xContext( xContext
),
420 m_aTimerTriggeredControllerLock( m_xChartDocument
)
424 DialogModel::~DialogModel()
426 if(maTimeBasedInfo
.bTimeBased
)
428 getModel().setTimeBasedRange(maTimeBasedInfo
.nStart
, maTimeBasedInfo
.nEnd
);
432 void DialogModel::setTemplate(
433 const Reference
< XChartTypeTemplate
> & xTemplate
)
435 m_xTemplate
= xTemplate
;
438 std::shared_ptr
< RangeSelectionHelper
> const &
439 DialogModel::getRangeSelectionHelper() const
441 if( ! m_spRangeSelectionHelper
)
442 m_spRangeSelectionHelper
=
443 std::make_shared
<RangeSelectionHelper
>( m_xChartDocument
);
445 return m_spRangeSelectionHelper
;
448 Reference
< frame::XModel
> DialogModel::getChartModel() const
450 return m_xChartDocument
;
453 Reference
< data::XDataProvider
> DialogModel::getDataProvider() const
455 Reference
< data::XDataProvider
> xResult
;
456 if( m_xChartDocument
.is())
457 xResult
.set( m_xChartDocument
->getDataProvider());
461 std::vector
< Reference
< XDataSeriesContainer
> >
462 DialogModel::getAllDataSeriesContainers() const
464 std::vector
< Reference
< XDataSeriesContainer
> > aResult
;
468 Reference
< XDiagram
> xDiagram
;
469 if( m_xChartDocument
.is())
470 xDiagram
.set( m_xChartDocument
->getFirstDiagram());
473 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
474 xDiagram
, uno::UNO_QUERY_THROW
);
475 const Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
476 xCooSysCnt
->getCoordinateSystems());
477 for( Reference
< XCoordinateSystem
> const & coords
: aCooSysSeq
)
479 Reference
< XChartTypeContainer
> xCTCnt( coords
, uno::UNO_QUERY_THROW
);
480 const Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
482 aChartTypeSeq
.begin(), aChartTypeSeq
.end(),
483 std::back_inserter( aResult
),
484 lcl_ChartTypeToSeriesCnt() );
488 catch( const uno::Exception
& )
490 DBG_UNHANDLED_EXCEPTION("chart2");
496 std::vector
< DialogModel::tSeriesWithChartTypeByName
>
497 DialogModel::getAllDataSeriesWithLabel() const
499 std::vector
< tSeriesWithChartTypeByName
> aResult
;
500 std::vector
< Reference
< XDataSeriesContainer
> > aContainers(
501 getAllDataSeriesContainers());
503 std::copy( aContainers
.begin(), aContainers
.end(),
504 lcl_DataSeriesContainerAppend( &aResult
));
510 void addMissingRoles(DialogModel::tRolesWithRanges
& rResult
, const uno::Sequence
<OUString
>& rRoles
)
512 for(OUString
const & role
: rRoles
)
514 if(rResult
.find(role
) == rResult
.end())
515 rResult
.emplace(role
, OUString());
520 * Insert a new data series to chart type at position after specified series
523 * @param xChartType chart type that contains data series.
524 * @param xSeries insertion position. The new series will be inserted after
526 * @param xNewSeries new data series to insert.
528 void addNewSeriesToContainer(
529 const Reference
<XChartType
>& xChartType
,
530 const Reference
<XDataSeries
>& xSeries
,
531 const Reference
<XDataSeries
>& xNewSeries
)
533 Reference
<XDataSeriesContainer
> xSeriesCnt(xChartType
, uno::UNO_QUERY_THROW
);
534 auto aSeries
= comphelper::sequenceToContainer
<std::vector
<Reference
<XDataSeries
> >>(xSeriesCnt
->getDataSeries());
536 std::vector
<Reference
<XDataSeries
> >::iterator aIt
=
537 std::find( aSeries
.begin(), aSeries
.end(), xSeries
);
539 if( aIt
== aSeries
.end())
540 // if we have no series we insert at the first position.
541 aIt
= aSeries
.begin();
543 // vector::insert inserts before, so we have to advance
546 aSeries
.insert(aIt
, xNewSeries
);
547 xSeriesCnt
->setDataSeries(comphelper::containerToSequence(aSeries
));
552 DialogModel::tRolesWithRanges
DialogModel::getRolesWithRanges(
553 const Reference
< XDataSeries
> & xSeries
,
554 const OUString
& aRoleOfSequenceForLabel
,
555 const Reference
< chart2::XChartType
> & xChartType
)
557 DialogModel::tRolesWithRanges aResult
;
560 Reference
< data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY_THROW
);
561 const Sequence
< Reference
< data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
562 std::copy( aSeq
.begin(), aSeq
.end(),
563 lcl_RolesWithRangeAppend( &aResult
, aRoleOfSequenceForLabel
));
566 // add missing mandatory roles
567 Sequence
< OUString
> aRoles( xChartType
->getSupportedMandatoryRoles());
568 addMissingRoles(aResult
, aRoles
);
570 // add missing optional roles
571 aRoles
= xChartType
->getSupportedOptionalRoles();
572 addMissingRoles(aResult
, aRoles
);
574 // add missing property roles
575 aRoles
= xChartType
->getSupportedPropertyRoles();
576 addMissingRoles(aResult
, aRoles
);
579 catch( const uno::Exception
& )
581 DBG_UNHANDLED_EXCEPTION("chart2");
586 void DialogModel::moveSeries(
587 const Reference
< XDataSeries
> & xSeries
,
588 MoveDirection eDirection
)
590 m_aTimerTriggeredControllerLock
.startTimer();
591 ControllerLockGuardUNO
aLockedControllers( m_xChartDocument
);
593 Reference
< XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram());
594 DiagramHelper::moveSeries( xDiagram
, xSeries
, eDirection
==MoveDirection::Down
);
597 Reference
< chart2::XDataSeries
> DialogModel::insertSeriesAfter(
598 const Reference
< XDataSeries
> & xSeries
,
599 const Reference
< XChartType
> & xChartType
,
600 bool bCreateDataCachedSequences
/* = false */ )
602 m_aTimerTriggeredControllerLock
.startTimer();
603 ControllerLockGuardUNO
aLockedControllers( m_xChartDocument
);
604 Reference
< XDataSeries
> xNewSeries
;
608 Reference
< chart2::XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram() );
609 ThreeDLookScheme e3DScheme
= ThreeDHelper::detectScheme( xDiagram
);
611 sal_Int32 nSeriesInChartType
= 0;
612 const sal_Int32 nTotalSeries
= countSeries();
615 Reference
< XDataSeriesContainer
> xCnt( xChartType
, uno::UNO_QUERY_THROW
);
616 nSeriesInChartType
= xCnt
->getDataSeries().getLength();
624 nTotalSeries
, // new series' index
628 bCreateDataCachedSequences
));
630 // add new series to container
632 addNewSeriesToContainer(xChartType
, xSeries
, xNewSeries
);
634 ThreeDHelper::setScheme( xDiagram
, e3DScheme
);
636 catch( const uno::Exception
& )
638 DBG_UNHANDLED_EXCEPTION("chart2");
643 void DialogModel::deleteSeries(
644 const Reference
< XDataSeries
> & xSeries
,
645 const Reference
< XChartType
> & xChartType
)
647 m_aTimerTriggeredControllerLock
.startTimer();
648 ControllerLockGuardUNO
aLockedControllers( m_xChartDocument
);
650 DataSeriesHelper::deleteSeries( xSeries
, xChartType
);
653 Reference
< data::XLabeledDataSequence
> DialogModel::getCategories() const
655 Reference
< data::XLabeledDataSequence
> xResult
;
658 if( m_xChartDocument
.is())
660 Reference
< chart2::XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram());
661 xResult
.set( DiagramHelper::getCategoriesFromDiagram( xDiagram
));
664 catch( const uno::Exception
& )
666 DBG_UNHANDLED_EXCEPTION("chart2");
671 void DialogModel::setCategories( const Reference
< chart2::data::XLabeledDataSequence
> & xCategories
)
673 if( !m_xChartDocument
.is())
676 Reference
< chart2::XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram());
681 bool bSupportsCategories
= true;
683 Reference
< XChartType
> xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
684 if( xFirstChartType
.is() )
686 sal_Int32 nAxisType
= ChartTypeHelper::getAxisType( xFirstChartType
, 0 ); // x-axis
687 bSupportsCategories
= (nAxisType
== AxisType::CATEGORY
);
689 DiagramHelper::setCategoriesToDiagram( xCategories
, xDiagram
, true, bSupportsCategories
);
692 OUString
DialogModel::getCategoriesRange() const
694 Reference
< data::XLabeledDataSequence
> xLSeq( getCategories());
698 Reference
< data::XDataSequence
> xSeq( xLSeq
->getValues());
700 aRange
= xSeq
->getSourceRangeRepresentation();
705 bool DialogModel::isCategoryDiagram() const
708 if( m_xChartDocument
.is())
709 bRet
= DiagramHelper::isCategoryDiagram( m_xChartDocument
->getFirstDiagram() );
713 void DialogModel::detectArguments(
714 OUString
& rOutRangeString
,
715 bool & rOutUseColumns
,
716 bool & rOutFirstCellAsLabel
,
717 bool & rOutHasCategories
) const
721 uno::Sequence
< sal_Int32
> aSequenceMapping
;//todo YYYX
723 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
724 if( m_xChartDocument
.is())
726 (void)DataSourceHelper::detectRangeSegmentation(
727 Reference
< frame::XModel
>( m_xChartDocument
, uno::UNO_QUERY_THROW
),
728 rOutRangeString
, aSequenceMapping
, rOutUseColumns
, rOutFirstCellAsLabel
, rOutHasCategories
);
731 catch( const uno::Exception
& )
733 DBG_UNHANDLED_EXCEPTION("chart2");
737 bool DialogModel::allArgumentsForRectRangeDetected() const
739 return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument
);
742 void DialogModel::startControllerLockTimer()
744 m_aTimerTriggeredControllerLock
.startTimer();
747 void DialogModel::setData(
748 const Sequence
< beans::PropertyValue
> & rArguments
)
750 m_aTimerTriggeredControllerLock
.startTimer();
751 ControllerLockGuardUNO
aLockedControllers( m_xChartDocument
);
753 Reference
< data::XDataProvider
> xDataProvider( getDataProvider());
754 if( ! xDataProvider
.is() ||
757 OSL_FAIL( "Model objects missing" );
763 Reference
< chart2::data::XDataSource
> xDataSource(
764 xDataProvider
->createDataSource( rArguments
) );
766 Reference
< chart2::XDataInterpreter
> xInterpreter(
767 m_xTemplate
->getDataInterpreter());
768 if( xInterpreter
.is())
770 Reference
< chart2::XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram() );
771 ThreeDLookScheme e3DScheme
= ThreeDHelper::detectScheme( xDiagram
);
773 std::vector
< Reference
< XDataSeries
> > aSeriesToReUse(
774 DiagramHelper::getDataSeriesFromDiagram( xDiagram
));
775 applyInterpretedData(
776 xInterpreter
->interpretDataSource(
777 xDataSource
, rArguments
,
778 comphelper::containerToSequence( aSeriesToReUse
)),
781 ThreeDHelper::setScheme( xDiagram
, e3DScheme
);
784 catch( const uno::Exception
& )
786 DBG_UNHANDLED_EXCEPTION("chart2");
790 void DialogModel::setTimeBasedRange( bool bTimeBased
, sal_Int32 nStart
, sal_Int32 nEnd
) const
792 maTimeBasedInfo
.nStart
= nStart
;
793 maTimeBasedInfo
.nEnd
= nEnd
;
794 maTimeBasedInfo
.bTimeBased
= bTimeBased
;
797 OUString
DialogModel::ConvertRoleFromInternalToUI( const OUString
& rRoleString
)
799 return lcl_ConvertRole( rRoleString
);
802 OUString
DialogModel::GetRoleDataLabel()
804 return ::chart::SchResId(STR_OBJECT_DATALABELS
);
807 sal_Int32
DialogModel::GetRoleIndexForSorting( const OUString
& rInternalRoleString
)
809 static lcl_tRoleIndexMap aRoleIndexMap
= lcl_createRoleIndexMap();
811 lcl_tRoleIndexMap::const_iterator
aIt( aRoleIndexMap
.find( rInternalRoleString
));
812 if( aIt
!= aRoleIndexMap
.end())
820 void DialogModel::applyInterpretedData(
821 const InterpretedData
& rNewData
,
822 const std::vector
< Reference
< XDataSeries
> > & rSeriesToReUse
)
824 if( ! m_xChartDocument
.is())
827 m_aTimerTriggeredControllerLock
.startTimer();
828 Reference
< XDiagram
> xDiagram( m_xChartDocument
->getFirstDiagram());
833 if( m_xTemplate
.is() )
835 sal_Int32 nGroup
= 0;
836 sal_Int32 nSeriesCounter
= 0;
837 sal_Int32 nNewSeriesIndex
= static_cast< sal_Int32
>( rSeriesToReUse
.size());
838 const sal_Int32 nOuterSize
=rNewData
.Series
.getLength();
840 for(; nGroup
< nOuterSize
; ++nGroup
)
842 Sequence
< Reference
< XDataSeries
> > aSeries( rNewData
.Series
[ nGroup
] );
843 const sal_Int32 nSeriesInGroup
= aSeries
.getLength();
844 for( sal_Int32 nSeries
=0; nSeries
<nSeriesInGroup
; ++nSeries
, ++nSeriesCounter
)
846 if( std::find( rSeriesToReUse
.begin(), rSeriesToReUse
.end(), aSeries
[nSeries
] )
847 == rSeriesToReUse
.end())
849 Reference
< beans::XPropertySet
> xSeriesProp( aSeries
[nSeries
], uno::UNO_QUERY
);
850 if( xSeriesProp
.is())
852 // @deprecated: correct default color should be found by view
853 // without setting it as hard attribute
854 Reference
< XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
855 if( xColorScheme
.is())
856 xSeriesProp
->setPropertyValue( "Color" ,
857 uno::Any( xColorScheme
->getColorByIndex( nSeriesCounter
)));
859 m_xTemplate
->applyStyle( aSeries
[nSeries
], nGroup
, nNewSeriesIndex
++, nSeriesInGroup
);
866 std::vector
< Reference
< XDataSeriesContainer
> > aSeriesCnt( getAllDataSeriesContainers());
868 comphelper::sequenceToContainer
<std::vector
< Sequence
< Reference
< XDataSeries
> > >>( rNewData
.Series
));
870 OSL_ASSERT( aSeriesCnt
.size() == aNewSeries
.size());
872 std::vector
< Sequence
< Reference
< XDataSeries
> > >::const_iterator
aSrcIt( aNewSeries
.begin());
873 std::vector
< Reference
< XDataSeriesContainer
> >::iterator
aDestIt( aSeriesCnt
.begin());
874 for(; aSrcIt
!= aNewSeries
.end() && aDestIt
!= aSeriesCnt
.end();
875 ++aSrcIt
, ++aDestIt
)
879 OSL_ASSERT( (*aDestIt
).is());
880 (*aDestIt
)->setDataSeries( *aSrcIt
);
882 catch( const uno::Exception
& )
884 DBG_UNHANDLED_EXCEPTION("chart2");
888 DialogModel::setCategories(rNewData
.Categories
);
891 sal_Int32
DialogModel::countSeries() const
893 std::vector
< Reference
< XDataSeriesContainer
> > aCnt( getAllDataSeriesContainers());
894 return std::accumulate( aCnt
.begin(), aCnt
.end(), 0, lcl_addSeriesNumber());
897 ChartModel
& DialogModel::getModel() const
899 uno::Reference
< frame::XModel
> xModel
= getChartModel();
900 ChartModel
* pModel
= dynamic_cast<ChartModel
*>(xModel
.get());
907 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */