Bump for 3.6-28
[LibreOffice.git] / chart2 / source / controller / dialogs / DialogModel.cxx
blob5d93ee09ec28c198dfd92162ee6cccad60595d27
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "DialogModel.hxx"
31 #include "RangeSelectionHelper.hxx"
32 #include "PropertyHelper.hxx"
33 #include "DataSeriesHelper.hxx"
34 #include "DataSourceHelper.hxx"
35 #include "DiagramHelper.hxx"
36 #include "macros.hxx"
37 #include "Strings.hrc"
38 #include "ResId.hxx"
39 #include "ContainerHelper.hxx"
40 #include "CommonFunctors.hxx"
41 #include "ControllerLockGuard.hxx"
42 #include "ChartTypeHelper.hxx"
43 #include "ThreeDHelper.hxx"
45 #include <com/sun/star/util/XCloneable.hpp>
46 #include <com/sun/star/chart2/AxisType.hpp>
47 #include <com/sun/star/chart2/XTitled.hpp>
48 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
49 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
50 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
51 #include <com/sun/star/chart2/data/XDataSink.hpp>
53 #include <tools/string.hxx>
55 #include <utility>
56 #include <algorithm>
57 #include <iterator>
58 #include <functional>
59 #include <numeric>
60 #include <o3tl/compat_functional.hxx>
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::chart2;
64 using namespace ::chart::ContainerHelper;
66 using ::com::sun::star::uno::Reference;
67 using ::com::sun::star::uno::Sequence;
68 using ::rtl::OUString;
70 // ----------------------------------------
72 namespace
74 const OUString lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" ));
76 struct lcl_ChartTypeToSeriesCnt : ::std::unary_function<
77 Reference< XChartType >, Reference< XDataSeriesContainer > >
79 Reference< XDataSeriesContainer > operator() (
80 const Reference< XChartType > & xChartType )
82 return Reference< XDataSeriesContainer >::query( xChartType );
86 OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI )
88 OUString aResult( rRoleString );
90 typedef ::std::map< OUString, OUString > tTranslationMap;
91 static tTranslationMap aTranslationMap;
93 if( aTranslationMap.empty() )
95 aTranslationMap[ C2U( "categories" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_CATEGORIES )));
96 aTranslationMap[ C2U( "error-bars-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR )));
97 aTranslationMap[ C2U( "error-bars-x-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE )));
98 aTranslationMap[ C2U( "error-bars-x-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE )));
99 aTranslationMap[ C2U( "error-bars-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR )));
100 aTranslationMap[ C2U( "error-bars-y-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE )));
101 aTranslationMap[ C2U( "error-bars-y-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE )));
102 aTranslationMap[ C2U( "label" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LABEL )));
103 aTranslationMap[ C2U( "values-first" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_FIRST )));
104 aTranslationMap[ C2U( "values-last" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LAST )));
105 aTranslationMap[ C2U( "values-max" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MAX )));
106 aTranslationMap[ C2U( "values-min" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN )));
107 aTranslationMap[ C2U( "values-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X )));
108 aTranslationMap[ C2U( "values-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y )));
109 aTranslationMap[ C2U( "values-size" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE )));
112 if( bFromInternalToUI )
114 tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
115 if( aIt != aTranslationMap.end())
117 aResult = (*aIt).second;
120 else
122 tTranslationMap::const_iterator aIt(
123 ::std::find_if( aTranslationMap.begin(), aTranslationMap.end(),
124 ::o3tl::compose1( ::std::bind2nd(
125 ::std::equal_to< tTranslationMap::mapped_type >(),
126 rRoleString ),
127 ::o3tl::select2nd< tTranslationMap::value_type >())));
129 if( aIt != aTranslationMap.end())
130 aResult = (*aIt).first;
133 return aResult;
136 typedef ::std::map< ::rtl::OUString, sal_Int32 > lcl_tRoleIndexMap;
138 void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
140 rOutMap.clear();
141 sal_Int32 nIndex = 0;
143 rOutMap[ C2U( "label" ) ] = ++nIndex;
144 rOutMap[ C2U( "categories" ) ] = ++nIndex;
145 rOutMap[ C2U( "values-x" ) ] = ++nIndex;
146 rOutMap[ C2U( "values-y" ) ] = ++nIndex;
147 rOutMap[ C2U( "error-bars-x" ) ] = ++nIndex;
148 rOutMap[ C2U( "error-bars-x-positive" ) ] = ++nIndex;
149 rOutMap[ C2U( "error-bars-x-negative" ) ] = ++nIndex;
150 rOutMap[ C2U( "error-bars-y" ) ] = ++nIndex;
151 rOutMap[ C2U( "error-bars-y-positive" ) ] = ++nIndex;
152 rOutMap[ C2U( "error-bars-y-negative" ) ] = ++nIndex;
153 rOutMap[ C2U( "values-first" ) ] = ++nIndex;
154 rOutMap[ C2U( "values-min" ) ] = ++nIndex;
155 rOutMap[ C2U( "values-max" ) ] = ++nIndex;
156 rOutMap[ C2U( "values-last" ) ] = ++nIndex;
157 rOutMap[ C2U( "values-size" ) ] = ++nIndex;
160 struct lcl_DataSeriesContainerAppend : public
161 ::std::iterator< ::std::output_iterator_tag, Reference< XDataSeriesContainer > >
163 typedef ::std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;
165 explicit lcl_DataSeriesContainerAppend( tContainerType & rCnt )
166 : m_rDestCnt( rCnt )
169 lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
173 if( xVal.is())
175 Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
176 OUString aRole( RTL_CONSTASCII_USTRINGPARAM("values-y"));
177 Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
178 if( xCT.is())
179 aRole = xCT->getRoleOfSequenceForSeriesLabel();
180 for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
182 m_rDestCnt.push_back(
183 ::chart::DialogModel::tSeriesWithChartTypeByName(
184 ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
185 ::std::make_pair( aSeq[nI], xCT )));
189 catch( const uno::Exception & ex )
191 ASSERT_EXCEPTION( ex );
193 return *this;
196 lcl_DataSeriesContainerAppend & operator* () { return *this; }
197 lcl_DataSeriesContainerAppend & operator++ () { return *this; }
198 lcl_DataSeriesContainerAppend & operator++ (int) { return *this; }
200 private:
201 tContainerType & m_rDestCnt;
204 struct lcl_RolesWithRangeAppend : public
205 ::std::iterator< ::std::output_iterator_tag, Reference< data::XLabeledDataSequence > >
207 typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
209 explicit lcl_RolesWithRangeAppend( tContainerType & rCnt,
210 const ::rtl::OUString & aLabelRole )
211 : m_rDestCnt( rCnt ),
212 m_aRoleForLabelSeq( aLabelRole )
215 lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
219 if( xVal.is())
221 // data sequence
222 Reference< data::XDataSequence > xSeq( xVal->getValues());
223 if( xSeq.is())
225 OUString aRole;
226 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
227 if( xProp->getPropertyValue( C2U("Role")) >>= aRole )
229 m_rDestCnt.insert(
230 tContainerType::value_type(
231 aRole, xSeq->getSourceRangeRepresentation()));
232 // label
233 if( aRole.equals( m_aRoleForLabelSeq ))
235 Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
236 if( xLabelSeq.is())
238 m_rDestCnt.insert(
239 tContainerType::value_type(
240 lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation()));
247 catch( const uno::Exception & ex )
249 ASSERT_EXCEPTION( ex );
251 return *this;
254 lcl_RolesWithRangeAppend & operator* () { return *this; }
255 lcl_RolesWithRangeAppend & operator++ () { return *this; }
256 lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
258 private:
259 tContainerType & m_rDestCnt;
260 OUString m_aRoleForLabelSeq;
263 void lcl_SetSequenceRole(
264 const Reference< data::XDataSequence > & xSeq,
265 const OUString & rRole )
267 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
268 if( xProp.is())
269 xProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
272 Reference< XDataSeries > lcl_CreateNewSeries(
273 const Reference< uno::XComponentContext > & xContext,
274 const Reference< XChartType > & xChartType,
275 sal_Int32 nNewSeriesIndex,
276 sal_Int32 nTotalNumberOfSeriesInCTGroup,
277 const Reference< XDiagram > & xDiagram,
278 const Reference< XChartTypeTemplate > & xTemplate,
279 bool bCreateDataCachedSequences )
281 // create plain series
282 Reference< XDataSeries > xResult(
283 xContext->getServiceManager()->createInstanceWithContext(
284 C2U( "com.sun.star.chart2.DataSeries" ),
285 xContext ), uno::UNO_QUERY );
286 if( xTemplate.is())
288 Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
289 if( xResultProp.is())
291 // @deprecated: correct default color should be found by view
292 // without setting it as hard attribute
293 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
294 if( xColorScheme.is())
295 xResultProp->setPropertyValue(
296 C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nNewSeriesIndex )));
298 sal_Int32 nGroupIndex=0;
299 if( xChartType.is())
301 Sequence< Reference< XChartType > > aCTs(
302 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
303 for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
304 if( aCTs[nGroupIndex] == xChartType )
305 break;
306 if( nGroupIndex == aCTs.getLength())
307 nGroupIndex = 0;
309 xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
312 if( bCreateDataCachedSequences )
314 // set chart type specific roles
315 Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
316 if( xChartType.is() && xSink.is())
318 ::std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
319 const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
320 const OUString aLabel( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES )));
321 const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
322 const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
323 sal_Int32 nI = 0;
325 for(nI=0; nI<aRoles.getLength(); ++nI)
327 if( aRoles[nI].equals( lcl_aLabelRole ))
328 continue;
329 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
330 lcl_SetSequenceRole( xSeq, aRoles[nI] );
331 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
332 if( aRoles[nI].equals( aRoleOfSeqForSeriesLabel ))
334 Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
335 lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
336 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
338 else
339 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
342 for(nI=0; nI<aOptRoles.getLength(); ++nI)
344 if( aOptRoles[nI].equals( lcl_aLabelRole ))
345 continue;
346 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
347 lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
348 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
351 xSink->setData( ContainerToSequence( aNewSequences ));
355 return xResult;
358 struct lcl_addSeriesNumber : public ::std::binary_function<
359 sal_Int32, Reference< XDataSeriesContainer >, sal_Int32 >
361 sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
363 if( xCnt.is())
364 return nCurrentNumber + (xCnt->getDataSeries().getLength());
365 return nCurrentNumber;
369 } // anonymous namespace
371 // ----------------------------------------
374 namespace chart
377 DialogModel::DialogModel(
378 const Reference< XChartDocument > & xChartDocument,
379 const Reference< uno::XComponentContext > & xContext ) :
380 m_xChartDocument( xChartDocument ),
381 m_xContext( xContext ),
382 m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) )
386 DialogModel::~DialogModel()
389 void DialogModel::setTemplate(
390 const Reference< XChartTypeTemplate > & xTemplate )
392 m_xTemplate = xTemplate;
395 ::boost::shared_ptr< RangeSelectionHelper >
396 DialogModel::getRangeSelectionHelper() const
398 if( ! m_spRangeSelectionHelper.get())
399 m_spRangeSelectionHelper.reset(
400 new RangeSelectionHelper( m_xChartDocument ));
402 return m_spRangeSelectionHelper;
405 Reference< frame::XModel > DialogModel::getChartModel() const
407 Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY );
408 return xResult;
411 Reference< data::XDataProvider > DialogModel::getDataProvider() const
413 Reference< data::XDataProvider > xResult;
414 if( m_xChartDocument.is())
415 xResult.set( m_xChartDocument->getDataProvider());
416 return xResult;
419 ::std::vector< Reference< XDataSeriesContainer > >
420 DialogModel::getAllDataSeriesContainers() const
422 ::std::vector< Reference< XDataSeriesContainer > > aResult;
426 Reference< XDiagram > xDiagram;
427 if( m_xChartDocument.is())
428 xDiagram.set( m_xChartDocument->getFirstDiagram());
429 if( xDiagram.is())
431 Reference< XCoordinateSystemContainer > xCooSysCnt(
432 xDiagram, uno::UNO_QUERY_THROW );
433 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
434 xCooSysCnt->getCoordinateSystems());
435 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
437 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
438 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
439 ::std::transform(
440 aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
441 ::std::back_inserter( aResult ),
442 lcl_ChartTypeToSeriesCnt() );
446 catch( const uno::Exception & ex )
448 ASSERT_EXCEPTION( ex );
451 return aResult;
454 ::std::vector< DialogModel::tSeriesWithChartTypeByName >
455 DialogModel::getAllDataSeriesWithLabel() const
457 ::std::vector< tSeriesWithChartTypeByName > aResult;
458 ::std::vector< Reference< XDataSeriesContainer > > aContainers(
459 getAllDataSeriesContainers());
461 ::std::copy( aContainers.begin(), aContainers.end(),
462 lcl_DataSeriesContainerAppend( aResult ));
463 return aResult;
466 DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
467 const Reference< XDataSeries > & xSeries,
468 const ::rtl::OUString & aRoleOfSequenceForLabel,
469 const Reference< chart2::XChartType > & xChartType ) const
471 DialogModel::tRolesWithRanges aResult;
474 Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
475 const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
476 ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
477 lcl_RolesWithRangeAppend( aResult, aRoleOfSequenceForLabel ));
478 if( xChartType.is())
480 // add missing mandatory roles
481 Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
482 OUString aEmptyString;
483 sal_Int32 nI = 0;
484 for( nI=0; nI < aRoles.getLength(); ++nI )
486 if( aResult.find( aRoles[nI] ) == aResult.end() )
487 aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
490 // add missing optional roles
491 aRoles = xChartType->getSupportedOptionalRoles();
492 for( nI=0; nI < aRoles.getLength(); ++nI )
494 if( aResult.find( aRoles[nI] ) == aResult.end() )
495 aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
499 catch( const uno::Exception & ex )
501 ASSERT_EXCEPTION( ex );
503 return aResult;
506 void DialogModel::moveSeries(
507 const Reference< XDataSeries > & xSeries,
508 eMoveDirection eDirection )
510 m_aTimerTriggeredControllerLock.startTimer();
511 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
513 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
514 DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP );
517 Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
518 const Reference< XDataSeries > & xSeries,
519 const Reference< XChartType > & xChartType,
520 bool bCreateDataCachedSequences /* = false */ )
522 m_aTimerTriggeredControllerLock.startTimer();
523 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
524 Reference< XDataSeries > xNewSeries;
528 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
529 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
531 sal_Int32 nSeriesInChartType = 0;
532 const sal_Int32 nTotalSeries = countSeries();
533 if( xChartType.is())
535 Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW );
536 nSeriesInChartType = xCnt->getDataSeries().getLength();
539 // create new series
540 xNewSeries.set(
541 lcl_CreateNewSeries(
542 m_xContext,
543 xChartType,
544 nTotalSeries, // new series' index
545 nSeriesInChartType,
546 xDiagram,
547 m_xTemplate,
548 bCreateDataCachedSequences ));
550 // add new series to container
551 if( xNewSeries.is())
553 Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
554 ::std::vector< Reference< XDataSeries > > aSeries(
555 SequenceToVector( xSeriesCnt->getDataSeries()));
556 ::std::vector< Reference< XDataSeries > >::iterator aIt =
557 ::std::find( aSeries.begin(), aSeries.end(), xSeries );
558 if( aIt == aSeries.end())
559 // if we have no series we insert at the first position.
560 aIt = aSeries.begin();
561 else
562 // vector::insert inserts before, so we have to advance
563 ++aIt;
564 aSeries.insert( aIt, xNewSeries );
565 xSeriesCnt->setDataSeries( ContainerToSequence( aSeries ));
568 ThreeDHelper::setScheme( xDiagram, e3DScheme );
570 catch( const uno::Exception & ex )
572 ASSERT_EXCEPTION( ex );
574 return xNewSeries;
577 void DialogModel::deleteSeries(
578 const Reference< XDataSeries > & xSeries,
579 const Reference< XChartType > & xChartType )
581 m_aTimerTriggeredControllerLock.startTimer();
582 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
584 DataSeriesHelper::deleteSeries( xSeries, xChartType );
587 Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
589 Reference< data::XLabeledDataSequence > xResult;
592 if( m_xChartDocument.is())
594 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
595 xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
598 catch( const uno::Exception & ex )
600 ASSERT_EXCEPTION( ex );
602 return xResult;
605 void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
607 if( m_xChartDocument.is())
609 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
610 if( xDiagram.is())
612 // categories
613 bool bSupportsCategories = true;
615 Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
616 if( xFirstChartType.is() )
618 sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
619 bSupportsCategories = (nAxisType == AxisType::CATEGORY);
621 DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
626 OUString DialogModel::getCategoriesRange() const
628 Reference< data::XLabeledDataSequence > xLSeq( getCategories());
629 OUString aRange;
630 if( xLSeq.is())
632 Reference< data::XDataSequence > xSeq( xLSeq->getValues());
633 if( xSeq.is())
634 aRange = xSeq->getSourceRangeRepresentation();
636 return aRange;
639 bool DialogModel::isCategoryDiagram() const
641 bool bRet = false;
642 if( m_xChartDocument.is())
643 bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
644 return bRet;
647 void DialogModel::detectArguments(
648 OUString & rOutRangeString,
649 bool & rOutUseColumns,
650 bool & rOutFirstCellAsLabel,
651 bool & rOutHasCategories ) const
655 uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
657 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
658 if( m_xChartDocument.is())
659 DataSourceHelper::detectRangeSegmentation(
660 Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
661 rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
663 catch( const uno::Exception & ex )
665 ASSERT_EXCEPTION( ex );
669 bool DialogModel::allArgumentsForRectRangeDetected() const
671 return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
674 void DialogModel::startControllerLockTimer()
676 m_aTimerTriggeredControllerLock.startTimer();
679 bool DialogModel::setData(
680 const Sequence< beans::PropertyValue > & rArguments )
682 m_aTimerTriggeredControllerLock.startTimer();
683 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
685 Reference< data::XDataProvider > xDataProvider( getDataProvider());
686 if( ! xDataProvider.is() ||
687 ! m_xTemplate.is() )
689 OSL_FAIL( "Model objects missing" );
690 return false;
695 Reference< chart2::data::XDataSource > xDataSource(
696 xDataProvider->createDataSource( rArguments ) );
698 Reference< chart2::XDataInterpreter > xInterpreter(
699 m_xTemplate->getDataInterpreter());
700 if( xInterpreter.is())
702 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
703 ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
705 ::std::vector< Reference< XDataSeries > > aSeriesToReUse(
706 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
707 applyInterpretedData(
708 xInterpreter->interpretDataSource(
709 xDataSource, rArguments,
710 ContainerToSequence( aSeriesToReUse )),
711 aSeriesToReUse,
712 true /* bSetStyles */);
714 ThreeDHelper::setScheme( xDiagram, e3DScheme );
717 catch( const uno::Exception & ex )
719 ASSERT_EXCEPTION( ex );
720 return false;
723 return true;
726 OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
728 return lcl_ConvertRole( rRoleString, true );
731 OUString DialogModel::GetRoleDataLabel()
733 return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS )));
736 sal_Int32 DialogModel::GetRoleIndexForSorting( const ::rtl::OUString & rInternalRoleString )
738 static lcl_tRoleIndexMap aRoleIndexMap;
740 if( aRoleIndexMap.empty())
741 lcl_createRoleIndexMap( aRoleIndexMap );
743 lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
744 if( aIt != aRoleIndexMap.end())
745 return aIt->second;
747 return 0;
750 // private methods
752 void DialogModel::applyInterpretedData(
753 const InterpretedData & rNewData,
754 const ::std::vector< Reference< XDataSeries > > & rSeriesToReUse,
755 bool bSetStyles )
757 if( ! m_xChartDocument.is())
758 return;
760 m_aTimerTriggeredControllerLock.startTimer();
761 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
762 if( xDiagram.is())
764 // styles
765 if( bSetStyles && m_xTemplate.is() )
767 sal_Int32 nGroup = 0;
768 sal_Int32 nSeriesCounter = 0;
769 sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
770 const sal_Int32 nOuterSize=rNewData.Series.getLength();
772 for(; nGroup < nOuterSize; ++nGroup)
774 Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
775 const sal_Int32 nSeriesInGroup = aSeries.getLength();
776 for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
778 if( ::std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
779 == rSeriesToReUse.end())
781 Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
782 if( xSeriesProp.is())
784 // @deprecated: correct default color should be found by view
785 // without setting it as hard attribute
786 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
787 if( xColorScheme.is())
788 xSeriesProp->setPropertyValue(
789 C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nSeriesCounter )));
791 m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
797 // data series
798 ::std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
799 ::std::vector< Sequence< Reference< XDataSeries > > > aNewSeries(
800 SequenceToVector( rNewData.Series ));
802 OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());
804 ::std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
805 ::std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
806 for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
807 ++aSrcIt, ++aDestIt )
811 OSL_ASSERT( (*aDestIt).is());
812 (*aDestIt)->setDataSeries( *aSrcIt );
814 catch( const uno::Exception & ex )
816 ASSERT_EXCEPTION( ex );
820 DialogModel::setCategories(rNewData.Categories);
824 sal_Int32 DialogModel::countSeries() const
826 ::std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
827 return ::std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
830 } // namespace chart
832 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */