LibreOffice Module chart2 (master) 1
DialogModel.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "DialogModel.hxx"
22#include <DataInterpreter.hxx>
23#include <DataSeries.hxx>
24#include <DataSeriesHelper.hxx>
25#include <DataSourceHelper.hxx>
26#include <DiagramHelper.hxx>
27#include <Diagram.hxx>
28#include <strings.hrc>
29#include <ResId.hxx>
31#include <ChartType.hxx>
32#include <ChartTypeHelper.hxx>
33#include <ChartTypeTemplate.hxx>
34#include <ThreeDHelper.hxx>
35#include <ChartModel.hxx>
38
39#include <com/sun/star/chart2/AxisType.hpp>
40#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42
43#include <rtl/ustring.hxx>
44
45#include <utility>
46#include <algorithm>
47#include <cstddef>
48#include <iterator>
49#include <numeric>
50
51using namespace ::com::sun::star;
52using namespace ::com::sun::star::chart2;
53
54using ::com::sun::star::uno::Reference;
55using ::com::sun::star::uno::Sequence;
56
57namespace
58{
59constexpr OUStringLiteral lcl_aLabelRole( u"label" );
60
61
62OUString lcl_ConvertRole( const OUString & rRoleString )
63{
64 OUString aResult( rRoleString );
65
66 typedef std::map< OUString, OUString > tTranslationMap;
67 static const tTranslationMap aTranslationMap =
68 {
69 { "categories", ::chart::SchResId( STR_DATA_ROLE_CATEGORIES ) },
70 { "error-bars-x", ::chart::SchResId( STR_DATA_ROLE_X_ERROR ) },
71 { "error-bars-x-positive", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE ) },
72 { "error-bars-x-negative", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE ) },
73 { "error-bars-y", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR ) },
74 { "error-bars-y-positive", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE ) },
75 { "error-bars-y-negative", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE ) },
76 { "label", ::chart::SchResId( STR_DATA_ROLE_LABEL ) },
77 { "values-first", ::chart::SchResId( STR_DATA_ROLE_FIRST ) },
78 { "values-last", ::chart::SchResId( STR_DATA_ROLE_LAST ) },
79 { "values-max", ::chart::SchResId( STR_DATA_ROLE_MAX ) },
80 { "values-min", ::chart::SchResId( STR_DATA_ROLE_MIN ) },
81 { "values-x", ::chart::SchResId( STR_DATA_ROLE_X ) },
82 { "values-y", ::chart::SchResId( STR_DATA_ROLE_Y ) },
83 { "values-size", ::chart::SchResId( STR_DATA_ROLE_SIZE ) },
84 { "FillColor", ::chart::SchResId( STR_PROPERTY_ROLE_FILLCOLOR ) },
85 { "BorderColor", ::chart::SchResId( STR_PROPERTY_ROLE_BORDERCOLOR ) },
86 };
87
88 tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
89 if( aIt != aTranslationMap.end())
90 {
91 aResult = (*aIt).second;
92 }
93 return aResult;
94}
95
96typedef std::map< OUString, sal_Int32 > lcl_tRoleIndexMap;
97
98lcl_tRoleIndexMap lcl_createRoleIndexMap()
99{
100 lcl_tRoleIndexMap aMap;
101 sal_Int32 nIndex = 0;
102
103 aMap[ "label" ] = ++nIndex;
104 aMap[ "categories" ] = ++nIndex;
105 aMap[ "values-x" ] = ++nIndex;
106 aMap[ "values-y" ] = ++nIndex;
107 aMap[ "error-bars-x" ] = ++nIndex;
108 aMap[ "error-bars-x-positive" ] = ++nIndex;
109 aMap[ "error-bars-x-negative" ] = ++nIndex;
110 aMap[ "error-bars-y" ] = ++nIndex;
111 aMap[ "error-bars-y-positive" ] = ++nIndex;
112 aMap[ "error-bars-y-negative" ] = ++nIndex;
113 aMap[ "values-first" ] = ++nIndex;
114 aMap[ "values-min" ] = ++nIndex;
115 aMap[ "values-max" ] = ++nIndex;
116 aMap[ "values-last" ] = ++nIndex;
117 aMap[ "values-size" ] = ++nIndex;
118
119 return aMap;
120}
121
122
123struct lcl_RolesWithRangeAppend
124{
125 typedef Reference< data::XLabeledDataSequence > value_type;
126 typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
127
128 explicit lcl_RolesWithRangeAppend( tContainerType * rCnt,
129 OUString aLabelRole )
130 : m_rDestCnt( rCnt ),
131 m_aRoleForLabelSeq(std::move( aLabelRole ))
132 {}
133
134 lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
135 {
136 try
137 {
138 if( xVal.is())
139 {
140 // data sequence
141 Reference< data::XDataSequence > xSeq( xVal->getValues());
142 if( xSeq.is())
143 {
144 OUString aRole;
145 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
146 if( xProp->getPropertyValue( "Role" ) >>= aRole )
147 {
148 m_rDestCnt->emplace(aRole, xSeq->getSourceRangeRepresentation());
149 // label
150 if( aRole == m_aRoleForLabelSeq )
151 {
152 Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
153 if( xLabelSeq.is())
154 {
155 m_rDestCnt->emplace(
156 lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation());
157 }
158 }
159 }
160 }
161 }
162 }
163 catch( const uno::Exception & )
164 {
165 DBG_UNHANDLED_EXCEPTION("chart2");
166 }
167 return *this;
168 }
169
170 // Implement output operator requirements as required by std::copy (and
171 // implement prefix increment in terms of postfix increment to avoid unused
172 // member function warnings for the latter in the common case where
173 // std::copy would not actually need it):
174 lcl_RolesWithRangeAppend & operator* () { return *this; }
175 lcl_RolesWithRangeAppend & operator++ () { return operator++(0); }
176 lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
177
178private:
179 tContainerType * m_rDestCnt;
180 OUString m_aRoleForLabelSeq;
181};
182
183}
184
185namespace std
186{
187 template<> struct iterator_traits<lcl_RolesWithRangeAppend>
188 {
189 typedef std::output_iterator_tag iterator_category;
190 typedef Reference< data::XLabeledDataSequence > value_type;
192 };
193}
194
195namespace {
196
197void lcl_SetSequenceRole(
198 const Reference< data::XDataSequence > & xSeq,
199 const OUString & rRole )
200{
201 Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
202 if( xProp.is())
203 xProp->setPropertyValue( "Role" , uno::Any( rRole ));
204}
205
206Sequence< OUString > lcl_CopyExcludingValuesFirst(
207 Sequence< OUString > const & i_aInput )
208{
209 Sequence< OUString > aOutput( i_aInput.getLength());
210 auto pOutput = aOutput.getArray();
211 int nSourceIndex, nDestIndex;
212 for( nSourceIndex = nDestIndex = 0; nSourceIndex < i_aInput.getLength(); nSourceIndex++ )
213 {
214 if( i_aInput[nSourceIndex] == "values-first" )
215 {
216 aOutput.realloc( aOutput.getLength() - 1 );
217 pOutput = aOutput.getArray();
218 }
219 else
220 {
221 pOutput[nDestIndex] = i_aInput[nSourceIndex];
222 nDestIndex++;
223 }
224 }
225 return aOutput;
226}
227
228rtl::Reference< ::chart::DataSeries > lcl_CreateNewSeries(
229 const rtl::Reference< ::chart::ChartType > & xChartType,
230 sal_Int32 nNewSeriesIndex,
231 sal_Int32 nTotalNumberOfSeriesInCTGroup,
232 const rtl::Reference< ::chart::Diagram > & xDiagram,
234 bool bCreateDataCachedSequences )
235{
236 // create plain series
237 rtl::Reference< ::chart::DataSeries > xResult = new ::chart::DataSeries();
238 if( xTemplate.is())
239 {
240 // @deprecated: correct default color should be found by view
241 // without setting it as hard attribute
242 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
243 if( xColorScheme.is())
244 xResult->setPropertyValue( "Color" , uno::Any( xColorScheme->getColorByIndex( nNewSeriesIndex )));
245 std::size_t nGroupIndex=0;
246 if( xChartType.is())
247 {
248 std::vector< rtl::Reference< ::chart::ChartType > > aCTs =
249 xDiagram->getChartTypes();
250 for( ; nGroupIndex < aCTs.size(); ++nGroupIndex)
251 if( aCTs[nGroupIndex] == xChartType )
252 break;
253 if( nGroupIndex == aCTs.size())
254 nGroupIndex = 0;
255 }
256 xTemplate->applyStyle2( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
257 }
258
259 if( bCreateDataCachedSequences )
260 {
261 // set chart type specific roles
262 if( xChartType.is() )
263 {
264 std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aNewSequences;
265 const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
266 const OUString aLabel(::chart::SchResId(STR_DATA_UNNAMED_SERIES));
267 Sequence< OUString > aPossibleRoles( xChartType->getSupportedMandatoryRoles());
268 Sequence< OUString > aPossibleOptRoles( xChartType->getSupportedOptionalRoles());
269
270 //special handling for candlestick type
271 if( xTemplate.is())
272 {
273 rtl::Reference< ::chart::DataInterpreter > xInterpreter( xTemplate->getDataInterpreter2());
274 if( xInterpreter.is())
275 {
276 sal_Int32 nStockVariant;
277 if( xInterpreter->getChartTypeSpecificData("stock variant") >>= nStockVariant )
278 {
279 if( nStockVariant == 0 || nStockVariant == 2) {
280 //delete "values-first" role
281 aPossibleRoles = lcl_CopyExcludingValuesFirst(aPossibleRoles);
282 aPossibleOptRoles = lcl_CopyExcludingValuesFirst(aPossibleOptRoles);
283 }
284 }
285 }
286 }
287
288 const Sequence< OUString > aRoles( aPossibleRoles );
289 const Sequence< OUString > aOptRoles( aPossibleOptRoles );
290
291 for(OUString const & role : aRoles)
292 {
293 if( role == lcl_aLabelRole )
294 continue;
295 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
296 lcl_SetSequenceRole( xSeq, role );
297 // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
298 if( role == aRoleOfSeqForSeriesLabel )
299 {
300 Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
301 lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
302 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
303 }
304 else
305 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
306 }
307
308 for(OUString const & role : aOptRoles)
309 {
310 if( role == lcl_aLabelRole )
311 continue;
312 Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
313 lcl_SetSequenceRole( xSeq, role );
314 aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
315 }
316
317 xResult->setData( aNewSequences );
318 }
319 }
320
321 return xResult;
322}
323
324struct lcl_addSeriesNumber
325{
326 sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
327 {
328 if( xCnt.is())
329 return nCurrentNumber + (xCnt->getDataSeries().getLength());
330 return nCurrentNumber;
331 }
332};
333
334} // anonymous namespace
335
336namespace chart
337{
338
340 bTimeBased(false),
341 nStart(0),
342 nEnd(0)
343{
344}
345
347 rtl::Reference<::chart::ChartModel> xChartDocument ) :
348 m_xChartDocument(std::move( xChartDocument )),
349 m_aTimerTriggeredControllerLock( m_xChartDocument )
350{
351}
352
354{
356 {
357 getModel().setTimeBasedRange(maTimeBasedInfo.nStart, maTimeBasedInfo.nEnd);
358 }
359}
360
362 const rtl::Reference< ChartTypeTemplate > & xTemplate )
363{
364 m_xTemplate = xTemplate;
365}
366
367std::shared_ptr< RangeSelectionHelper > const &
369{
372 std::make_shared<RangeSelectionHelper>( m_xChartDocument );
373
375}
376
378{
379 return m_xChartDocument;
380}
381
383{
385 if( m_xChartDocument.is())
386 xResult.set( m_xChartDocument->getDataProvider());
387 return xResult;
388}
389
390std::vector< rtl::Reference< ChartType > >
392{
393 std::vector< rtl::Reference< ChartType > > aResult;
394
395 try
396 {
397 if( !m_xChartDocument )
398 return {};
399 rtl::Reference< Diagram > xDiagram = m_xChartDocument->getFirstChartDiagram();
400 if( xDiagram.is())
401 {
402 const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysSeq(
403 xDiagram->getBaseCoordinateSystems());
404 for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq )
405 {
406
407 for (const auto & rxChartType : coords->getChartTypes2())
408 aResult.push_back(rxChartType);
409 }
410 }
411 }
412 catch( const uno::Exception & )
413 {
414 DBG_UNHANDLED_EXCEPTION("chart2");
415 }
416
417 return aResult;
418}
419
420std::vector< DialogModel::tSeriesWithChartTypeByName >
422{
423 std::vector< tSeriesWithChartTypeByName > aResult;
424 std::vector< rtl::Reference< ChartType > > aContainers(
426
427 for (const auto & rxChartType : aContainers )
428 {
429 try
430 {
431 const std::vector< rtl::Reference< DataSeries > > & aSeq = rxChartType->getDataSeries2();
432 OUString aRole = rxChartType->getRoleOfSequenceForSeriesLabel();
433 for( rtl::Reference< DataSeries > const & dataSeries : aSeq )
434 {
435 aResult.push_back(
437 dataSeries->getLabelForRole( aRole ),
438 std::make_pair( dataSeries, rxChartType )));
439 }
440 }
441 catch( const uno::Exception & )
442 {
443 DBG_UNHANDLED_EXCEPTION("chart2");
444 }
445 }
446
447 return aResult;
448}
449
450namespace {
451
452void addMissingRoles(DialogModel::tRolesWithRanges& rResult, const uno::Sequence<OUString>& rRoles)
453{
454 for(OUString const & role : rRoles)
455 {
456 if(rResult.find(role) == rResult.end())
457 rResult.emplace(role, OUString());
458 }
459}
460
470void addNewSeriesToContainer(
471 const rtl::Reference<ChartType>& xChartType,
472 const rtl::Reference<DataSeries>& xSeries,
473 const rtl::Reference<DataSeries>& xNewSeries )
474{
475 auto aSeries = xChartType->getDataSeries2();
476
477 auto aIt = std::find( aSeries.begin(), aSeries.end(), xSeries);
478
479 if( aIt == aSeries.end())
480 // if we have no series we insert at the first position.
481 aIt = aSeries.begin();
482 else
483 // vector::insert inserts before, so we have to advance
484 ++aIt;
485
486 aSeries.insert(aIt, xNewSeries);
487 xChartType->setDataSeries(aSeries);
488}
489
490}
491
493 const Reference< XDataSeries > & xSeries,
494 const OUString & aRoleOfSequenceForLabel,
495 const rtl::Reference< ::chart::ChartType > & xChartType )
496{
498 try
499 {
500 Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
501 const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
502 std::copy( aSeq.begin(), aSeq.end(),
503 lcl_RolesWithRangeAppend( &aResult, aRoleOfSequenceForLabel ));
504 if( xChartType.is())
505 {
506 // add missing mandatory roles
507 Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
508 addMissingRoles(aResult, aRoles);
509
510 // add missing optional roles
511 aRoles = xChartType->getSupportedOptionalRoles();
512 addMissingRoles(aResult, aRoles);
513
514 // add missing property roles
515 aRoles = xChartType->getSupportedPropertyRoles();
516 addMissingRoles(aResult, aRoles);
517 }
518 }
519 catch( const uno::Exception & )
520 {
521 DBG_UNHANDLED_EXCEPTION("chart2");
522 }
523 return aResult;
524}
525
527 const rtl::Reference< DataSeries > & xSeries,
528 MoveDirection eDirection )
529{
531 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
532
533 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
534 xDiagram->moveSeries( xSeries, eDirection==MoveDirection::Down );
535}
536
538 const Reference< XDataSeries > & xUnoSeries,
539 const rtl::Reference< ::chart::ChartType > & xChartType,
540 bool bCreateDataCachedSequences /* = false */ )
541{
543 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
545 rtl::Reference<DataSeries> xSeries = dynamic_cast<DataSeries*>(xUnoSeries.get());
546 assert(xSeries || !xUnoSeries);
547
548 try
549 {
550 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram() );
551 ThreeDLookScheme e3DScheme = xDiagram->detectScheme();
552
553 sal_Int32 nSeriesInChartType = 0;
554 const sal_Int32 nTotalSeries = countSeries();
555 if( xChartType.is())
556 {
557 nSeriesInChartType = xChartType->getDataSeries().getLength();
558 }
559
560 // create new series
561 xNewSeries =
562 lcl_CreateNewSeries(
563 xChartType,
564 nTotalSeries, // new series' index
565 nSeriesInChartType,
566 xDiagram,
568 bCreateDataCachedSequences );
569
570 // add new series to container
571 if( xNewSeries.is())
572 addNewSeriesToContainer(xChartType, xSeries, xNewSeries);
573
574 xDiagram->setScheme( e3DScheme );
575 }
576 catch( const uno::Exception & )
577 {
578 DBG_UNHANDLED_EXCEPTION("chart2");
579 }
580 return xNewSeries;
581}
582
584 const rtl::Reference< DataSeries > & xSeries,
585 const rtl::Reference< ChartType > & xChartType )
586{
588 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
589
590 DataSeriesHelper::deleteSeries( xSeries, xChartType );
591}
592
594{
596 try
597 {
598 if( m_xChartDocument.is())
599 {
600 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
601 if (xDiagram.is())
602 xResult = xDiagram->getCategories();
603 }
604 }
605 catch( const uno::Exception & )
606 {
607 DBG_UNHANDLED_EXCEPTION("chart2");
608 }
609 return xResult;
610}
611
613{
614 if( !m_xChartDocument.is())
615 return;
616
617 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
618 if( !xDiagram.is())
619 return;
620
621 // categories
622 bool bSupportsCategories = true;
623
624 rtl::Reference< ChartType > xFirstChartType( xDiagram->getChartTypeByIndex( 0 ) );
625 if( xFirstChartType.is() )
626 {
627 sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
628 bSupportsCategories = (nAxisType == AxisType::CATEGORY);
629 }
630 xDiagram->setCategories( xCategories, true, bSupportsCategories );
631}
632
634{
635 OUString aRange;
636 try
637 {
639 if( xLSeq.is())
640 {
641 Reference< data::XDataSequence > xSeq( xLSeq->getValues());
642 if( xSeq.is())
643 aRange = xSeq->getSourceRangeRepresentation();
644 }
645 }
646 catch (const lang::DisposedException&)
647 {
648 TOOLS_WARN_EXCEPTION( "chart2", "unexpected exception caught" );
649 }
650 return aRange;
651}
652
654{
655 bool bRet = false;
656 if( m_xChartDocument.is() && m_xChartDocument->getFirstChartDiagram())
657 bRet = m_xChartDocument->getFirstChartDiagram()->isCategory();
658 return bRet;
659}
660
662 OUString & rOutRangeString,
663 bool & rOutUseColumns,
664 bool & rOutFirstCellAsLabel,
665 bool & rOutHasCategories ) const
666{
667 try
668 {
669 uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
670
671 // Note: unused data is currently not supported in being passed to detectRangeSegmentation
672 if( m_xChartDocument.is())
673 {
676 rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
677 }
678 }
679 catch( const uno::Exception & )
680 {
681 DBG_UNHANDLED_EXCEPTION("chart2");
682 }
683}
684
686{
688}
689
691{
693}
694
696 const Sequence< beans::PropertyValue > & rArguments )
697{
699 ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
700
702 if( ! xDataProvider.is() ||
703 ! m_xTemplate.is() )
704 {
705 OSL_FAIL( "Model objects missing" );
706 return;
707 }
708
709 try
710 {
712 xDataProvider->createDataSource( rArguments ) );
713
715 m_xTemplate->getDataInterpreter2());
716 if( xInterpreter.is())
717 {
718 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram() );
719 ThreeDLookScheme e3DScheme = xDiagram->detectScheme();
720
721 std::vector< rtl::Reference< DataSeries > > aSeriesToReUse =
722 xDiagram->getDataSeries();
724 xInterpreter->interpretDataSource(
725 xDataSource, rArguments,
726 aSeriesToReUse ),
727 aSeriesToReUse);
728
729 xDiagram->setScheme( e3DScheme );
730 }
731 }
732 catch( const uno::Exception & )
733 {
734 DBG_UNHANDLED_EXCEPTION("chart2");
735 }
736}
737
738void DialogModel::setTimeBasedRange( bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const
739{
740 maTimeBasedInfo.nStart = nStart;
741 maTimeBasedInfo.nEnd = nEnd;
742 maTimeBasedInfo.bTimeBased = bTimeBased;
743}
744
745OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
746{
747 return lcl_ConvertRole( rRoleString );
748}
749
751{
752 return ::chart::SchResId(STR_OBJECT_DATALABELS);
753}
754
755sal_Int32 DialogModel::GetRoleIndexForSorting( const OUString & rInternalRoleString )
756{
757 static lcl_tRoleIndexMap aRoleIndexMap = lcl_createRoleIndexMap();
758
759 lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
760 if( aIt != aRoleIndexMap.end())
761 return aIt->second;
762
763 return 0;
764}
765
766// private methods
767
769 const InterpretedData & rNewData,
770 const std::vector< rtl::Reference< DataSeries > > & rSeriesToReUse )
771{
772 if( ! m_xChartDocument.is())
773 return;
774
776 rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
777 if( !xDiagram.is())
778 return;
779
780 // styles
781 if( m_xTemplate.is() )
782 {
783 sal_Int32 nGroup = 0;
784 sal_Int32 nSeriesCounter = 0;
785 sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
786 const sal_Int32 nOuterSize=rNewData.Series.size();
787
788 for(; nGroup < nOuterSize; ++nGroup)
789 {
790 const std::vector< rtl::Reference< DataSeries > > & aSeries( rNewData.Series[ nGroup ] );
791 const sal_Int32 nSeriesInGroup = aSeries.size();
792 for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
793 {
794 if( std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
795 == rSeriesToReUse.end())
796 {
797 if( aSeries[nSeries].is())
798 {
799 // @deprecated: correct default color should be found by view
800 // without setting it as hard attribute
801 Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
802 if( xColorScheme.is())
803 aSeries[nSeries]->setPropertyValue( "Color" ,
804 uno::Any( xColorScheme->getColorByIndex( nSeriesCounter )));
805 }
806 m_xTemplate->applyStyle2( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
807 }
808 }
809 }
810 }
811
812 // data series
813 std::vector< rtl::Reference< ChartType > > aSeriesCnt = getAllDataSeriesContainers();
814
815 OSL_ASSERT( aSeriesCnt.size() == rNewData.Series.size());
816
817 auto aSrcIt = rNewData.Series.begin();
818 auto aDestIt = aSeriesCnt.begin();
819 for(; aSrcIt != rNewData.Series.end() && aDestIt != aSeriesCnt.end();
820 ++aSrcIt, ++aDestIt )
821 {
822 try
823 {
824 OSL_ASSERT( (*aDestIt).is());
825 (*aDestIt)->setDataSeries( *aSrcIt );
826 }
827 catch( const uno::Exception & )
828 {
829 DBG_UNHANDLED_EXCEPTION("chart2");
830 }
831 }
832
834}
835
837{
838 std::vector< rtl::Reference< ChartType > > aCnt( getAllDataSeriesContainers());
839 return std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
840}
841
842ChartModel& DialogModel::getModel() const
843{
844 return *m_xChartDocument;
845}
846
847} // namespace chart
848
849/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static sal_Int32 getAxisType(const rtl::Reference< ::chart::ChartType > &xChartType, sal_Int32 nDimensionIndex)
This guard calls lockControllers at the given Model in the CTOR and unlockControllers in the DTOR.
static bool detectRangeSegmentation(const rtl::Reference<::chart::ChartModel > &xChartModel, OUString &rOutRangeString, css::uno::Sequence< sal_Int32 > &rSequenceMapping, bool &rOutUseColumns, bool &rOutFirstCellAsLabel, bool &rOutHasCategories)
static css::uno::Reference< css::chart2::data::XDataSequence > createCachedDataSequence()
static bool allArgumentsForRectRangeDetected(const rtl::Reference<::chart::ChartModel > &xChartDocument)
Returns true, if all arguments necessary for getting all data by a rectangular region are returned by...
static rtl::Reference< LabeledDataSequence > createLabeledDataSequence()
std::vector< rtl::Reference< ::chart::ChartType > > getAllDataSeriesContainers() const
void setData(const css::uno::Sequence< css::beans::PropertyValue > &rArguments)
const rtl::Reference<::chart::ChartModel > & getChartModel() const
DialogModel(rtl::Reference<::chart::ChartModel > xChartDocument)
bool isCategoryDiagram() const
std::pair< OUString, std::pair< rtl::Reference< ::chart::DataSeries >, rtl::Reference< ::chart::ChartType > > > tSeriesWithChartTypeByName
Definition: DialogModel.hxx:74
std::shared_ptr< RangeSelectionHelper > m_spRangeSelectionHelper
void setCategories(const css::uno::Reference< css::chart2::data::XLabeledDataSequence > &xCategories)
static OUString GetRoleDataLabel()
void detectArguments(OUString &rOutRangeString, bool &rOutUseColumns, bool &rOutFirstCellAsLabel, bool &rOutHasCategories) const
std::vector< tSeriesWithChartTypeByName > getAllDataSeriesWithLabel() const
void setTemplate(const rtl::Reference< ::chart::ChartTypeTemplate > &xTemplate)
void setTimeBasedRange(bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const
void deleteSeries(const rtl::Reference< ::chart::DataSeries > &xSeries, const rtl::Reference< ::chart::ChartType > &xChartType)
rtl::Reference< ::chart::DataSeries > insertSeriesAfter(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, const rtl::Reference< ::chart::ChartType > &xChartType, bool bCreateDataCachedSequences=false)
std::map< OUString, OUString > tRolesWithRanges
Definition: DialogModel.hxx:77
bool allArgumentsForRectRangeDetected() const
css::uno::Reference< css::chart2::data::XDataProvider > getDataProvider() const
static OUString ConvertRoleFromInternalToUI(const OUString &rRoleString)
ChartModel & getModel() const
void moveSeries(const rtl::Reference< DataSeries > &xSeries, MoveDirection eDirection)
sal_Int32 countSeries() const
std::shared_ptr< RangeSelectionHelper > const & getRangeSelectionHelper() const
void startControllerLockTimer()
rtl::Reference<::chart::ChartModel > m_xChartDocument
TimerTriggeredControllerLock m_aTimerTriggeredControllerLock
static sal_Int32 GetRoleIndexForSorting(const OUString &rInternalRoleString)
css::uno::Reference< css::chart2::data::XLabeledDataSequence > getCategories() const
DialogModelTimeBasedInfo maTimeBasedInfo
static tRolesWithRanges getRolesWithRanges(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, const OUString &aRoleOfSequenceForLabel, const rtl::Reference< ::chart::ChartType > &xChartType)
rtl::Reference< ::chart::ChartTypeTemplate > m_xTemplate
OUString getCategoriesRange() const
void applyInterpretedData(const InterpretedData &rNewData, const std::vector< rtl::Reference< ::chart::DataSeries > > &rSeriesToReUse)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
SotClipboardFormatId & operator++(SotClipboardFormatId &eFormat)
sal_Int32 nIndex
Sequence< sal_Int8 > aSeq
OOO_DLLPUBLIC_CHARTTOOLS void deleteSeries(const rtl::Reference< ::chart::DataSeries > &xSeries, const rtl::Reference< ::chart::ChartType > &xChartType)
ThreeDLookScheme
OUString OOO_DLLPUBLIC_CHARTTOOLS SchResId(TranslateId aId)
Definition: ResId.cxx:24
HashMap_OWString_Interface aMap
offers tooling to interpret different data sources in a structural and chart-type-dependent way.
std::vector< std::vector< rtl::Reference<::chart::DataSeries > > > Series
css::uno::Reference< css::chart2::data::XLabeledDataSequence > Categories
Reference< data::XLabeledDataSequence > value_type
OUString aLabel