vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / chart2 / source / controller / dialogs / DialogModel.cxx
blob94cdc5b24ea7b00a5cdcfbf6821e94a5a2399ce2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
26 #include <ResId.hxx>
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>
44 #include <utility>
45 #include <algorithm>
46 #include <iterator>
47 #include <numeric>
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;
55 namespace
57 const OUString lcl_aLabelRole( "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 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;
99 return aResult;
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;
125 return aMap;
128 struct lcl_DataSeriesContainerAppend
130 typedef Reference< XDataSeriesContainer > value_type;
131 typedef std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;
133 explicit lcl_DataSeriesContainerAppend( tContainerType * rCnt )
134 : m_rDestCnt( rCnt )
137 lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
141 if( xVal.is())
143 Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
144 OUString aRole( "values-y" );
145 Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
146 if( xCT.is())
147 aRole = xCT->getRoleOfSequenceForSeriesLabel();
148 for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
150 m_rDestCnt->push_back(
151 ::chart::DialogModel::tSeriesWithChartTypeByName(
152 ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
153 std::make_pair( aSeq[nI], xCT )));
157 catch( const uno::Exception & )
159 DBG_UNHANDLED_EXCEPTION("chart2");
161 return *this;
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; }
172 private:
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 )
191 if( xVal.is())
193 // data sequence
194 Reference< data::XDataSequence > xSeq( xVal->getValues());
195 if( xSeq.is())
197 OUString aRole;
198 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
199 if( xProp->getPropertyValue( "Role" ) >>= aRole )
201 m_rDestCnt->emplace(aRole, xSeq->getSourceRangeRepresentation());
202 // label
203 if( aRole == m_aRoleForLabelSeq )
205 Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
206 if( xLabelSeq.is())
208 m_rDestCnt->emplace(
209 lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation());
216 catch( const uno::Exception & )
218 DBG_UNHANDLED_EXCEPTION("chart2");
220 return *this;
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; }
231 private:
232 tContainerType * m_rDestCnt;
233 OUString m_aRoleForLabelSeq;
238 namespace std
240 template<> struct iterator_traits<lcl_DataSeriesContainerAppend>
242 typedef std::output_iterator_tag iterator_category;
243 typedef Reference< XDataSeriesContainer > value_type;
246 template<> struct iterator_traits<lcl_RolesWithRangeAppend>
248 typedef std::output_iterator_tag iterator_category;
249 typedef Reference< data::XLabeledDataSequence > value_type;
253 namespace {
255 void lcl_SetSequenceRole(
256 const Reference< data::XDataSequence > & xSeq,
257 const OUString & rRole )
259 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
260 if( xProp.is())
261 xProp->setPropertyValue( "Role" , uno::Any( rRole ));
264 Reference< XDataSeries > lcl_CreateNewSeries(
265 const Reference< uno::XComponentContext > & xContext,
266 const Reference< XChartType > & xChartType,
267 sal_Int32 nNewSeriesIndex,
268 sal_Int32 nTotalNumberOfSeriesInCTGroup,
269 const Reference< XDiagram > & xDiagram,
270 const Reference< XChartTypeTemplate > & xTemplate,
271 bool bCreateDataCachedSequences )
273 // create plain series
274 Reference< XDataSeries > xResult(
275 xContext->getServiceManager()->createInstanceWithContext(
276 "com.sun.star.chart2.DataSeries" ,
277 xContext ), uno::UNO_QUERY );
278 if( xTemplate.is())
280 Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
281 if( xResultProp.is())
283 // @deprecated: correct default color should be found by view
284 // without setting it as hard attribute
285 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
286 if( xColorScheme.is())
287 xResultProp->setPropertyValue( "Color" , uno::Any( xColorScheme->getColorByIndex( nNewSeriesIndex )));
289 sal_Int32 nGroupIndex=0;
290 if( xChartType.is())
292 Sequence< Reference< XChartType > > aCTs(
293 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
294 for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
295 if( aCTs[nGroupIndex] == xChartType )
296 break;
297 if( nGroupIndex == aCTs.getLength())
298 nGroupIndex = 0;
300 xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
303 if( bCreateDataCachedSequences )
305 // set chart type specific roles
306 Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
307 if( xChartType.is() && xSink.is())
309 std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
310 const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
311 const OUString aLabel(::chart::SchResId(STR_DATA_UNNAMED_SERIES));
312 const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
313 const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
314 sal_Int32 nI = 0;
316 for(nI=0; nI<aRoles.getLength(); ++nI)
318 if( aRoles[nI] == lcl_aLabelRole )
319 continue;
320 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
321 lcl_SetSequenceRole( xSeq, aRoles[nI] );
322 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
323 if( aRoles[nI] == aRoleOfSeqForSeriesLabel )
325 Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
326 lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
327 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
329 else
330 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
333 for(nI=0; nI<aOptRoles.getLength(); ++nI)
335 if( aOptRoles[nI] == lcl_aLabelRole )
336 continue;
337 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
338 lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
339 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
342 xSink->setData( comphelper::containerToSequence( aNewSequences ));
346 return xResult;
349 struct lcl_addSeriesNumber
351 sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
353 if( xCnt.is())
354 return nCurrentNumber + (xCnt->getDataSeries().getLength());
355 return nCurrentNumber;
359 } // anonymous namespace
361 namespace chart
364 DialogModelTimeBasedInfo::DialogModelTimeBasedInfo():
365 bTimeBased(false),
366 nStart(0),
367 nEnd(0)
371 DialogModel::DialogModel(
372 const Reference< XChartDocument > & xChartDocument,
373 const Reference< uno::XComponentContext > & xContext ) :
374 m_xChartDocument( xChartDocument ),
375 m_xContext( xContext ),
376 m_aTimerTriggeredControllerLock( m_xChartDocument )
380 DialogModel::~DialogModel()
382 if(maTimeBasedInfo.bTimeBased)
384 getModel().setTimeBasedRange(maTimeBasedInfo.nStart, maTimeBasedInfo.nEnd);
388 void DialogModel::setTemplate(
389 const Reference< XChartTypeTemplate > & xTemplate )
391 m_xTemplate = xTemplate;
394 std::shared_ptr< RangeSelectionHelper > const &
395 DialogModel::getRangeSelectionHelper() const
397 if( ! m_spRangeSelectionHelper.get())
398 m_spRangeSelectionHelper.reset(
399 new RangeSelectionHelper( m_xChartDocument ));
401 return m_spRangeSelectionHelper;
404 Reference< frame::XModel > DialogModel::getChartModel() const
406 return m_xChartDocument;
409 Reference< data::XDataProvider > DialogModel::getDataProvider() const
411 Reference< data::XDataProvider > xResult;
412 if( m_xChartDocument.is())
413 xResult.set( m_xChartDocument->getDataProvider());
414 return xResult;
417 std::vector< Reference< XDataSeriesContainer > >
418 DialogModel::getAllDataSeriesContainers() const
420 std::vector< Reference< XDataSeriesContainer > > aResult;
424 Reference< XDiagram > xDiagram;
425 if( m_xChartDocument.is())
426 xDiagram.set( m_xChartDocument->getFirstDiagram());
427 if( xDiagram.is())
429 Reference< XCoordinateSystemContainer > xCooSysCnt(
430 xDiagram, uno::UNO_QUERY_THROW );
431 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
432 xCooSysCnt->getCoordinateSystems());
433 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
435 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
436 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
437 std::transform(
438 aChartTypeSeq.begin(), aChartTypeSeq.end(),
439 std::back_inserter( aResult ),
440 lcl_ChartTypeToSeriesCnt() );
444 catch( const uno::Exception & )
446 DBG_UNHANDLED_EXCEPTION("chart2");
449 return aResult;
452 std::vector< DialogModel::tSeriesWithChartTypeByName >
453 DialogModel::getAllDataSeriesWithLabel() const
455 std::vector< tSeriesWithChartTypeByName > aResult;
456 std::vector< Reference< XDataSeriesContainer > > aContainers(
457 getAllDataSeriesContainers());
459 std::copy( aContainers.begin(), aContainers.end(),
460 lcl_DataSeriesContainerAppend( &aResult ));
461 return aResult;
464 namespace {
466 void addMissingRoles(DialogModel::tRolesWithRanges& rResult, const uno::Sequence<OUString>& rRoles)
468 for(sal_Int32 i = 0, n = rRoles.getLength(); i < n; ++i)
470 if(rResult.find(rRoles[i]) == rResult.end())
471 rResult.emplace(rRoles[i], OUString());
476 * Insert a new data series to chart type at position after specified series
477 * position.
479 * @param xChartType chart type that contains data series.
480 * @param xSeries insertion position. The new series will be inserted after
481 * this one.
482 * @param xNewSeries new data series to insert.
484 void addNewSeriesToContainer(
485 const Reference<XChartType>& xChartType,
486 const Reference<XDataSeries>& xSeries,
487 const Reference<XDataSeries>& xNewSeries )
489 Reference<XDataSeriesContainer> xSeriesCnt(xChartType, uno::UNO_QUERY_THROW);
490 auto aSeries = comphelper::sequenceToContainer<std::vector<Reference<XDataSeries> >>(xSeriesCnt->getDataSeries());
492 std::vector<Reference<XDataSeries> >::iterator aIt =
493 std::find( aSeries.begin(), aSeries.end(), xSeries);
495 if( aIt == aSeries.end())
496 // if we have no series we insert at the first position.
497 aIt = aSeries.begin();
498 else
499 // vector::insert inserts before, so we have to advance
500 ++aIt;
502 aSeries.insert(aIt, xNewSeries);
503 xSeriesCnt->setDataSeries(comphelper::containerToSequence(aSeries));
508 DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
509 const Reference< XDataSeries > & xSeries,
510 const OUString & aRoleOfSequenceForLabel,
511 const Reference< chart2::XChartType > & xChartType )
513 DialogModel::tRolesWithRanges aResult;
516 Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
517 const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
518 std::copy( aSeq.begin(), aSeq.end(),
519 lcl_RolesWithRangeAppend( &aResult, aRoleOfSequenceForLabel ));
520 if( xChartType.is())
522 // add missing mandatory roles
523 Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
524 addMissingRoles(aResult, aRoles);
526 // add missing optional roles
527 aRoles = xChartType->getSupportedOptionalRoles();
528 addMissingRoles(aResult, aRoles);
530 // add missing property roles
531 aRoles = xChartType->getSupportedPropertyRoles();
532 addMissingRoles(aResult, aRoles);
535 catch( const uno::Exception & )
537 DBG_UNHANDLED_EXCEPTION("chart2");
539 return aResult;
542 void DialogModel::moveSeries(
543 const Reference< XDataSeries > & xSeries,
544 MoveDirection eDirection )
546 m_aTimerTriggeredControllerLock.startTimer();
547 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
549 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
550 DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MoveDirection::Down );
553 Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
554 const Reference< XDataSeries > & xSeries,
555 const Reference< XChartType > & xChartType,
556 bool bCreateDataCachedSequences /* = false */ )
558 m_aTimerTriggeredControllerLock.startTimer();
559 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
560 Reference< XDataSeries > xNewSeries;
564 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
565 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
567 sal_Int32 nSeriesInChartType = 0;
568 const sal_Int32 nTotalSeries = countSeries();
569 if( xChartType.is())
571 Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW );
572 nSeriesInChartType = xCnt->getDataSeries().getLength();
575 // create new series
576 xNewSeries.set(
577 lcl_CreateNewSeries(
578 m_xContext,
579 xChartType,
580 nTotalSeries, // new series' index
581 nSeriesInChartType,
582 xDiagram,
583 m_xTemplate,
584 bCreateDataCachedSequences ));
586 // add new series to container
587 if( xNewSeries.is())
588 addNewSeriesToContainer(xChartType, xSeries, xNewSeries);
590 ThreeDHelper::setScheme( xDiagram, e3DScheme );
592 catch( const uno::Exception & )
594 DBG_UNHANDLED_EXCEPTION("chart2");
596 return xNewSeries;
599 void DialogModel::deleteSeries(
600 const Reference< XDataSeries > & xSeries,
601 const Reference< XChartType > & xChartType )
603 m_aTimerTriggeredControllerLock.startTimer();
604 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
606 DataSeriesHelper::deleteSeries( xSeries, xChartType );
609 Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
611 Reference< data::XLabeledDataSequence > xResult;
614 if( m_xChartDocument.is())
616 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
617 xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
620 catch( const uno::Exception & )
622 DBG_UNHANDLED_EXCEPTION("chart2");
624 return xResult;
627 void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
629 if( m_xChartDocument.is())
631 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
632 if( xDiagram.is())
634 // categories
635 bool bSupportsCategories = true;
637 Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
638 if( xFirstChartType.is() )
640 sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
641 bSupportsCategories = (nAxisType == AxisType::CATEGORY);
643 DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
648 OUString DialogModel::getCategoriesRange() const
650 Reference< data::XLabeledDataSequence > xLSeq( getCategories());
651 OUString aRange;
652 if( xLSeq.is())
654 Reference< data::XDataSequence > xSeq( xLSeq->getValues());
655 if( xSeq.is())
656 aRange = xSeq->getSourceRangeRepresentation();
658 return aRange;
661 bool DialogModel::isCategoryDiagram() const
663 bool bRet = false;
664 if( m_xChartDocument.is())
665 bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
666 return bRet;
669 void DialogModel::detectArguments(
670 OUString & rOutRangeString,
671 bool & rOutUseColumns,
672 bool & rOutFirstCellAsLabel,
673 bool & rOutHasCategories ) const
677 uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
679 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
680 if( m_xChartDocument.is())
681 DataSourceHelper::detectRangeSegmentation(
682 Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
683 rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
685 catch( const uno::Exception & )
687 DBG_UNHANDLED_EXCEPTION("chart2");
691 bool DialogModel::allArgumentsForRectRangeDetected() const
693 return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
696 void DialogModel::startControllerLockTimer()
698 m_aTimerTriggeredControllerLock.startTimer();
701 void DialogModel::setData(
702 const Sequence< beans::PropertyValue > & rArguments )
704 m_aTimerTriggeredControllerLock.startTimer();
705 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
707 Reference< data::XDataProvider > xDataProvider( getDataProvider());
708 if( ! xDataProvider.is() ||
709 ! m_xTemplate.is() )
711 OSL_FAIL( "Model objects missing" );
712 return;
717 Reference< chart2::data::XDataSource > xDataSource(
718 xDataProvider->createDataSource( rArguments ) );
720 Reference< chart2::XDataInterpreter > xInterpreter(
721 m_xTemplate->getDataInterpreter());
722 if( xInterpreter.is())
724 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
725 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
727 std::vector< Reference< XDataSeries > > aSeriesToReUse(
728 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
729 applyInterpretedData(
730 xInterpreter->interpretDataSource(
731 xDataSource, rArguments,
732 comphelper::containerToSequence( aSeriesToReUse )),
733 aSeriesToReUse);
735 ThreeDHelper::setScheme( xDiagram, e3DScheme );
738 catch( const uno::Exception & )
740 DBG_UNHANDLED_EXCEPTION("chart2");
744 void DialogModel::setTimeBasedRange( bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const
746 maTimeBasedInfo.nStart = nStart;
747 maTimeBasedInfo.nEnd = nEnd;
748 maTimeBasedInfo.bTimeBased = bTimeBased;
751 OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
753 return lcl_ConvertRole( rRoleString );
756 OUString DialogModel::GetRoleDataLabel()
758 return ::chart::SchResId(STR_OBJECT_DATALABELS);
761 sal_Int32 DialogModel::GetRoleIndexForSorting( const OUString & rInternalRoleString )
763 static lcl_tRoleIndexMap aRoleIndexMap = lcl_createRoleIndexMap();
765 lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
766 if( aIt != aRoleIndexMap.end())
767 return aIt->second;
769 return 0;
772 // private methods
774 void DialogModel::applyInterpretedData(
775 const InterpretedData & rNewData,
776 const std::vector< Reference< XDataSeries > > & rSeriesToReUse )
778 if( ! m_xChartDocument.is())
779 return;
781 m_aTimerTriggeredControllerLock.startTimer();
782 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
783 if( xDiagram.is())
785 // styles
786 if( m_xTemplate.is() )
788 sal_Int32 nGroup = 0;
789 sal_Int32 nSeriesCounter = 0;
790 sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
791 const sal_Int32 nOuterSize=rNewData.Series.getLength();
793 for(; nGroup < nOuterSize; ++nGroup)
795 Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
796 const sal_Int32 nSeriesInGroup = aSeries.getLength();
797 for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
799 if( std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
800 == rSeriesToReUse.end())
802 Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
803 if( xSeriesProp.is())
805 // @deprecated: correct default color should be found by view
806 // without setting it as hard attribute
807 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
808 if( xColorScheme.is())
809 xSeriesProp->setPropertyValue( "Color" ,
810 uno::Any( xColorScheme->getColorByIndex( nSeriesCounter )));
812 m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
818 // data series
819 std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
820 auto aNewSeries(
821 comphelper::sequenceToContainer<std::vector< Sequence< Reference< XDataSeries > > >>( rNewData.Series ));
823 OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());
825 std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
826 std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
827 for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
828 ++aSrcIt, ++aDestIt )
832 OSL_ASSERT( (*aDestIt).is());
833 (*aDestIt)->setDataSeries( *aSrcIt );
835 catch( const uno::Exception & )
837 DBG_UNHANDLED_EXCEPTION("chart2");
841 DialogModel::setCategories(rNewData.Categories);
845 sal_Int32 DialogModel::countSeries() const
847 std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
848 return std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
851 ChartModel& DialogModel::getModel() const
853 uno::Reference< frame::XModel > xModel = getChartModel();
854 ChartModel* pModel = dynamic_cast<ChartModel*>(xModel.get());
855 assert(pModel);
856 return *pModel;
859 } // namespace chart
861 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */