Branch data Line data Source code
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 : :
21 : : #include "DialogModel.hxx"
22 : : #include "RangeSelectionHelper.hxx"
23 : : #include "PropertyHelper.hxx"
24 : : #include "DataSeriesHelper.hxx"
25 : : #include "DataSourceHelper.hxx"
26 : : #include "DiagramHelper.hxx"
27 : : #include "macros.hxx"
28 : : #include "Strings.hrc"
29 : : #include "ResId.hxx"
30 : : #include "ContainerHelper.hxx"
31 : : #include "CommonFunctors.hxx"
32 : : #include "ControllerLockGuard.hxx"
33 : : #include "ChartTypeHelper.hxx"
34 : : #include "ThreeDHelper.hxx"
35 : :
36 : : #include <com/sun/star/util/XCloneable.hpp>
37 : : #include <com/sun/star/chart2/AxisType.hpp>
38 : : #include <com/sun/star/chart2/XTitled.hpp>
39 : : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
40 : : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
41 : : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42 : : #include <com/sun/star/chart2/data/XDataSink.hpp>
43 : :
44 : : #include <tools/string.hxx>
45 : :
46 : : #include <utility>
47 : : #include <algorithm>
48 : : #include <iterator>
49 : : #include <functional>
50 : : #include <numeric>
51 : : #include <o3tl/compat_functional.hxx>
52 : :
53 : : using namespace ::com::sun::star;
54 : : using namespace ::com::sun::star::chart2;
55 : : using namespace ::chart::ContainerHelper;
56 : :
57 : : using ::com::sun::star::uno::Reference;
58 : : using ::com::sun::star::uno::Sequence;
59 : : using ::rtl::OUString;
60 : :
61 : : // ----------------------------------------
62 : :
63 : : namespace
64 : : {
65 : 16 : const OUString lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" ));
66 : :
67 : : struct lcl_ChartTypeToSeriesCnt : ::std::unary_function<
68 : : Reference< XChartType >, Reference< XDataSeriesContainer > >
69 : : {
70 : 0 : Reference< XDataSeriesContainer > operator() (
71 : : const Reference< XChartType > & xChartType )
72 : : {
73 : 0 : return Reference< XDataSeriesContainer >::query( xChartType );
74 : : }
75 : : };
76 : :
77 : 0 : OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI )
78 : : {
79 : 0 : OUString aResult( rRoleString );
80 : :
81 : : typedef ::std::map< OUString, OUString > tTranslationMap;
82 [ # # ][ # # ]: 0 : static tTranslationMap aTranslationMap;
[ # # ][ # # ]
83 : :
84 [ # # ]: 0 : if( aTranslationMap.empty() )
85 : : {
86 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "categories" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_CATEGORIES )));
[ # # ][ # # ]
[ # # ][ # # ]
87 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR )));
[ # # ][ # # ]
[ # # ][ # # ]
88 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-x-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE )));
[ # # ][ # # ]
[ # # ][ # # ]
89 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-x-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE )));
[ # # ][ # # ]
[ # # ][ # # ]
90 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR )));
[ # # ][ # # ]
[ # # ][ # # ]
91 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-y-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE )));
[ # # ][ # # ]
[ # # ][ # # ]
92 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "error-bars-y-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE )));
[ # # ][ # # ]
[ # # ][ # # ]
93 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "label" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LABEL )));
[ # # ][ # # ]
[ # # ][ # # ]
94 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-first" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_FIRST )));
[ # # ][ # # ]
[ # # ][ # # ]
95 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-last" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LAST )));
[ # # ][ # # ]
[ # # ][ # # ]
96 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-max" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MAX )));
[ # # ][ # # ]
[ # # ][ # # ]
97 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-min" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN )));
[ # # ][ # # ]
[ # # ][ # # ]
98 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X )));
[ # # ][ # # ]
[ # # ][ # # ]
99 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y )));
[ # # ][ # # ]
[ # # ][ # # ]
100 [ # # ][ # # ]: 0 : aTranslationMap[ C2U( "values-size" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE )));
[ # # ][ # # ]
[ # # ][ # # ]
101 : : }
102 : :
103 [ # # ]: 0 : if( bFromInternalToUI )
104 : : {
105 [ # # ]: 0 : tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
106 [ # # ]: 0 : if( aIt != aTranslationMap.end())
107 : : {
108 : 0 : aResult = (*aIt).second;
109 : : }
110 : : }
111 : : else
112 : : {
113 : : tTranslationMap::const_iterator aIt(
114 : : ::std::find_if( aTranslationMap.begin(), aTranslationMap.end(),
115 : : ::o3tl::compose1( ::std::bind2nd(
116 : : ::std::equal_to< tTranslationMap::mapped_type >(),
117 : : rRoleString ),
118 [ # # ][ # # ]: 0 : ::o3tl::select2nd< tTranslationMap::value_type >())));
[ # # ]
119 : :
120 [ # # ]: 0 : if( aIt != aTranslationMap.end())
121 : 0 : aResult = (*aIt).first;
122 : : }
123 : :
124 : 0 : return aResult;
125 : : }
126 : :
127 : : typedef ::std::map< ::rtl::OUString, sal_Int32 > lcl_tRoleIndexMap;
128 : :
129 : 0 : void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap )
130 : : {
131 : 0 : rOutMap.clear();
132 : 0 : sal_Int32 nIndex = 0;
133 : :
134 [ # # ]: 0 : rOutMap[ C2U( "label" ) ] = ++nIndex;
135 [ # # ]: 0 : rOutMap[ C2U( "categories" ) ] = ++nIndex;
136 [ # # ]: 0 : rOutMap[ C2U( "values-x" ) ] = ++nIndex;
137 [ # # ]: 0 : rOutMap[ C2U( "values-y" ) ] = ++nIndex;
138 [ # # ]: 0 : rOutMap[ C2U( "error-bars-x" ) ] = ++nIndex;
139 [ # # ]: 0 : rOutMap[ C2U( "error-bars-x-positive" ) ] = ++nIndex;
140 [ # # ]: 0 : rOutMap[ C2U( "error-bars-x-negative" ) ] = ++nIndex;
141 [ # # ]: 0 : rOutMap[ C2U( "error-bars-y" ) ] = ++nIndex;
142 [ # # ]: 0 : rOutMap[ C2U( "error-bars-y-positive" ) ] = ++nIndex;
143 [ # # ]: 0 : rOutMap[ C2U( "error-bars-y-negative" ) ] = ++nIndex;
144 [ # # ]: 0 : rOutMap[ C2U( "values-first" ) ] = ++nIndex;
145 [ # # ]: 0 : rOutMap[ C2U( "values-min" ) ] = ++nIndex;
146 [ # # ]: 0 : rOutMap[ C2U( "values-max" ) ] = ++nIndex;
147 [ # # ]: 0 : rOutMap[ C2U( "values-last" ) ] = ++nIndex;
148 [ # # ]: 0 : rOutMap[ C2U( "values-size" ) ] = ++nIndex;
149 : 0 : }
150 : :
151 : : struct lcl_DataSeriesContainerAppend : public
152 : : ::std::iterator< ::std::output_iterator_tag, Reference< XDataSeriesContainer > >
153 : : {
154 : : typedef ::std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType;
155 : :
156 : 0 : explicit lcl_DataSeriesContainerAppend( tContainerType & rCnt )
157 : 0 : : m_rDestCnt( rCnt )
158 : 0 : {}
159 : :
160 : 0 : lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal )
161 : : {
162 : : try
163 : : {
164 [ # # ]: 0 : if( xVal.is())
165 : : {
166 [ # # ][ # # ]: 0 : Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries());
167 [ # # ]: 0 : OUString aRole( RTL_CONSTASCII_USTRINGPARAM("values-y"));
168 [ # # ]: 0 : Reference< XChartType > xCT( xVal, uno::UNO_QUERY );
169 [ # # ]: 0 : if( xCT.is())
170 [ # # ][ # # ]: 0 : aRole = xCT->getRoleOfSequenceForSeriesLabel();
171 [ # # ]: 0 : for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI )
172 : : {
173 : : m_rDestCnt.push_back(
174 : : ::chart::DialogModel::tSeriesWithChartTypeByName(
175 [ # # ]: 0 : ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ),
176 [ # # ][ # # ]: 0 : ::std::make_pair( aSeq[nI], xCT )));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
177 [ # # ][ # # ]: 0 : }
178 : : }
179 : : }
180 : 0 : catch( const uno::Exception & ex )
181 : : {
182 : : ASSERT_EXCEPTION( ex );
183 : : }
184 : 0 : return *this;
185 : : }
186 : :
187 : 0 : lcl_DataSeriesContainerAppend & operator* () { return *this; }
188 : 0 : lcl_DataSeriesContainerAppend & operator++ () { return *this; }
189 : : lcl_DataSeriesContainerAppend & operator++ (int) { return *this; }
190 : :
191 : : private:
192 : : tContainerType & m_rDestCnt;
193 : : };
194 : :
195 : 0 : struct lcl_RolesWithRangeAppend : public
196 : : ::std::iterator< ::std::output_iterator_tag, Reference< data::XLabeledDataSequence > >
197 : : {
198 : : typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
199 : :
200 : 0 : explicit lcl_RolesWithRangeAppend( tContainerType & rCnt,
201 : : const ::rtl::OUString & aLabelRole )
202 : : : m_rDestCnt( rCnt ),
203 : 0 : m_aRoleForLabelSeq( aLabelRole )
204 : 0 : {}
205 : :
206 : 0 : lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
207 : : {
208 : : try
209 : : {
210 [ # # ]: 0 : if( xVal.is())
211 : : {
212 : : // data sequence
213 [ # # ][ # # ]: 0 : Reference< data::XDataSequence > xSeq( xVal->getValues());
214 [ # # ]: 0 : if( xSeq.is())
215 : : {
216 : 0 : OUString aRole;
217 [ # # ]: 0 : Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
218 [ # # ][ # # ]: 0 : if( xProp->getPropertyValue( C2U("Role")) >>= aRole )
[ # # ][ # # ]
219 : : {
220 : : m_rDestCnt.insert(
221 : : tContainerType::value_type(
222 [ # # ][ # # ]: 0 : aRole, xSeq->getSourceRangeRepresentation()));
[ # # ]
223 : : // label
224 [ # # ]: 0 : if( aRole.equals( m_aRoleForLabelSeq ))
225 : : {
226 [ # # ][ # # ]: 0 : Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
227 [ # # ]: 0 : if( xLabelSeq.is())
228 : : {
229 : : m_rDestCnt.insert(
230 : : tContainerType::value_type(
231 [ # # ][ # # ]: 0 : lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation()));
[ # # ]
232 : 0 : }
233 : : }
234 : 0 : }
235 [ # # ]: 0 : }
236 : : }
237 : : }
238 : 0 : catch( const uno::Exception & ex )
239 : : {
240 : : ASSERT_EXCEPTION( ex );
241 : : }
242 : 0 : return *this;
243 : : }
244 : :
245 : 0 : lcl_RolesWithRangeAppend & operator* () { return *this; }
246 : 0 : lcl_RolesWithRangeAppend & operator++ () { return *this; }
247 : : lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
248 : :
249 : : private:
250 : : tContainerType & m_rDestCnt;
251 : : OUString m_aRoleForLabelSeq;
252 : : };
253 : :
254 : 0 : void lcl_SetSequenceRole(
255 : : const Reference< data::XDataSequence > & xSeq,
256 : : const OUString & rRole )
257 : : {
258 [ # # ]: 0 : Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
259 [ # # ]: 0 : if( xProp.is())
260 [ # # ][ # # ]: 0 : xProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
[ # # ][ # # ]
261 : 0 : }
262 : :
263 : 0 : Reference< XDataSeries > lcl_CreateNewSeries(
264 : : const Reference< uno::XComponentContext > & xContext,
265 : : const Reference< XChartType > & xChartType,
266 : : sal_Int32 nNewSeriesIndex,
267 : : sal_Int32 nTotalNumberOfSeriesInCTGroup,
268 : : const Reference< XDiagram > & xDiagram,
269 : : const Reference< XChartTypeTemplate > & xTemplate,
270 : : bool bCreateDataCachedSequences )
271 : : {
272 : : // create plain series
273 : : Reference< XDataSeries > xResult(
274 [ # # ]: 0 : xContext->getServiceManager()->createInstanceWithContext(
275 : : C2U( "com.sun.star.chart2.DataSeries" ),
276 [ # # ][ # # ]: 0 : xContext ), uno::UNO_QUERY );
[ # # ]
277 [ # # ]: 0 : if( xTemplate.is())
278 : : {
279 [ # # ]: 0 : Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY );
280 [ # # ]: 0 : if( xResultProp.is())
281 : : {
282 : : // @deprecated: correct default color should be found by view
283 : : // without setting it as hard attribute
284 [ # # ][ # # ]: 0 : Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
285 [ # # ]: 0 : if( xColorScheme.is())
286 [ # # ]: 0 : xResultProp->setPropertyValue(
287 [ # # ][ # # ]: 0 : C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nNewSeriesIndex )));
[ # # ][ # # ]
[ # # ]
288 : : }
289 : 0 : sal_Int32 nGroupIndex=0;
290 [ # # ]: 0 : if( xChartType.is())
291 : : {
292 : : Sequence< Reference< XChartType > > aCTs(
293 [ # # ]: 0 : ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ));
294 [ # # ]: 0 : for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex)
295 [ # # ][ # # ]: 0 : if( aCTs[nGroupIndex] == xChartType )
[ # # ]
296 : 0 : break;
297 [ # # ]: 0 : if( nGroupIndex == aCTs.getLength())
298 [ # # ]: 0 : nGroupIndex = 0;
299 : : }
300 [ # # ][ # # ]: 0 : xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
301 : : }
302 : :
303 [ # # ]: 0 : if( bCreateDataCachedSequences )
304 : : {
305 : : // set chart type specific roles
306 [ # # ]: 0 : Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY );
307 [ # # ][ # # ]: 0 : if( xChartType.is() && xSink.is())
[ # # ]
308 : : {
309 [ # # ]: 0 : ::std::vector< Reference< data::XLabeledDataSequence > > aNewSequences;
310 [ # # ][ # # ]: 0 : const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
311 [ # # ][ # # ]: 0 : const OUString aLabel( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES )));
[ # # ][ # # ]
312 [ # # ][ # # ]: 0 : const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
313 [ # # ][ # # ]: 0 : const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
314 : 0 : sal_Int32 nI = 0;
315 : :
316 [ # # ]: 0 : for(nI=0; nI<aRoles.getLength(); ++nI)
317 : : {
318 [ # # ]: 0 : if( aRoles[nI].equals( lcl_aLabelRole ))
319 : 0 : continue;
320 [ # # ]: 0 : Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
321 [ # # ]: 0 : lcl_SetSequenceRole( xSeq, aRoles[nI] );
322 : : // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
323 [ # # ]: 0 : if( aRoles[nI].equals( aRoleOfSeqForSeriesLabel ))
324 : : {
325 [ # # ]: 0 : Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
326 [ # # ]: 0 : lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
327 [ # # ][ # # ]: 0 : aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
328 : : }
329 : : else
330 [ # # ][ # # ]: 0 : aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
331 : 0 : }
332 : :
333 [ # # ]: 0 : for(nI=0; nI<aOptRoles.getLength(); ++nI)
334 : : {
335 [ # # ]: 0 : if( aOptRoles[nI].equals( lcl_aLabelRole ))
336 : 0 : continue;
337 [ # # ]: 0 : Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
338 [ # # ]: 0 : lcl_SetSequenceRole( xSeq, aOptRoles[nI] );
339 [ # # ][ # # ]: 0 : aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
340 : 0 : }
341 : :
342 [ # # ][ # # ]: 0 : xSink->setData( ContainerToSequence( aNewSequences ));
[ # # ][ # # ]
[ # # ][ # # ]
343 : 0 : }
344 : : }
345 : :
346 : 0 : return xResult;
347 : : }
348 : :
349 : : struct lcl_addSeriesNumber : public ::std::binary_function<
350 : : sal_Int32, Reference< XDataSeriesContainer >, sal_Int32 >
351 : : {
352 : 0 : sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
353 : : {
354 [ # # ]: 0 : if( xCnt.is())
355 : 0 : return nCurrentNumber + (xCnt->getDataSeries().getLength());
356 : 0 : return nCurrentNumber;
357 : : }
358 : : };
359 : :
360 : : } // anonymous namespace
361 : :
362 : : // ----------------------------------------
363 : :
364 : :
365 : : namespace chart
366 : : {
367 : :
368 : 0 : DialogModel::DialogModel(
369 : : const Reference< XChartDocument > & xChartDocument,
370 : : const Reference< uno::XComponentContext > & xContext ) :
371 : : m_xChartDocument( xChartDocument ),
372 : : m_xContext( xContext ),
373 [ # # ][ # # ]: 0 : m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) )
[ # # ]
374 : : {
375 : 0 : }
376 : :
377 [ # # ][ # # ]: 0 : DialogModel::~DialogModel()
378 : 0 : {}
379 : :
380 : 0 : void DialogModel::setTemplate(
381 : : const Reference< XChartTypeTemplate > & xTemplate )
382 : : {
383 : 0 : m_xTemplate = xTemplate;
384 : 0 : }
385 : :
386 : : ::boost::shared_ptr< RangeSelectionHelper >
387 : 0 : DialogModel::getRangeSelectionHelper() const
388 : : {
389 [ # # ]: 0 : if( ! m_spRangeSelectionHelper.get())
390 : : m_spRangeSelectionHelper.reset(
391 [ # # ]: 0 : new RangeSelectionHelper( m_xChartDocument ));
392 : :
393 : 0 : return m_spRangeSelectionHelper;
394 : : }
395 : :
396 : 0 : Reference< frame::XModel > DialogModel::getChartModel() const
397 : : {
398 : 0 : Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY );
399 : 0 : return xResult;
400 : : }
401 : :
402 : 0 : Reference< data::XDataProvider > DialogModel::getDataProvider() const
403 : : {
404 : 0 : Reference< data::XDataProvider > xResult;
405 [ # # ]: 0 : if( m_xChartDocument.is())
406 [ # # ][ # # ]: 0 : xResult.set( m_xChartDocument->getDataProvider());
[ # # ]
407 : 0 : return xResult;
408 : : }
409 : :
410 : : ::std::vector< Reference< XDataSeriesContainer > >
411 : 0 : DialogModel::getAllDataSeriesContainers() const
412 : : {
413 : 0 : ::std::vector< Reference< XDataSeriesContainer > > aResult;
414 : :
415 : : try
416 : : {
417 : 0 : Reference< XDiagram > xDiagram;
418 [ # # ]: 0 : if( m_xChartDocument.is())
419 [ # # ][ # # ]: 0 : xDiagram.set( m_xChartDocument->getFirstDiagram());
[ # # ]
420 [ # # ]: 0 : if( xDiagram.is())
421 : : {
422 : : Reference< XCoordinateSystemContainer > xCooSysCnt(
423 [ # # ]: 0 : xDiagram, uno::UNO_QUERY_THROW );
424 : : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
425 [ # # ][ # # ]: 0 : xCooSysCnt->getCoordinateSystems());
426 [ # # ]: 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
427 : : {
428 [ # # ][ # # ]: 0 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
429 [ # # ][ # # ]: 0 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
430 : : ::std::transform(
431 : 0 : aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
432 : : ::std::back_inserter( aResult ),
433 [ # # # # ]: 0 : lcl_ChartTypeToSeriesCnt() );
434 [ # # ][ # # ]: 0 : }
435 [ # # ]: 0 : }
436 : : }
437 [ # # ]: 0 : catch( const uno::Exception & ex )
438 : : {
439 : : ASSERT_EXCEPTION( ex );
440 : : }
441 : :
442 : 0 : return aResult;
443 : : }
444 : :
445 : : ::std::vector< DialogModel::tSeriesWithChartTypeByName >
446 : 0 : DialogModel::getAllDataSeriesWithLabel() const
447 : : {
448 [ # # ]: 0 : ::std::vector< tSeriesWithChartTypeByName > aResult;
449 : : ::std::vector< Reference< XDataSeriesContainer > > aContainers(
450 [ # # ]: 0 : getAllDataSeriesContainers());
451 : :
452 : : ::std::copy( aContainers.begin(), aContainers.end(),
453 [ # # ]: 0 : lcl_DataSeriesContainerAppend( aResult ));
454 : 0 : return aResult;
455 : : }
456 : :
457 : 0 : DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
458 : : const Reference< XDataSeries > & xSeries,
459 : : const ::rtl::OUString & aRoleOfSequenceForLabel,
460 : : const Reference< chart2::XChartType > & xChartType ) const
461 : : {
462 : 0 : DialogModel::tRolesWithRanges aResult;
463 : : try
464 : : {
465 [ # # ]: 0 : Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
466 [ # # ][ # # ]: 0 : const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
467 : 0 : ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
468 [ # # ]: 0 : lcl_RolesWithRangeAppend( aResult, aRoleOfSequenceForLabel ));
469 [ # # ]: 0 : if( xChartType.is())
470 : : {
471 : : // add missing mandatory roles
472 [ # # ][ # # ]: 0 : Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
473 : 0 : OUString aEmptyString;
474 : 0 : sal_Int32 nI = 0;
475 [ # # ]: 0 : for( nI=0; nI < aRoles.getLength(); ++nI )
476 : : {
477 [ # # ][ # # ]: 0 : if( aResult.find( aRoles[nI] ) == aResult.end() )
[ # # ]
478 [ # # ][ # # ]: 0 : aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
479 : : }
480 : :
481 : : // add missing optional roles
482 [ # # ][ # # ]: 0 : aRoles = xChartType->getSupportedOptionalRoles();
[ # # ][ # # ]
483 [ # # ]: 0 : for( nI=0; nI < aRoles.getLength(); ++nI )
484 : : {
485 [ # # ][ # # ]: 0 : if( aResult.find( aRoles[nI] ) == aResult.end() )
[ # # ]
486 [ # # ][ # # ]: 0 : aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString ));
487 [ # # ]: 0 : }
488 [ # # ][ # # ]: 0 : }
489 : : }
490 [ # # ]: 0 : catch( const uno::Exception & ex )
491 : : {
492 : : ASSERT_EXCEPTION( ex );
493 : : }
494 : 0 : return aResult;
495 : : }
496 : :
497 : 0 : void DialogModel::moveSeries(
498 : : const Reference< XDataSeries > & xSeries,
499 : : eMoveDirection eDirection )
500 : : {
501 [ # # ]: 0 : m_aTimerTriggeredControllerLock.startTimer();
502 [ # # ][ # # ]: 0 : ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
503 : :
504 [ # # ][ # # ]: 0 : Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
505 [ # # ][ # # ]: 0 : DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP );
506 : 0 : }
507 : :
508 : 0 : Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter(
509 : : const Reference< XDataSeries > & xSeries,
510 : : const Reference< XChartType > & xChartType,
511 : : bool bCreateDataCachedSequences /* = false */ )
512 : : {
513 [ # # ]: 0 : m_aTimerTriggeredControllerLock.startTimer();
514 [ # # ][ # # ]: 0 : ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
515 : 0 : Reference< XDataSeries > xNewSeries;
516 : :
517 : : try
518 : : {
519 [ # # ][ # # ]: 0 : Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
520 [ # # ]: 0 : ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
521 : :
522 : 0 : sal_Int32 nSeriesInChartType = 0;
523 [ # # ]: 0 : const sal_Int32 nTotalSeries = countSeries();
524 [ # # ]: 0 : if( xChartType.is())
525 : : {
526 [ # # ]: 0 : Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW );
527 [ # # ][ # # ]: 0 : nSeriesInChartType = xCnt->getDataSeries().getLength();
[ # # ]
528 : : }
529 : :
530 : : // create new series
531 : : xNewSeries.set(
532 : : lcl_CreateNewSeries(
533 : : m_xContext,
534 : : xChartType,
535 : : nTotalSeries, // new series' index
536 : : nSeriesInChartType,
537 : : xDiagram,
538 : : m_xTemplate,
539 [ # # ][ # # ]: 0 : bCreateDataCachedSequences ));
540 : :
541 : : // add new series to container
542 [ # # ]: 0 : if( xNewSeries.is())
543 : : {
544 [ # # ]: 0 : Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
545 : : ::std::vector< Reference< XDataSeries > > aSeries(
546 [ # # ][ # # ]: 0 : SequenceToVector( xSeriesCnt->getDataSeries()));
[ # # ][ # # ]
547 : : ::std::vector< Reference< XDataSeries > >::iterator aIt =
548 [ # # ]: 0 : ::std::find( aSeries.begin(), aSeries.end(), xSeries );
549 [ # # ][ # # ]: 0 : if( aIt == aSeries.end())
550 : : // if we have no series we insert at the first position.
551 : 0 : aIt = aSeries.begin();
552 : : else
553 : : // vector::insert inserts before, so we have to advance
554 : 0 : ++aIt;
555 [ # # ]: 0 : aSeries.insert( aIt, xNewSeries );
556 [ # # ][ # # ]: 0 : xSeriesCnt->setDataSeries( ContainerToSequence( aSeries ));
[ # # ][ # # ]
557 : : }
558 : :
559 [ # # ][ # # ]: 0 : ThreeDHelper::setScheme( xDiagram, e3DScheme );
560 : : }
561 [ # # ]: 0 : catch( const uno::Exception & ex )
562 : : {
563 : : ASSERT_EXCEPTION( ex );
564 : : }
565 [ # # ]: 0 : return xNewSeries;
566 : : }
567 : :
568 : 0 : void DialogModel::deleteSeries(
569 : : const Reference< XDataSeries > & xSeries,
570 : : const Reference< XChartType > & xChartType )
571 : : {
572 [ # # ]: 0 : m_aTimerTriggeredControllerLock.startTimer();
573 [ # # ][ # # ]: 0 : ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
574 : :
575 [ # # ][ # # ]: 0 : DataSeriesHelper::deleteSeries( xSeries, xChartType );
576 : 0 : }
577 : :
578 : 0 : Reference< data::XLabeledDataSequence > DialogModel::getCategories() const
579 : : {
580 : 0 : Reference< data::XLabeledDataSequence > xResult;
581 : : try
582 : : {
583 [ # # ]: 0 : if( m_xChartDocument.is())
584 : : {
585 [ # # ][ # # ]: 0 : Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
586 [ # # ][ # # ]: 0 : xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram ));
[ # # ]
587 : : }
588 : : }
589 [ # # ]: 0 : catch( const uno::Exception & ex )
590 : : {
591 : : ASSERT_EXCEPTION( ex );
592 : : }
593 : 0 : return xResult;
594 : : }
595 : :
596 : 0 : void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
597 : : {
598 [ # # ]: 0 : if( m_xChartDocument.is())
599 : : {
600 [ # # ][ # # ]: 0 : Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
601 [ # # ]: 0 : if( xDiagram.is())
602 : : {
603 : : // categories
604 : 0 : bool bSupportsCategories = true;
605 : :
606 [ # # ]: 0 : Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
607 [ # # ]: 0 : if( xFirstChartType.is() )
608 : : {
609 [ # # ]: 0 : sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
610 : 0 : bSupportsCategories = (nAxisType == AxisType::CATEGORY);
611 : : }
612 [ # # ]: 0 : DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories );
613 : 0 : }
614 : : }
615 : 0 : }
616 : :
617 : 0 : OUString DialogModel::getCategoriesRange() const
618 : : {
619 [ # # ]: 0 : Reference< data::XLabeledDataSequence > xLSeq( getCategories());
620 : 0 : OUString aRange;
621 [ # # ]: 0 : if( xLSeq.is())
622 : : {
623 [ # # ][ # # ]: 0 : Reference< data::XDataSequence > xSeq( xLSeq->getValues());
624 [ # # ]: 0 : if( xSeq.is())
625 [ # # ][ # # ]: 0 : aRange = xSeq->getSourceRangeRepresentation();
626 : : }
627 : 0 : return aRange;
628 : : }
629 : :
630 : 0 : bool DialogModel::isCategoryDiagram() const
631 : : {
632 : 0 : bool bRet = false;
633 [ # # ]: 0 : if( m_xChartDocument.is())
634 [ # # ]: 0 : bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() );
635 : 0 : return bRet;
636 : : }
637 : :
638 : 0 : void DialogModel::detectArguments(
639 : : OUString & rOutRangeString,
640 : : bool & rOutUseColumns,
641 : : bool & rOutFirstCellAsLabel,
642 : : bool & rOutHasCategories ) const
643 : : {
644 : : try
645 : : {
646 [ # # ]: 0 : uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
647 : :
648 : : // Note: unused data is currently not supported in being passed to detectRangeSegmentation
649 [ # # ]: 0 : if( m_xChartDocument.is())
650 : : DataSourceHelper::detectRangeSegmentation(
651 : : Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ),
652 [ # # ][ # # ]: 0 : rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
[ # # ][ # # ]
653 : : }
654 : 0 : catch( const uno::Exception & ex )
655 : : {
656 : : ASSERT_EXCEPTION( ex );
657 : : }
658 : 0 : }
659 : :
660 : 0 : bool DialogModel::allArgumentsForRectRangeDetected() const
661 : : {
662 : 0 : return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
663 : : }
664 : :
665 : 0 : void DialogModel::startControllerLockTimer()
666 : : {
667 : 0 : m_aTimerTriggeredControllerLock.startTimer();
668 : 0 : }
669 : :
670 : 0 : bool DialogModel::setData(
671 : : const Sequence< beans::PropertyValue > & rArguments )
672 : : {
673 [ # # ]: 0 : m_aTimerTriggeredControllerLock.startTimer();
674 [ # # ][ # # ]: 0 : ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
675 : :
676 [ # # ]: 0 : Reference< data::XDataProvider > xDataProvider( getDataProvider());
677 [ # # # # ]: 0 : if( ! xDataProvider.is() ||
[ # # ]
678 : 0 : ! m_xTemplate.is() )
679 : : {
680 : : OSL_FAIL( "Model objects missing" );
681 : 0 : return false;
682 : : }
683 : :
684 : : try
685 : : {
686 : : Reference< chart2::data::XDataSource > xDataSource(
687 [ # # ][ # # ]: 0 : xDataProvider->createDataSource( rArguments ) );
688 : :
689 : : Reference< chart2::XDataInterpreter > xInterpreter(
690 [ # # ][ # # ]: 0 : m_xTemplate->getDataInterpreter());
691 [ # # ]: 0 : if( xInterpreter.is())
692 : : {
693 [ # # ][ # # ]: 0 : Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() );
694 [ # # ]: 0 : ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram );
695 : :
696 : : ::std::vector< Reference< XDataSeries > > aSeriesToReUse(
697 [ # # ]: 0 : DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
698 : : applyInterpretedData(
699 [ # # ]: 0 : xInterpreter->interpretDataSource(
700 : : xDataSource, rArguments,
701 : 0 : ContainerToSequence( aSeriesToReUse )),
702 : : aSeriesToReUse,
703 [ # # ][ # # ]: 0 : true /* bSetStyles */);
[ # # ][ # # ]
[ # # ]
704 : :
705 [ # # ]: 0 : ThreeDHelper::setScheme( xDiagram, e3DScheme );
706 [ # # ]: 0 : }
707 : : }
708 [ # # ]: 0 : catch( const uno::Exception & ex )
709 : : {
710 : : ASSERT_EXCEPTION( ex );
711 : 0 : return false;
712 : : }
713 : :
714 [ # # ]: 0 : return true;
715 : : }
716 : :
717 : 0 : OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
718 : : {
719 : 0 : return lcl_ConvertRole( rRoleString, true );
720 : : }
721 : :
722 : 0 : OUString DialogModel::GetRoleDataLabel()
723 : : {
724 [ # # ][ # # ]: 0 : return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS )));
[ # # ]
725 : : }
726 : :
727 : 0 : sal_Int32 DialogModel::GetRoleIndexForSorting( const ::rtl::OUString & rInternalRoleString )
728 : : {
729 [ # # ][ # # ]: 0 : static lcl_tRoleIndexMap aRoleIndexMap;
[ # # ][ # # ]
730 : :
731 [ # # ]: 0 : if( aRoleIndexMap.empty())
732 [ # # ]: 0 : lcl_createRoleIndexMap( aRoleIndexMap );
733 : :
734 [ # # ]: 0 : lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
735 [ # # ]: 0 : if( aIt != aRoleIndexMap.end())
736 : 0 : return aIt->second;
737 : :
738 : 0 : return 0;
739 : : }
740 : :
741 : : // private methods
742 : :
743 : 0 : void DialogModel::applyInterpretedData(
744 : : const InterpretedData & rNewData,
745 : : const ::std::vector< Reference< XDataSeries > > & rSeriesToReUse,
746 : : bool bSetStyles )
747 : : {
748 [ # # ]: 0 : if( ! m_xChartDocument.is())
749 : 0 : return;
750 : :
751 [ # # ]: 0 : m_aTimerTriggeredControllerLock.startTimer();
752 [ # # ][ # # ]: 0 : Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram());
753 [ # # ]: 0 : if( xDiagram.is())
754 : : {
755 : : // styles
756 [ # # ][ # # ]: 0 : if( bSetStyles && m_xTemplate.is() )
[ # # ]
757 : : {
758 : 0 : sal_Int32 nGroup = 0;
759 : 0 : sal_Int32 nSeriesCounter = 0;
760 : 0 : sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
761 : 0 : const sal_Int32 nOuterSize=rNewData.Series.getLength();
762 : :
763 [ # # ]: 0 : for(; nGroup < nOuterSize; ++nGroup)
764 : : {
765 [ # # ]: 0 : Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] );
766 : 0 : const sal_Int32 nSeriesInGroup = aSeries.getLength();
767 [ # # ]: 0 : for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
768 : : {
769 [ # # ][ # # ]: 0 : if( ::std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
[ # # ]
770 [ # # ]: 0 : == rSeriesToReUse.end())
771 : : {
772 [ # # ][ # # ]: 0 : Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY );
773 [ # # ]: 0 : if( xSeriesProp.is())
774 : : {
775 : : // @deprecated: correct default color should be found by view
776 : : // without setting it as hard attribute
777 [ # # ][ # # ]: 0 : Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
778 [ # # ]: 0 : if( xColorScheme.is())
779 [ # # ]: 0 : xSeriesProp->setPropertyValue(
780 [ # # ][ # # ]: 0 : C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nSeriesCounter )));
[ # # ][ # # ]
[ # # ]
781 : : }
782 [ # # ][ # # ]: 0 : m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
[ # # ]
783 : : }
784 : : }
785 [ # # ]: 0 : }
786 : : }
787 : :
788 : : // data series
789 [ # # ]: 0 : ::std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers());
790 : : ::std::vector< Sequence< Reference< XDataSeries > > > aNewSeries(
791 [ # # ]: 0 : SequenceToVector( rNewData.Series ));
792 : :
793 : : OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size());
794 : :
795 [ # # # # ]: 0 : ::std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin());
796 : 0 : ::std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin());
797 [ # # ][ # # ]: 0 : for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end();
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
798 : : ++aSrcIt, ++aDestIt )
799 : : {
800 : : try
801 : : {
802 : : OSL_ASSERT( (*aDestIt).is());
803 [ # # ][ # # ]: 0 : (*aDestIt)->setDataSeries( *aSrcIt );
804 : : }
805 [ # # ]: 0 : catch( const uno::Exception & ex )
806 : : {
807 : : ASSERT_EXCEPTION( ex );
808 : : }
809 : : }
810 : :
811 [ # # ]: 0 : DialogModel::setCategories(rNewData.Categories);
812 : 0 : }
813 : : }
814 : :
815 : 0 : sal_Int32 DialogModel::countSeries() const
816 : : {
817 [ # # ]: 0 : ::std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers());
818 [ # # ]: 0 : return ::std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
819 : : }
820 : :
821 [ + - ][ + - ]: 48 : } // namespace chart
822 : :
823 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|