Update ooo320-m1
[ooovba.git] / chart2 / source / controller / dialogs / DialogModel.cxx
blobaab0775c887a4da7411eddabaa324c17ffc9c5ff
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DialogModel.cxx,v $
10 * $Revision: 1.7.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "DialogModel.hxx"
35 #include "RangeSelectionHelper.hxx"
36 #include "PropertyHelper.hxx"
37 #include "DataSeriesHelper.hxx"
38 #include "DataSourceHelper.hxx"
39 #include "DiagramHelper.hxx"
40 #include "macros.hxx"
41 #include "Strings.hrc"
42 #include "ResId.hxx"
43 #include "ContainerHelper.hxx"
44 #include "CommonFunctors.hxx"
45 #include "ControllerLockGuard.hxx"
46 #include "ChartTypeHelper.hxx"
48 #include <com/sun/star/util/XCloneable.hpp>
49 #include <com/sun/star/chart2/AxisType.hpp>
50 #include <com/sun/star/chart2/XTitled.hpp>
51 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
52 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
53 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
54 #include <com/sun/star/chart2/data/XDataSink.hpp>
56 #include <tools/string.hxx>
58 #include <utility>
59 #include <algorithm>
60 #include <iterator>
61 #include <functional>
62 #include <numeric>
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::chart2;
66 using namespace ::chart::ContainerHelper;
68 using ::com::sun::star::uno::Reference;
69 using ::com::sun::star::uno::Sequence;
70 using ::rtl::OUString;
72 // ----------------------------------------
74 namespace
76 const OUString lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" ));
78 struct lcl_ChartTypeToSeriesCnt : ::std::unary_function<
79 Reference< XChartType >, Reference< XDataSeriesContainer > >
81 Reference< XDataSeriesContainer > operator() (
82 const Reference< XChartType > & xChartType )
84 return Reference< XDataSeriesContainer >::query( xChartType );
88 OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI )
90 OUString aResult( rRoleString );
92 typedef ::std::map< OUString, OUString > tTranslationMap;
93 static tTranslationMap aTranslationMap;
95 if( aTranslationMap.size() == 0 )
97 aTranslationMap[ C2U( "categories" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_CATEGORIES )));
98 aTranslationMap[ C2U( "error-bars-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR )));
99 aTranslationMap[ C2U( "error-bars-x-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE )));
100 aTranslationMap[ C2U( "error-bars-x-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE )));
101 aTranslationMap[ C2U( "error-bars-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR )));
102 aTranslationMap[ C2U( "error-bars-y-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE )));
103 aTranslationMap[ C2U( "error-bars-y-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE )));
104 aTranslationMap[ C2U( "label" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LABEL )));
105 aTranslationMap[ C2U( "values-first" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_FIRST )));
106 aTranslationMap[ C2U( "values-last" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LAST )));
107 aTranslationMap[ C2U( "values-max" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MAX )));
108 aTranslationMap[ C2U( "values-min" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN )));
109 aTranslationMap[ C2U( "values-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X )));
110 aTranslationMap[ C2U( "values-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y )));
111 aTranslationMap[ C2U( "values-size" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE )));
114 if( bFromInternalToUI )
116 tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
117 if( aIt != aTranslationMap.end())
119 aResult = (*aIt).second;
122 else
124 tTranslationMap::const_iterator aIt(
125 ::std::find_if( aTranslationMap.begin(), aTranslationMap.end(),
126 ::std::compose1( ::std::bind2nd(
127 ::std::equal_to< tTranslationMap::mapped_type >(),
128 rRoleString ),
129 ::std::select2nd< tTranslationMap::value_type >())));
131 if( aIt != aTranslationMap.end())
132 aResult = (*aIt).first;
135 return aResult;
138 typedef ::std::map< ::rtl::OUString, sal_Int32 > lcl_tRoleIndexMap;
140 void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
142 rOutMap.clear();
143 sal_Int32 nIndex = 0;
145 rOutMap[ C2U( "label" ) ] = ++nIndex;
146 rOutMap[ C2U( "categories" ) ] = ++nIndex;
147 rOutMap[ C2U( "values-x" ) ] = ++nIndex;
148 rOutMap[ C2U( "values-y" ) ] = ++nIndex;
149 rOutMap[ C2U( "error-bars-x" ) ] = ++nIndex;
150 rOutMap[ C2U( "error-bars-x-positive" ) ] = ++nIndex;
151 rOutMap[ C2U( "error-bars-x-negative" ) ] = ++nIndex;
152 rOutMap[ C2U( "error-bars-y" ) ] = ++nIndex;
153 rOutMap[ C2U( "error-bars-y-positive" ) ] = ++nIndex;
154 rOutMap[ C2U( "error-bars-y-negative" ) ] = ++nIndex;
155 rOutMap[ C2U( "values-first" ) ] = ++nIndex;
156 rOutMap[ C2U( "values-min" ) ] = ++nIndex;
157 rOutMap[ C2U( "values-max" ) ] = ++nIndex;
158 rOutMap[ C2U( "values-last" ) ] = ++nIndex;
159 rOutMap[ C2U( "values-size" ) ] = ++nIndex;
162 struct lcl_DataSeriesContainerAppend : public
163 ::std::iterator< ::std::output_iterator_tag, Reference< XDataSeriesContainer > >
165 typedef ::std::vector< chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;
167 explicit lcl_DataSeriesContainerAppend( tContainerType & rCnt )
168 : m_rDestCnt( rCnt )
171 lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
175 if( xVal.is())
177 Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
178 OUString aRole( RTL_CONSTASCII_USTRINGPARAM("values-y"));
179 Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
180 if( xCT.is())
181 aRole = xCT->getRoleOfSequenceForSeriesLabel();
182 for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
184 m_rDestCnt.push_back(
185 chart::DialogModel::tSeriesWithChartTypeByName(
186 ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
187 ::std::make_pair( aSeq[nI], xCT )));
191 catch( uno::Exception & ex )
193 ASSERT_EXCEPTION( ex );
195 return *this;
198 lcl_DataSeriesContainerAppend & operator* () { return *this; }
199 lcl_DataSeriesContainerAppend & operator++ () { return *this; }
200 lcl_DataSeriesContainerAppend & operator++ (int) { return *this; }
202 private:
203 tContainerType & m_rDestCnt;
206 struct lcl_RolesWithRangeAppend : public
207 ::std::iterator< ::std::output_iterator_tag, Reference< data::XLabeledDataSequence > >
209 typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
211 explicit lcl_RolesWithRangeAppend( tContainerType & rCnt,
212 const ::rtl::OUString & aLabelRole )
213 : m_rDestCnt( rCnt ),
214 m_aRoleForLabelSeq( aLabelRole )
217 lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
221 if( xVal.is())
223 // data sequence
224 Reference< data::XDataSequence > xSeq( xVal->getValues());
225 if( xSeq.is())
227 OUString aRole;
228 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
229 if( xProp->getPropertyValue( C2U("Role")) >>= aRole )
231 m_rDestCnt.insert(
232 tContainerType::value_type(
233 aRole, xSeq->getSourceRangeRepresentation()));
234 // label
235 if( aRole.equals( m_aRoleForLabelSeq ))
237 Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
238 if( xLabelSeq.is())
240 m_rDestCnt.insert(
241 tContainerType::value_type(
242 lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation()));
249 catch( uno::Exception & ex )
251 ASSERT_EXCEPTION( ex );
253 return *this;
256 lcl_RolesWithRangeAppend & operator* () { return *this; }
257 lcl_RolesWithRangeAppend & operator++ () { return *this; }
258 lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
260 private:
261 tContainerType & m_rDestCnt;
262 OUString m_aRoleForLabelSeq;
265 void lcl_SetSequenceRole(
266 const Reference< data::XDataSequence > & xSeq,
267 const OUString & rRole )
269 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
270 if( xProp.is())
271 xProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
274 Reference< XDataSeries > lcl_CreateNewSeries(
275 const Reference< uno::XComponentContext > & xContext,
276 const Reference< XChartType > & xChartType,
277 sal_Int32 nNewSeriesIndex,
278 sal_Int32 nTotalNumberOfSeriesInCTGroup,
279 const Reference< XDiagram > & xDiagram,
280 const Reference< XChartTypeTemplate > & xTemplate,
281 bool bCreateDataCachedSequences )
283 // create plain series
284 Reference< XDataSeries > xResult(
285 xContext->getServiceManager()->createInstanceWithContext(
286 C2U( "com.sun.star.chart2.DataSeries" ),
287 xContext ), uno::UNO_QUERY );
288 if( xTemplate.is())
290 Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
291 if( xResultProp.is())
293 // @deprecated: correct default color should be found by view
294 // without setting it as hard attribute
295 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
296 if( xColorScheme.is())
297 xResultProp->setPropertyValue(
298 C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nNewSeriesIndex )));
300 sal_Int32 nGroupIndex=0;
301 if( xChartType.is())
303 Sequence< Reference< XChartType > > aCTs(
304 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
305 for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
306 if( aCTs[nGroupIndex] == xChartType )
307 break;
308 if( nGroupIndex == aCTs.getLength())
309 nGroupIndex = 0;
311 xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
314 if( bCreateDataCachedSequences )
316 // set chart type specific roles
317 Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
318 if( xChartType.is() && xSink.is())
320 ::std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
321 const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
322 const OUString aLabel( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES )));
323 const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
324 const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
325 sal_Int32 nI = 0;
327 for(nI=0; nI<aRoles.getLength(); ++nI)
329 if( aRoles[nI].equals( lcl_aLabelRole ))
330 continue;
331 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
332 lcl_SetSequenceRole( xSeq, aRoles[nI] );
333 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
334 if( aRoles[nI].equals( aRoleOfSeqForSeriesLabel ))
336 Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
337 lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
338 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
340 else
341 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
344 for(nI=0; nI<aOptRoles.getLength(); ++nI)
346 if( aOptRoles[nI].equals( lcl_aLabelRole ))
347 continue;
348 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
349 lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
350 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
353 xSink->setData( ContainerToSequence( aNewSequences ));
357 return xResult;
360 struct lcl_addSeriesNumber : public ::std::binary_function<
361 sal_Int32, Reference< XDataSeriesContainer >, sal_Int32 >
363 sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
365 if( xCnt.is())
366 return nCurrentNumber + (xCnt->getDataSeries().getLength());
367 return nCurrentNumber;
371 } // anonymous namespace
373 // ----------------------------------------
376 namespace chart
379 DialogModel::DialogModel(
380 const Reference< XChartDocument > & xChartDocument,
381 const Reference< uno::XComponentContext > & xContext ) :
382 m_xChartDocument( xChartDocument ),
383 m_xContext( xContext ),
384 m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) )
386 createBackup();
389 DialogModel::~DialogModel()
392 void DialogModel::setTemplate(
393 const Reference< XChartTypeTemplate > & xTemplate )
395 m_xTemplate = xTemplate;
398 ::boost::shared_ptr< RangeSelectionHelper >
399 DialogModel::getRangeSelectionHelper() const
401 if( ! m_spRangeSelectionHelper.get())
402 m_spRangeSelectionHelper.reset(
403 new RangeSelectionHelper( m_xChartDocument ));
405 return m_spRangeSelectionHelper;
408 Reference< frame::XModel > DialogModel::getChartModel() const
410 Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY );
411 return xResult;
414 Reference< data::XDataProvider > DialogModel::getDataProvider() const
416 Reference< data::XDataProvider > xResult;
417 if( m_xChartDocument.is())
418 xResult.set( m_xChartDocument->getDataProvider());
419 return xResult;
422 ::std::vector< Reference< XDataSeriesContainer > >
423 DialogModel::getAllDataSeriesContainers() const
425 ::std::vector< Reference< XDataSeriesContainer > > aResult;
429 Reference< XDiagram > xDiagram;
430 if( m_xChartDocument.is())
431 xDiagram.set( m_xChartDocument->getFirstDiagram());
432 if( xDiagram.is())
434 Reference< XCoordinateSystemContainer > xCooSysCnt(
435 xDiagram, uno::UNO_QUERY_THROW );
436 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
437 xCooSysCnt->getCoordinateSystems());
438 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
440 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
441 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
442 ::std::transform(
443 aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
444 ::std::back_inserter( aResult ),
445 lcl_ChartTypeToSeriesCnt() );
449 catch( uno::Exception & ex )
451 ASSERT_EXCEPTION( ex );
454 return aResult;
457 ::std::vector< DialogModel::tSeriesWithChartTypeByName >
458 DialogModel::getAllDataSeriesWithLabel() const
460 ::std::vector< tSeriesWithChartTypeByName > aResult;
461 ::std::vector< Reference< XDataSeriesContainer > > aContainers(
462 getAllDataSeriesContainers());
464 ::std::copy( aContainers.begin(), aContainers.end(),
465 lcl_DataSeriesContainerAppend( aResult ));
466 return aResult;
469 DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
470 const Reference< XDataSeries > & xSeries,
471 const ::rtl::OUString & aRoleOfSequenceForLabel,
472 const Reference< chart2::XChartType > & xChartType ) const
474 DialogModel::tRolesWithRanges aResult;
477 Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
478 const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
479 ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
480 lcl_RolesWithRangeAppend( aResult, aRoleOfSequenceForLabel ));
481 if( xChartType.is())
483 // add missing mandatory roles
484 Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
485 OUString aEmptyString;
486 sal_Int32 nI = 0;
487 for( nI=0; nI < aRoles.getLength(); ++nI )
489 if( aResult.find( aRoles[nI] ) == aResult.end() )
490 aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
493 // add missing optional roles
494 aRoles = xChartType->getSupportedOptionalRoles();
495 for( nI=0; nI < aRoles.getLength(); ++nI )
497 if( aResult.find( aRoles[nI] ) == aResult.end() )
498 aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
502 catch( uno::Exception & ex )
504 ASSERT_EXCEPTION( ex );
506 return aResult;
509 void DialogModel::moveSeries(
510 const Reference< XDataSeries > & xSeries,
511 eMoveDirection eDirection )
513 m_aTimerTriggeredControllerLock.startTimer();
514 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
516 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
517 DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP );
520 Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
521 const Reference< XDataSeries > & xSeries,
522 const Reference< XChartType > & xChartType,
523 bool bCreateDataCachedSequences /* = false */ )
525 m_aTimerTriggeredControllerLock.startTimer();
526 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
527 Reference< XDataSeries > xNewSeries;
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 m_xChartDocument->getFirstDiagram(),
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 catch( uno::Exception & ex )
570 ASSERT_EXCEPTION( ex );
572 return xNewSeries;
575 void DialogModel::deleteSeries(
576 const Reference< XDataSeries > & xSeries,
577 const Reference< XChartType > & xChartType )
579 m_aTimerTriggeredControllerLock.startTimer();
580 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
582 DataSeriesHelper::deleteSeries( xSeries, xChartType );
585 Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
587 Reference< data::XLabeledDataSequence > xResult;
590 if( m_xChartDocument.is())
592 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
593 xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
596 catch( uno::Exception & ex )
598 ASSERT_EXCEPTION( ex );
600 return xResult;
603 void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
605 if( m_xChartDocument.is())
607 Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
608 if( xDiagram.is())
610 // categories
611 bool bSupportsCategories = true;
613 Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
614 if( xFirstChartType.is() )
616 sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
617 bSupportsCategories = (nAxisType == AxisType::CATEGORY);
619 DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
624 OUString DialogModel::getCategoriesRange() const
626 Reference< data::XLabeledDataSequence > xLSeq( getCategories());
627 OUString aRange;
628 if( xLSeq.is())
630 Reference< data::XDataSequence > xSeq( xLSeq->getValues());
631 if( xSeq.is())
632 aRange = xSeq->getSourceRangeRepresentation();
634 return aRange;
637 bool DialogModel::isCategoryDiagram() const
639 bool bRet = false;
640 if( m_xChartDocument.is())
641 bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
642 return bRet;
645 void DialogModel::detectArguments(
646 OUString & rOutRangeString,
647 bool & rOutUseColumns,
648 bool & rOutFirstCellAsLabel,
649 bool & rOutHasCategories ) const
653 uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
655 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
656 if( m_xChartDocument.is())
657 DataSourceHelper::detectRangeSegmentation(
658 Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
659 rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
661 catch( uno::Exception & ex )
663 ASSERT_EXCEPTION( ex );
667 bool DialogModel::allArgumentsForRectRangeDetected() const
669 return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
672 void DialogModel::startControllerLockTimer()
674 m_aTimerTriggeredControllerLock.startTimer();
677 bool DialogModel::setData(
678 const Sequence< beans::PropertyValue > & rArguments )
680 m_aTimerTriggeredControllerLock.startTimer();
681 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
683 Reference< data::XDataProvider > xDataProvider( getDataProvider());
684 if( ! xDataProvider.is() ||
685 ! m_xTemplate.is() )
687 OSL_ENSURE( false, "Model objects missing" );
688 return false;
693 Reference< chart2::data::XDataSource > xDataSource(
694 xDataProvider->createDataSource( rArguments ) );
696 Reference< chart2::XDataInterpreter > xInterpreter(
697 m_xTemplate->getDataInterpreter());
698 if( xInterpreter.is())
700 ::std::vector< Reference< XDataSeries > > aSeriesToReUse(
701 DiagramHelper::getDataSeriesFromDiagram( m_xChartDocument->getFirstDiagram()));
702 applyInterpretedData(
703 xInterpreter->interpretDataSource(
704 xDataSource, rArguments,
705 ContainerToSequence( aSeriesToReUse )),
706 aSeriesToReUse,
707 true /* bSetStyles */);
710 catch( uno::Exception & ex )
712 ASSERT_EXCEPTION( ex );
713 return false;
716 return true;
719 // static
720 OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
722 return lcl_ConvertRole( rRoleString, true );
725 // static
726 OUString DialogModel::GetRoleDataLabel()
728 return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS )));
731 // static
733 sal_Int32 DialogModel::GetRoleIndexForSorting( const ::rtl::OUString & rInternalRoleString )
735 static lcl_tRoleIndexMap aRoleIndexMap;
737 if( aRoleIndexMap.empty())
738 lcl_createRoleIndexMap( aRoleIndexMap );
740 lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
741 if( aIt != aRoleIndexMap.end())
742 return aIt->second;
744 return 0;
747 // private methods
749 void DialogModel::createBackup()
751 OSL_ENSURE( ! m_xBackupChartDocument.is(), "Cloning already cloned model" );
754 Reference< util::XCloneable > xCloneable( m_xChartDocument, uno::UNO_QUERY_THROW );
755 m_xBackupChartDocument.set( xCloneable->createClone(), uno::UNO_QUERY_THROW );
757 catch( uno::Exception & ex )
759 ASSERT_EXCEPTION( ex );
763 void DialogModel::applyInterpretedData(
764 const InterpretedData & rNewData,
765 const ::std::vector< Reference< XDataSeries > > & rSeriesToReUse,
766 bool bSetStyles )
768 if( ! m_xChartDocument.is())
769 return;
771 m_aTimerTriggeredControllerLock.startTimer();
772 Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
773 if( xDiagram.is())
775 // styles
776 if( bSetStyles && m_xTemplate.is() )
778 sal_Int32 nGroup = 0;
779 sal_Int32 nSeriesCounter = 0;
780 sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
781 const sal_Int32 nOuterSize=rNewData.Series.getLength();
783 for(; nGroup < nOuterSize; ++nGroup)
785 Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
786 const sal_Int32 nSeriesInGroup = aSeries.getLength();
787 for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
789 if( ::std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
790 == rSeriesToReUse.end())
792 Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
793 if( xSeriesProp.is())
795 // @deprecated: correct default color should be found by view
796 // without setting it as hard attribute
797 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
798 if( xColorScheme.is())
799 xSeriesProp->setPropertyValue(
800 C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nSeriesCounter )));
802 m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
808 // data series
809 ::std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
810 ::std::vector< Sequence< Reference< XDataSeries > > > aNewSeries(
811 SequenceToVector( rNewData.Series ));
813 OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());
815 ::std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
816 ::std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
817 for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
818 ++aSrcIt, ++aDestIt )
822 OSL_ASSERT( (*aDestIt).is());
823 (*aDestIt)->setDataSeries( *aSrcIt );
825 catch( uno::Exception & ex )
827 ASSERT_EXCEPTION( ex );
831 DialogModel::setCategories(rNewData.Categories);
834 OSL_ASSERT( ! rNewData.UnusedData.hasElements());
837 sal_Int32 DialogModel::countSeries() const
839 ::std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
840 return ::std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
843 } // namespace chart