Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / chart2 / source / controller / dialogs / DialogModel.cxx
blob13b85804c9c780785c8b61630d5466ade61d372c
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 <PropertyHelper.hxx>
23 #include <DataSeriesHelper.hxx>
24 #include <DataSourceHelper.hxx>
25 #include <DiagramHelper.hxx>
26 #include <strings.hrc>
27 #include <ResId.hxx>
28 #include <ContainerHelper.hxx>
29 #include <CommonFunctors.hxx>
30 #include <ControllerLockGuard.hxx>
31 #include <ChartTypeHelper.hxx>
32 #include <ThreeDHelper.hxx>
34 #include <com/sun/star/util/XCloneable.hpp>
35 #include <com/sun/star/chart2/AxisType.hpp>
36 #include <com/sun/star/chart2/XTitled.hpp>
37 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
38 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
39 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
40 #include <com/sun/star/chart2/data/XDataSink.hpp>
41 #include <comphelper/sequence.hxx>
42 #include <tools/diagnose_ex.h>
44 #include <rtl/ustring.hxx>
46 #include <utility>
47 #include <algorithm>
48 #include <iterator>
49 #include <numeric>
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::chart2;
54 using ::com::sun::star::uno::Reference;
55 using ::com::sun::star::uno::Sequence;
57 namespace
59 const OUString lcl_aLabelRole( "label" );
61 struct lcl_ChartTypeToSeriesCnt
63 Reference< XDataSeriesContainer > operator() (
64 const Reference< XChartType > & xChartType )
66 return Reference< XDataSeriesContainer >::query( xChartType );
70 OUString lcl_ConvertRole( const OUString & rRoleString )
72 OUString aResult( rRoleString );
74 typedef std::map< OUString, OUString > tTranslationMap;
75 static tTranslationMap aTranslationMap;
77 if( aTranslationMap.empty() )
79 aTranslationMap[ "categories" ] = ::chart::SchResId( STR_DATA_ROLE_CATEGORIES );
80 aTranslationMap[ "error-bars-x" ] = ::chart::SchResId( STR_DATA_ROLE_X_ERROR );
81 aTranslationMap[ "error-bars-x-positive" ] = ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE );
82 aTranslationMap[ "error-bars-x-negative" ] = ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE );
83 aTranslationMap[ "error-bars-y" ] = ::chart::SchResId( STR_DATA_ROLE_Y_ERROR );
84 aTranslationMap[ "error-bars-y-positive" ] = ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE );
85 aTranslationMap[ "error-bars-y-negative" ] = ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE );
86 aTranslationMap[ "label" ] = ::chart::SchResId( STR_DATA_ROLE_LABEL );
87 aTranslationMap[ "values-first" ] = ::chart::SchResId( STR_DATA_ROLE_FIRST );
88 aTranslationMap[ "values-last" ] = ::chart::SchResId( STR_DATA_ROLE_LAST );
89 aTranslationMap[ "values-max" ] = ::chart::SchResId( STR_DATA_ROLE_MAX );
90 aTranslationMap[ "values-min" ] = ::chart::SchResId( STR_DATA_ROLE_MIN );
91 aTranslationMap[ "values-x" ] = ::chart::SchResId( STR_DATA_ROLE_X );
92 aTranslationMap[ "values-y" ] = ::chart::SchResId( STR_DATA_ROLE_Y );
93 aTranslationMap[ "values-size" ] = ::chart::SchResId( STR_DATA_ROLE_SIZE );
94 aTranslationMap[ "FillColor" ] = ::chart::SchResId( STR_PROPERTY_ROLE_FILLCOLOR );
95 aTranslationMap[ "BorderColor" ] = ::chart::SchResId( STR_PROPERTY_ROLE_BORDERCOLOR );
98 tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
99 if( aIt != aTranslationMap.end())
101 aResult = (*aIt).second;
103 return aResult;
106 typedef std::map< OUString, sal_Int32 > lcl_tRoleIndexMap;
108 void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
110 rOutMap.clear();
111 sal_Int32 nIndex = 0;
113 rOutMap[ "label" ] = ++nIndex;
114 rOutMap[ "categories" ] = ++nIndex;
115 rOutMap[ "values-x" ] = ++nIndex;
116 rOutMap[ "values-y" ] = ++nIndex;
117 rOutMap[ "error-bars-x" ] = ++nIndex;
118 rOutMap[ "error-bars-x-positive" ] = ++nIndex;
119 rOutMap[ "error-bars-x-negative" ] = ++nIndex;
120 rOutMap[ "error-bars-y" ] = ++nIndex;
121 rOutMap[ "error-bars-y-positive" ] = ++nIndex;
122 rOutMap[ "error-bars-y-negative" ] = ++nIndex;
123 rOutMap[ "values-first" ] = ++nIndex;
124 rOutMap[ "values-min" ] = ++nIndex;
125 rOutMap[ "values-max" ] = ++nIndex;
126 rOutMap[ "values-last" ] = ++nIndex;
127 rOutMap[ "values-size" ] = ++nIndex;
130 struct lcl_DataSeriesContainerAppend
132 typedef Reference< XDataSeriesContainer > value_type;
133 typedef std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;
135 explicit lcl_DataSeriesContainerAppend( tContainerType * rCnt )
136 : m_rDestCnt( rCnt )
139 lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
143 if( xVal.is())
145 Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
146 OUString aRole( "values-y" );
147 Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
148 if( xCT.is())
149 aRole = xCT->getRoleOfSequenceForSeriesLabel();
150 for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
152 m_rDestCnt->push_back(
153 ::chart::DialogModel::tSeriesWithChartTypeByName(
154 ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
155 std::make_pair( aSeq[nI], xCT )));
159 catch( const uno::Exception & )
161 DBG_UNHANDLED_EXCEPTION("chart2");
163 return *this;
166 // Implement output operator requirements as required by std::copy (and
167 // implement prefix increment in terms of postfix increment to avoid unused
168 // member function warnings for the latter in the common case where
169 // std::copy would not actually need it):
170 lcl_DataSeriesContainerAppend & operator* () { return *this; }
171 lcl_DataSeriesContainerAppend & operator++ () { return operator++(0); }
172 lcl_DataSeriesContainerAppend & operator++ (int) { return *this; }
174 private:
175 tContainerType * m_rDestCnt;
178 struct lcl_RolesWithRangeAppend
180 typedef Reference< data::XLabeledDataSequence > value_type;
181 typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
183 explicit lcl_RolesWithRangeAppend( tContainerType * rCnt,
184 const OUString & aLabelRole )
185 : m_rDestCnt( rCnt ),
186 m_aRoleForLabelSeq( aLabelRole )
189 lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
193 if( xVal.is())
195 // data sequence
196 Reference< data::XDataSequence > xSeq( xVal->getValues());
197 if( xSeq.is())
199 OUString aRole;
200 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
201 if( xProp->getPropertyValue( "Role" ) >>= aRole )
203 m_rDestCnt->emplace(aRole, xSeq->getSourceRangeRepresentation());
204 // label
205 if( aRole == m_aRoleForLabelSeq )
207 Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
208 if( xLabelSeq.is())
210 m_rDestCnt->emplace(
211 lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation());
218 catch( const uno::Exception & )
220 DBG_UNHANDLED_EXCEPTION("chart2");
222 return *this;
225 // Implement output operator requirements as required by std::copy (and
226 // implement prefix increment in terms of postfix increment to avoid unused
227 // member function warnings for the latter in the common case where
228 // std::copy would not actually need it):
229 lcl_RolesWithRangeAppend & operator* () { return *this; }
230 lcl_RolesWithRangeAppend & operator++ () { return operator++(0); }
231 lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
233 private:
234 tContainerType * m_rDestCnt;
235 OUString m_aRoleForLabelSeq;
240 namespace std
242 template<> struct iterator_traits<lcl_DataSeriesContainerAppend>
244 typedef std::output_iterator_tag iterator_category;
245 typedef Reference< XDataSeriesContainer > value_type;
248 template<> struct iterator_traits<lcl_RolesWithRangeAppend>
250 typedef std::output_iterator_tag iterator_category;
251 typedef Reference< data::XLabeledDataSequence > value_type;
255 namespace {
257 void lcl_SetSequenceRole(
258 const Reference< data::XDataSequence > & xSeq,
259 const OUString & rRole )
261 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
262 if( xProp.is())
263 xProp->setPropertyValue( "Role" , uno::Any( rRole ));
266 Reference< XDataSeries > lcl_CreateNewSeries(
267 const Reference< uno::XComponentContext > & xContext,
268 const Reference< XChartType > & xChartType,
269 sal_Int32 nNewSeriesIndex,
270 sal_Int32 nTotalNumberOfSeriesInCTGroup,
271 const Reference< XDiagram > & xDiagram,
272 const Reference< XChartTypeTemplate > & xTemplate,
273 bool bCreateDataCachedSequences )
275 // create plain series
276 Reference< XDataSeries > xResult(
277 xContext->getServiceManager()->createInstanceWithContext(
278 "com.sun.star.chart2.DataSeries" ,
279 xContext ), uno::UNO_QUERY );
280 if( xTemplate.is())
282 Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
283 if( xResultProp.is())
285 // @deprecated: correct default color should be found by view
286 // without setting it as hard attribute
287 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
288 if( xColorScheme.is())
289 xResultProp->setPropertyValue( "Color" , uno::Any( xColorScheme->getColorByIndex( nNewSeriesIndex )));
291 sal_Int32 nGroupIndex=0;
292 if( xChartType.is())
294 Sequence< Reference< XChartType > > aCTs(
295 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
296 for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
297 if( aCTs[nGroupIndex] == xChartType )
298 break;
299 if( nGroupIndex == aCTs.getLength())
300 nGroupIndex = 0;
302 xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
305 if( bCreateDataCachedSequences )
307 // set chart type specific roles
308 Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
309 if( xChartType.is() && xSink.is())
311 std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
312 const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
313 const OUString aLabel(::chart::SchResId(STR_DATA_UNNAMED_SERIES));
314 const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
315 const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
316 sal_Int32 nI = 0;
318 for(nI=0; nI<aRoles.getLength(); ++nI)
320 if( aRoles[nI] == lcl_aLabelRole )
321 continue;
322 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
323 lcl_SetSequenceRole( xSeq, aRoles[nI] );
324 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
325 if( aRoles[nI] == aRoleOfSeqForSeriesLabel )
327 Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
328 lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
329 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
331 else
332 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
335 for(nI=0; nI<aOptRoles.getLength(); ++nI)
337 if( aOptRoles[nI] == lcl_aLabelRole )
338 continue;
339 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
340 lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
341 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
344 xSink->setData( comphelper::containerToSequence( aNewSequences ));
348 return xResult;
351 struct lcl_addSeriesNumber
353 sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
355 if( xCnt.is())
356 return nCurrentNumber + (xCnt->getDataSeries().getLength());
357 return nCurrentNumber;
361 } // anonymous namespace
363 namespace chart
366 DialogModelTimeBasedInfo::DialogModelTimeBasedInfo():
367 bTimeBased(false),
368 nStart(0),
369 nEnd(0)
373 DialogModel::DialogModel(
374 const Reference< XChartDocument > & xChartDocument,
375 const Reference< uno::XComponentContext > & xContext ) :
376 m_xChartDocument( xChartDocument ),
377 m_xContext( xContext ),
378 m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) )
382 DialogModel::~DialogModel()
384 if(maTimeBasedInfo.bTimeBased)
386 getModel().setTimeBasedRange(maTimeBasedInfo.nStart, maTimeBasedInfo.nEnd);
390 void DialogModel::setTemplate(
391 const Reference< XChartTypeTemplate > & xTemplate )
393 m_xTemplate = xTemplate;
396 std::shared_ptr< RangeSelectionHelper > const &
397 DialogModel::getRangeSelectionHelper() const
399 if( ! m_spRangeSelectionHelper.get())
400 m_spRangeSelectionHelper.reset(
401 new RangeSelectionHelper( m_xChartDocument ));
403 return m_spRangeSelectionHelper;
406 Reference< frame::XModel > DialogModel::getChartModel() const
408 Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY );
409 return xResult;
412 Reference< data::XDataProvider > DialogModel::getDataProvider() const
414 Reference< data::XDataProvider > xResult;
415 if( m_xChartDocument.is())
416 xResult.set( m_xChartDocument->getDataProvider());
417 return xResult;
420 std::vector< Reference< XDataSeriesContainer > >
421 DialogModel::getAllDataSeriesContainers() const
423 std::vector< Reference< XDataSeriesContainer > > aResult;
427 Reference< XDiagram > xDiagram;
428 if( m_xChartDocument.is())
429 xDiagram.set( m_xChartDocument->getFirstDiagram());
430 if( xDiagram.is())
432 Reference< XCoordinateSystemContainer > xCooSysCnt(
433 xDiagram, uno::UNO_QUERY_THROW );
434 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
435 xCooSysCnt->getCoordinateSystems());
436 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
438 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
439 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
440 std::transform(
441 aChartTypeSeq.begin(), aChartTypeSeq.end(),
442 std::back_inserter( aResult ),
443 lcl_ChartTypeToSeriesCnt() );
447 catch( const uno::Exception & )
449 DBG_UNHANDLED_EXCEPTION("chart2");
452 return aResult;
455 std::vector< DialogModel::tSeriesWithChartTypeByName >
456 DialogModel::getAllDataSeriesWithLabel() const
458 std::vector< tSeriesWithChartTypeByName > aResult;
459 std::vector< Reference< XDataSeriesContainer > > aContainers(
460 getAllDataSeriesContainers());
462 std::copy( aContainers.begin(), aContainers.end(),
463 lcl_DataSeriesContainerAppend( &aResult ));
464 return aResult;
467 namespace {
469 void addMissingRoles(DialogModel::tRolesWithRanges& rResult, const uno::Sequence<OUString>& rRoles)
471 for(sal_Int32 i = 0, n = rRoles.getLength(); i < n; ++i)
473 if(rResult.find(rRoles[i]) == rResult.end())
474 rResult.emplace(rRoles[i], OUString());
479 * Insert a new data series to chart type at position after specified series
480 * position.
482 * @param xChartType chart type that contains data series.
483 * @param xSeries insertion position. The new series will be inserted after
484 * this one.
485 * @param xNewSeries new data series to insert.
487 void addNewSeriesToContainer(
488 const Reference<XChartType>& xChartType,
489 const Reference<XDataSeries>& xSeries,
490 const Reference<XDataSeries>& xNewSeries )
492 Reference<XDataSeriesContainer> xSeriesCnt(xChartType, uno::UNO_QUERY_THROW);
493 std::vector<Reference<XDataSeries> > aSeries = ContainerHelper::SequenceToVector(xSeriesCnt->getDataSeries());
495 std::vector<Reference<XDataSeries> >::iterator aIt =
496 std::find( aSeries.begin(), aSeries.end(), xSeries);
498 if( aIt == aSeries.end())
499 // if we have no series we insert at the first position.
500 aIt = aSeries.begin();
501 else
502 // vector::insert inserts before, so we have to advance
503 ++aIt;
505 aSeries.insert(aIt, xNewSeries);
506 xSeriesCnt->setDataSeries(comphelper::containerToSequence(aSeries));
511 DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
512 const Reference< XDataSeries > & xSeries,
513 const OUString & aRoleOfSequenceForLabel,
514 const Reference< chart2::XChartType > & xChartType )
516 DialogModel::tRolesWithRanges aResult;
519 Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
520 const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
521 std::copy( aSeq.begin(), aSeq.end(),
522 lcl_RolesWithRangeAppend( &aResult, aRoleOfSequenceForLabel ));
523 if( xChartType.is())
525 // add missing mandatory roles
526 Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
527 addMissingRoles(aResult, aRoles);
529 // add missing optional roles
530 aRoles = xChartType->getSupportedOptionalRoles();
531 addMissingRoles(aResult, aRoles);
533 // add missing property roles
534 aRoles = xChartType->getSupportedPropertyRoles();
535 addMissingRoles(aResult, aRoles);
538 catch( const uno::Exception & )
540 DBG_UNHANDLED_EXCEPTION("chart2");
542 return aResult;
545 void DialogModel::moveSeries(
546 const Reference< XDataSeries > & xSeries,
547 eMoveDirection eDirection )
549 m_aTimerTriggeredControllerLock.startTimer();
550 ControllerLockGuardUNO aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
552 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
553 DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP );
556 Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
557 const Reference< XDataSeries > & xSeries,
558 const Reference< XChartType > & xChartType,
559 bool bCreateDataCachedSequences /* = false */ )
561 m_aTimerTriggeredControllerLock.startTimer();
562 ControllerLockGuardUNO aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
563 Reference< XDataSeries > xNewSeries;
567 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
568 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
570 sal_Int32 nSeriesInChartType = 0;
571 const sal_Int32 nTotalSeries = countSeries();
572 if( xChartType.is())
574 Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW );
575 nSeriesInChartType = xCnt->getDataSeries().getLength();
578 // create new series
579 xNewSeries.set(
580 lcl_CreateNewSeries(
581 m_xContext,
582 xChartType,
583 nTotalSeries, // new series' index
584 nSeriesInChartType,
585 xDiagram,
586 m_xTemplate,
587 bCreateDataCachedSequences ));
589 // add new series to container
590 if( xNewSeries.is())
591 addNewSeriesToContainer(xChartType, xSeries, xNewSeries);
593 ThreeDHelper::setScheme( xDiagram, e3DScheme );
595 catch( const uno::Exception & )
597 DBG_UNHANDLED_EXCEPTION("chart2");
599 return xNewSeries;
602 void DialogModel::deleteSeries(
603 const Reference< XDataSeries > & xSeries,
604 const Reference< XChartType > & xChartType )
606 m_aTimerTriggeredControllerLock.startTimer();
607 ControllerLockGuardUNO aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
609 DataSeriesHelper::deleteSeries( xSeries, xChartType );
612 Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
614 Reference< data::XLabeledDataSequence > xResult;
617 if( m_xChartDocument.is())
619 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
620 xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
623 catch( const uno::Exception & )
625 DBG_UNHANDLED_EXCEPTION("chart2");
627 return xResult;
630 void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
632 if( m_xChartDocument.is())
634 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
635 if( xDiagram.is())
637 // categories
638 bool bSupportsCategories = true;
640 Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
641 if( xFirstChartType.is() )
643 sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
644 bSupportsCategories = (nAxisType == AxisType::CATEGORY);
646 DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
651 OUString DialogModel::getCategoriesRange() const
653 Reference< data::XLabeledDataSequence > xLSeq( getCategories());
654 OUString aRange;
655 if( xLSeq.is())
657 Reference< data::XDataSequence > xSeq( xLSeq->getValues());
658 if( xSeq.is())
659 aRange = xSeq->getSourceRangeRepresentation();
661 return aRange;
664 bool DialogModel::isCategoryDiagram() const
666 bool bRet = false;
667 if( m_xChartDocument.is())
668 bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
669 return bRet;
672 void DialogModel::detectArguments(
673 OUString & rOutRangeString,
674 bool & rOutUseColumns,
675 bool & rOutFirstCellAsLabel,
676 bool & rOutHasCategories ) const
680 uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
682 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
683 if( m_xChartDocument.is())
684 DataSourceHelper::detectRangeSegmentation(
685 Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
686 rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
688 catch( const uno::Exception & )
690 DBG_UNHANDLED_EXCEPTION("chart2");
694 bool DialogModel::allArgumentsForRectRangeDetected() const
696 return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
699 void DialogModel::startControllerLockTimer()
701 m_aTimerTriggeredControllerLock.startTimer();
704 void DialogModel::setData(
705 const Sequence< beans::PropertyValue > & rArguments )
707 m_aTimerTriggeredControllerLock.startTimer();
708 ControllerLockGuardUNO aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
710 Reference< data::XDataProvider > xDataProvider( getDataProvider());
711 if( ! xDataProvider.is() ||
712 ! m_xTemplate.is() )
714 OSL_FAIL( "Model objects missing" );
715 return;
720 Reference< chart2::data::XDataSource > xDataSource(
721 xDataProvider->createDataSource( rArguments ) );
723 Reference< chart2::XDataInterpreter > xInterpreter(
724 m_xTemplate->getDataInterpreter());
725 if( xInterpreter.is())
727 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
728 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
730 std::vector< Reference< XDataSeries > > aSeriesToReUse(
731 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
732 applyInterpretedData(
733 xInterpreter->interpretDataSource(
734 xDataSource, rArguments,
735 comphelper::containerToSequence( aSeriesToReUse )),
736 aSeriesToReUse);
738 ThreeDHelper::setScheme( xDiagram, e3DScheme );
741 catch( const uno::Exception & )
743 DBG_UNHANDLED_EXCEPTION("chart2");
747 void DialogModel::setTimeBasedRange( bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const
749 maTimeBasedInfo.nStart = nStart;
750 maTimeBasedInfo.nEnd = nEnd;
751 maTimeBasedInfo.bTimeBased = bTimeBased;
754 OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
756 return lcl_ConvertRole( rRoleString );
759 OUString DialogModel::GetRoleDataLabel()
761 return ::chart::SchResId(STR_OBJECT_DATALABELS);
764 sal_Int32 DialogModel::GetRoleIndexForSorting( const OUString & rInternalRoleString )
766 static lcl_tRoleIndexMap aRoleIndexMap;
768 if( aRoleIndexMap.empty())
769 lcl_createRoleIndexMap( aRoleIndexMap );
771 lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
772 if( aIt != aRoleIndexMap.end())
773 return aIt->second;
775 return 0;
778 // private methods
780 void DialogModel::applyInterpretedData(
781 const InterpretedData & rNewData,
782 const std::vector< Reference< XDataSeries > > & rSeriesToReUse )
784 if( ! m_xChartDocument.is())
785 return;
787 m_aTimerTriggeredControllerLock.startTimer();
788 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
789 if( xDiagram.is())
791 // styles
792 if( m_xTemplate.is() )
794 sal_Int32 nGroup = 0;
795 sal_Int32 nSeriesCounter = 0;
796 sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
797 const sal_Int32 nOuterSize=rNewData.Series.getLength();
799 for(; nGroup < nOuterSize; ++nGroup)
801 Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
802 const sal_Int32 nSeriesInGroup = aSeries.getLength();
803 for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
805 if( std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
806 == rSeriesToReUse.end())
808 Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
809 if( xSeriesProp.is())
811 // @deprecated: correct default color should be found by view
812 // without setting it as hard attribute
813 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
814 if( xColorScheme.is())
815 xSeriesProp->setPropertyValue( "Color" ,
816 uno::Any( xColorScheme->getColorByIndex( nSeriesCounter )));
818 m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
824 // data series
825 std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
826 std::vector< Sequence< Reference< XDataSeries > > > aNewSeries(
827 ContainerHelper::SequenceToVector( rNewData.Series ));
829 OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());
831 std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
832 std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
833 for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
834 ++aSrcIt, ++aDestIt )
838 OSL_ASSERT( (*aDestIt).is());
839 (*aDestIt)->setDataSeries( *aSrcIt );
841 catch( const uno::Exception & )
843 DBG_UNHANDLED_EXCEPTION("chart2");
847 DialogModel::setCategories(rNewData.Categories);
851 sal_Int32 DialogModel::countSeries() const
853 std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
854 return std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
857 ChartModel& DialogModel::getModel() const
859 uno::Reference< frame::XModel > xModel = getChartModel();
860 ChartModel* pModel = dynamic_cast<ChartModel*>(xModel.get());
861 return *pModel;
864 } // namespace chart
866 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */