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 : #include "DiagramHelper.hxx"
21 : #include "LegendHelper.hxx"
22 : #include "PropertyHelper.hxx"
23 : #include "macros.hxx"
24 : #include "DataSeriesHelper.hxx"
25 : #include "AxisHelper.hxx"
26 : #include "ContainerHelper.hxx"
27 : #include "ChartTypeHelper.hxx"
28 : #include "ChartModelHelper.hxx"
29 : #include "CommonConverters.hxx"
30 : #include "ExplicitCategoriesProvider.hxx"
31 : #include "servicenames_charttypes.hxx"
32 : #include "RelativePositionHelper.hxx"
33 : #include "ControllerLockGuard.hxx"
34 : #include "NumberFormatterWrapper.hxx"
35 :
36 : #include <com/sun/star/chart/MissingValueTreatment.hpp>
37 : #include <com/sun/star/chart/XChartDocument.hpp>
38 : #include <com/sun/star/chart/XDiagramPositioning.hpp>
39 : #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
40 : #include <com/sun/star/chart2/XTitled.hpp>
41 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
42 : #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
43 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
44 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
45 : #include <com/sun/star/chart2/InterpretedData.hpp>
46 : #include <com/sun/star/chart2/AxisType.hpp>
47 : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
48 : #include <com/sun/star/chart2/RelativePosition.hpp>
49 : #include <com/sun/star/chart2/RelativeSize.hpp>
50 :
51 : #include <com/sun/star/util/NumberFormat.hpp>
52 : #include <com/sun/star/util/XModifiable.hpp>
53 : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
54 :
55 : #include <unotools/saveopt.hxx>
56 : #include <rtl/math.hxx>
57 : #include <svl/zformat.hxx>
58 : // header for class Application
59 : #include <vcl/svapp.hxx>
60 :
61 : using namespace ::com::sun::star;
62 : using namespace ::com::sun::star::chart2;
63 : using namespace ::std;
64 :
65 : using ::com::sun::star::uno::Reference;
66 : using ::com::sun::star::uno::Sequence;
67 : using ::com::sun::star::uno::Any;
68 : using ::rtl::OUString;
69 : using ::com::sun::star::chart2::XAnyDescriptionAccess;
70 :
71 : namespace chart
72 : {
73 :
74 : DiagramHelper::tTemplateWithServiceName
75 0 : DiagramHelper::getTemplateForDiagram(
76 : const Reference< XDiagram > & xDiagram,
77 : const Reference< lang::XMultiServiceFactory > & xChartTypeManager,
78 : const OUString & rPreferredTemplateName )
79 : {
80 0 : DiagramHelper::tTemplateWithServiceName aResult;
81 :
82 0 : if( ! (xChartTypeManager.is() && xDiagram.is()))
83 : return aResult;
84 :
85 0 : Sequence< OUString > aServiceNames( xChartTypeManager->getAvailableServiceNames());
86 0 : const sal_Int32 nLength = aServiceNames.getLength();
87 :
88 0 : bool bHasPreferredTemplate = !rPreferredTemplateName.isEmpty();
89 0 : bool bTemplateFound = false;
90 :
91 0 : if( bHasPreferredTemplate )
92 : {
93 : Reference< XChartTypeTemplate > xTempl(
94 0 : xChartTypeManager->createInstance( rPreferredTemplateName ), uno::UNO_QUERY );
95 :
96 0 : if( xTempl.is() &&
97 0 : xTempl->matchesTemplate( xDiagram, sal_True ))
98 : {
99 0 : aResult.first = xTempl;
100 0 : aResult.second = rPreferredTemplateName;
101 0 : bTemplateFound = true;
102 0 : }
103 : }
104 :
105 0 : for( sal_Int32 i = 0; ! bTemplateFound && i < nLength; ++i )
106 : {
107 : try
108 : {
109 0 : if( ! bHasPreferredTemplate ||
110 0 : ! rPreferredTemplateName.equals( aServiceNames[ i ] ))
111 : {
112 : Reference< XChartTypeTemplate > xTempl(
113 0 : xChartTypeManager->createInstance( aServiceNames[ i ] ), uno::UNO_QUERY_THROW );
114 :
115 0 : if( xTempl->matchesTemplate( xDiagram, sal_True ))
116 : {
117 0 : aResult.first = xTempl;
118 0 : aResult.second = aServiceNames[ i ];
119 0 : bTemplateFound = true;
120 0 : }
121 : }
122 : }
123 0 : catch( const uno::Exception & ex )
124 : {
125 : ASSERT_EXCEPTION( ex );
126 : }
127 : }
128 :
129 0 : return aResult;
130 : }
131 :
132 41 : void DiagramHelper::setVertical(
133 : const Reference< XDiagram > & xDiagram,
134 : bool bVertical /* = true */ )
135 : {
136 : try
137 : {
138 41 : Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
139 41 : if( xCnt.is())
140 : {
141 : Sequence< Reference< XCoordinateSystem > > aCooSys(
142 41 : xCnt->getCoordinateSystems());
143 41 : uno::Any aValue;
144 41 : aValue <<= bVertical;
145 82 : for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
146 : {
147 41 : uno::Reference< XCoordinateSystem > xCooSys( aCooSys[i] );
148 41 : Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
149 41 : bool bChanged = false;
150 41 : if( xProp.is() )
151 : {
152 41 : bool bOldSwap = sal_False;
153 41 : if( !(xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bOldSwap)
154 : || bVertical != bOldSwap )
155 0 : bChanged = true;
156 :
157 41 : if( bChanged )
158 0 : xProp->setPropertyValue( C2U("SwapXAndYAxis"), aValue );
159 : }
160 41 : if( xCooSys.is() )
161 : {
162 41 : const sal_Int32 nDimensionCount( xCooSys->getDimension() );
163 41 : sal_Int32 nDimIndex = 0;
164 123 : for(nDimIndex=0; nDimIndex<nDimensionCount; ++nDimIndex)
165 : {
166 82 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex);
167 164 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
168 : {
169 82 : Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimIndex,nI ));
170 82 : if( xAxis.is() )
171 : {
172 : //adapt title rotation only when axis swapping has changed
173 82 : if( bChanged )
174 : {
175 0 : Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
176 0 : if( xTitled.is())
177 : {
178 0 : Reference< beans::XPropertySet > xTitleProps( xTitled->getTitleObject(), uno::UNO_QUERY );
179 0 : if( !xTitleProps.is() )
180 0 : continue;
181 0 : double fAngleDegree = 0.0;
182 0 : xTitleProps->getPropertyValue( C2U( "TextRotation" ) ) >>= fAngleDegree;
183 0 : if( !::rtl::math::approxEqual( fAngleDegree, 0.0 )
184 0 : && !::rtl::math::approxEqual( fAngleDegree, 90.0 ) )
185 0 : continue;
186 :
187 0 : double fNewAngleDegree = 0.0;
188 0 : if( !bVertical && nDimIndex == 1 )
189 0 : fNewAngleDegree = 90.0;
190 0 : else if( bVertical && nDimIndex == 0 )
191 0 : fNewAngleDegree = 90.0;
192 :
193 0 : xTitleProps->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree ));
194 0 : }
195 : }
196 : }
197 82 : }
198 : }
199 : }
200 82 : }
201 41 : }
202 : }
203 0 : catch( const uno::Exception & ex )
204 : {
205 : ASSERT_EXCEPTION( ex );
206 : }
207 41 : }
208 :
209 123 : bool DiagramHelper::getVertical( const uno::Reference< chart2::XDiagram > & xDiagram,
210 : bool& rbFound, bool& rbAmbiguous )
211 : {
212 123 : bool bValue = false;
213 123 : rbFound = false;
214 123 : rbAmbiguous = false;
215 :
216 123 : Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
217 123 : if( xCnt.is())
218 : {
219 : Sequence< Reference< XCoordinateSystem > > aCooSys(
220 123 : xCnt->getCoordinateSystems());
221 246 : for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
222 : {
223 123 : Reference< beans::XPropertySet > xProp( aCooSys[i], uno::UNO_QUERY );
224 123 : if( xProp.is())
225 : {
226 123 : bool bCurrent = false;
227 123 : if( xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bCurrent )
228 : {
229 123 : if( !rbFound )
230 : {
231 123 : bValue = bCurrent;
232 123 : rbFound = true;
233 : }
234 0 : else if( bCurrent != bValue )
235 : {
236 : // ambiguous -> choose always first found
237 0 : rbAmbiguous = true;
238 : }
239 : }
240 : }
241 246 : }
242 : }
243 123 : return bValue;
244 : }
245 :
246 0 : void DiagramHelper::setStackMode(
247 : const Reference< XDiagram > & xDiagram,
248 : StackMode eStackMode,
249 : bool bOnlyAtFirstChartType /* = true */
250 : )
251 : {
252 : try
253 : {
254 0 : if( eStackMode == StackMode_AMBIGUOUS )
255 : return;
256 :
257 0 : bool bValueFound = false;
258 0 : bool bIsAmbiguous = false;
259 0 : StackMode eOldStackMode = DiagramHelper::getStackMode( xDiagram, bValueFound, bIsAmbiguous );
260 :
261 0 : if( eStackMode == eOldStackMode && !bIsAmbiguous )
262 : return;
263 :
264 0 : StackingDirection eNewDirection = StackingDirection_NO_STACKING;
265 0 : if( eStackMode == StackMode_Y_STACKED || eStackMode == StackMode_Y_STACKED_PERCENT )
266 0 : eNewDirection = StackingDirection_Y_STACKING;
267 0 : else if( eStackMode == StackMode_Z_STACKED )
268 0 : eNewDirection = StackingDirection_Z_STACKING;
269 :
270 0 : uno::Any aNewDirection( uno::makeAny(eNewDirection) );
271 :
272 0 : sal_Bool bPercent = sal_False;
273 0 : if( eStackMode == StackMode_Y_STACKED_PERCENT )
274 0 : bPercent = sal_True;
275 :
276 : //iterate through all coordinate systems
277 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
278 0 : if( !xCooSysContainer.is() )
279 : return;
280 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
281 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
282 : {
283 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
284 : //set correct percent stacking
285 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(1);
286 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
287 : {
288 0 : Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
289 0 : if( xAxis.is())
290 : {
291 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
292 0 : if( (aScaleData.AxisType==AxisType::PERCENT) != bPercent )
293 : {
294 0 : if( bPercent )
295 0 : aScaleData.AxisType = AxisType::PERCENT;
296 : else
297 0 : aScaleData.AxisType = AxisType::REALNUMBER;
298 0 : xAxis->setScaleData( aScaleData );
299 0 : }
300 : }
301 0 : }
302 : //iterate through all chart types in the current coordinate system
303 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
304 0 : if( !xChartTypeContainer.is() )
305 0 : continue;
306 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
307 0 : sal_Int32 nMax = aChartTypeList.getLength();
308 0 : if( bOnlyAtFirstChartType
309 : && nMax >= 1 )
310 0 : nMax = 1;
311 0 : for( sal_Int32 nT = 0; nT < nMax; ++nT )
312 : {
313 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
314 :
315 : //iterate through all series in this chart type
316 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
317 : OSL_ASSERT( xDataSeriesContainer.is());
318 0 : if( !xDataSeriesContainer.is() )
319 0 : continue;
320 :
321 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
322 0 : for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
323 : {
324 0 : Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
325 0 : if(xProp.is())
326 0 : xProp->setPropertyValue( C2U( "StackingDirection" ), aNewDirection );
327 0 : }
328 0 : }
329 0 : }
330 : }
331 0 : catch( const uno::Exception & ex )
332 : {
333 : ASSERT_EXCEPTION( ex );
334 : }
335 : }
336 :
337 0 : StackMode DiagramHelper::getStackMode( const Reference< XDiagram > & xDiagram, bool& rbFound, bool& rbAmbiguous )
338 : {
339 0 : rbFound=false;
340 0 : rbAmbiguous=false;
341 :
342 0 : StackMode eGlobalStackMode = StackMode_NONE;
343 :
344 : //iterate through all coordinate systems
345 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
346 0 : if( !xCooSysContainer.is() )
347 0 : return eGlobalStackMode;
348 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
349 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
350 : {
351 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
352 :
353 : //iterate through all chart types in the current coordinate system
354 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
355 0 : if( !xChartTypeContainer.is() )
356 0 : continue;
357 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
358 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
359 : {
360 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
361 :
362 : StackMode eLocalStackMode = DiagramHelper::getStackModeFromChartType(
363 0 : xChartType, rbFound, rbAmbiguous, xCooSys );
364 :
365 0 : if( rbFound && eLocalStackMode != eGlobalStackMode && nT>0 )
366 : {
367 0 : rbAmbiguous = true;
368 0 : return eGlobalStackMode;
369 : }
370 :
371 0 : eGlobalStackMode = eLocalStackMode;
372 0 : }
373 0 : }
374 :
375 0 : return eGlobalStackMode;
376 : }
377 :
378 82 : StackMode DiagramHelper::getStackModeFromChartType(
379 : const Reference< XChartType > & xChartType,
380 : bool& rbFound, bool& rbAmbiguous,
381 : const Reference< XCoordinateSystem > & xCorrespondingCoordinateSystem )
382 : {
383 82 : StackMode eStackMode = StackMode_NONE;
384 82 : rbFound = false;
385 82 : rbAmbiguous = false;
386 :
387 : try
388 : {
389 82 : Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
390 82 : Sequence< Reference< chart2::XDataSeries > > aSeries( xDSCnt->getDataSeries());
391 :
392 82 : chart2::StackingDirection eCommonDirection = chart2::StackingDirection_NO_STACKING;
393 82 : bool bDirectionInitialized = false;
394 :
395 : // first series is irrelvant for stacking, start with second, unless
396 : // there is only one series
397 82 : const sal_Int32 nSeriesCount = aSeries.getLength();
398 82 : sal_Int32 i = (nSeriesCount == 1) ? 0: 1;
399 164 : for( ; i<nSeriesCount; ++i )
400 : {
401 82 : rbFound = true;
402 82 : Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY_THROW );
403 82 : chart2::StackingDirection eCurrentDirection = eCommonDirection;
404 : // property is not MAYBEVOID
405 82 : bool bSuccess = ( xProp->getPropertyValue( C2U("StackingDirection") ) >>= eCurrentDirection );
406 : OSL_ASSERT( bSuccess );
407 : (void)(bSuccess); // avoid warning in non-debug builds
408 82 : if( ! bDirectionInitialized )
409 : {
410 41 : eCommonDirection = eCurrentDirection;
411 41 : bDirectionInitialized = true;
412 : }
413 : else
414 : {
415 41 : if( eCommonDirection != eCurrentDirection )
416 : {
417 0 : rbAmbiguous = true;
418 : break;
419 : }
420 : }
421 82 : }
422 :
423 82 : if( rbFound )
424 : {
425 41 : if( eCommonDirection == chart2::StackingDirection_Z_STACKING )
426 0 : eStackMode = StackMode_Z_STACKED;
427 41 : else if( eCommonDirection == chart2::StackingDirection_Y_STACKING )
428 : {
429 0 : eStackMode = StackMode_Y_STACKED;
430 :
431 : // percent stacking
432 0 : if( xCorrespondingCoordinateSystem.is() )
433 : {
434 0 : if( 1 < xCorrespondingCoordinateSystem->getDimension() )
435 : {
436 0 : sal_Int32 nAxisIndex = 0;
437 0 : if( nSeriesCount )
438 0 : nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(aSeries[0]);
439 :
440 : Reference< chart2::XAxis > xAxis(
441 0 : xCorrespondingCoordinateSystem->getAxisByDimension( 1,nAxisIndex ));
442 0 : if( xAxis.is())
443 : {
444 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
445 0 : if( aScaleData.AxisType==chart2::AxisType::PERCENT )
446 0 : eStackMode = StackMode_Y_STACKED_PERCENT;
447 0 : }
448 : }
449 : }
450 : }
451 82 : }
452 : }
453 0 : catch( const uno::Exception & ex )
454 : {
455 : ASSERT_EXCEPTION( ex );
456 : }
457 :
458 82 : return eStackMode;
459 : }
460 :
461 246 : sal_Int32 DiagramHelper::getDimension( const Reference< XDiagram > & xDiagram )
462 : {
463 : // -1: not yet set
464 246 : sal_Int32 nResult = -1;
465 :
466 : try
467 : {
468 246 : Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
469 246 : if( xCooSysCnt.is() )
470 : {
471 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
472 246 : xCooSysCnt->getCoordinateSystems());
473 :
474 246 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
475 : {
476 246 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
477 246 : if(xCooSys.is())
478 : {
479 246 : nResult = xCooSys->getDimension();
480 : break;
481 : }
482 492 : }
483 246 : }
484 : }
485 0 : catch( const uno::Exception & ex )
486 : {
487 : ASSERT_EXCEPTION( ex );
488 : }
489 :
490 246 : return nResult;
491 : }
492 :
493 0 : void DiagramHelper::setDimension(
494 : const Reference< XDiagram > & xDiagram,
495 : sal_Int32 nNewDimensionCount )
496 : {
497 0 : if( ! xDiagram.is())
498 0 : return;
499 :
500 0 : if( DiagramHelper::getDimension( xDiagram ) == nNewDimensionCount )
501 0 : return;
502 :
503 : try
504 : {
505 0 : bool rbFound = false;
506 0 : bool rbAmbiguous = true;
507 0 : StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous );
508 0 : bool bIsSupportingOnlyDeepStackingFor3D=false;
509 :
510 : //change all coordinate systems:
511 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
512 0 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
513 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
514 : {
515 0 : Reference< XCoordinateSystem > xOldCooSys( aCooSysList[nCS], uno::UNO_QUERY );
516 0 : Reference< XCoordinateSystem > xNewCooSys;
517 :
518 0 : Reference< XChartTypeContainer > xChartTypeContainer( xOldCooSys, uno::UNO_QUERY );
519 0 : if( !xChartTypeContainer.is() )
520 0 : continue;
521 :
522 0 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
523 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
524 : {
525 0 : Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY );
526 0 : bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType );
527 0 : if(!xNewCooSys.is())
528 : {
529 0 : xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount );
530 : break;
531 : }
532 : //@todo make sure that all following charttypes are also capable of the new dimension
533 : //otherwise separate them in a different group
534 : //BM: might be done in replaceCoordinateSystem()
535 0 : }
536 :
537 : // replace the old coordinate system at all places where it was used
538 0 : DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys );
539 0 : }
540 :
541 : //correct stack mode if necessary
542 0 : if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D )
543 0 : DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED );
544 0 : else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED )
545 0 : DiagramHelper::setStackMode( xDiagram, StackMode_NONE );
546 : }
547 0 : catch( const uno::Exception & ex )
548 : {
549 : ASSERT_EXCEPTION( ex );
550 : }
551 : }
552 :
553 0 : void DiagramHelper::replaceCoordinateSystem(
554 : const Reference< XDiagram > & xDiagram,
555 : const Reference< XCoordinateSystem > & xCooSysToReplace,
556 : const Reference< XCoordinateSystem > & xReplacement )
557 : {
558 : OSL_ASSERT( xDiagram.is());
559 0 : if( ! xDiagram.is())
560 0 : return;
561 :
562 : // update the coordinate-system container
563 0 : Reference< XCoordinateSystemContainer > xCont( xDiagram, uno::UNO_QUERY );
564 0 : if( xCont.is())
565 : {
566 : try
567 : {
568 0 : Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
569 :
570 : // move chart types of xCooSysToReplace to xReplacement
571 0 : Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW );
572 0 : Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW );
573 0 : xCTCntReplacement->setChartTypes( xCTCntCooSys->getChartTypes());
574 :
575 0 : xCont->removeCoordinateSystem( xCooSysToReplace );
576 0 : xCont->addCoordinateSystem( xReplacement );
577 :
578 0 : if( xCategories.is() )
579 0 : DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram );
580 : }
581 0 : catch( const uno::Exception & ex )
582 : {
583 : ASSERT_EXCEPTION( ex );
584 : }
585 0 : }
586 : }
587 :
588 0 : bool DiagramHelper::isSeriesAttachedToMainAxis(
589 : const uno::Reference< chart2::XDataSeries >& xDataSeries )
590 : {
591 0 : sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
592 0 : return (nAxisIndex==0);
593 : }
594 :
595 0 : bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis
596 : , const uno::Reference< chart2::XDataSeries >& xDataSeries
597 : , const uno::Reference< chart2::XDiagram >& xDiagram
598 : , const uno::Reference< uno::XComponentContext > & xContext
599 : , bool bAdaptAxes )
600 : {
601 0 : bool bChanged = false;
602 :
603 : //set property at axis
604 0 : Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
605 0 : if( !xProp.is() )
606 0 : return bChanged;
607 :
608 0 : sal_Int32 nNewAxisIndex = bAttachToMainAxis ? 0 : 1;
609 0 : sal_Int32 nOldAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
610 0 : uno::Reference< chart2::XAxis > xOldAxis( DiagramHelper::getAttachedAxis( xDataSeries, xDiagram ) );
611 :
612 0 : if( nOldAxisIndex != nNewAxisIndex )
613 : {
614 : try
615 : {
616 0 : xProp->setPropertyValue( C2U("AttachedAxisIndex"), uno::makeAny( nNewAxisIndex ) );
617 0 : bChanged = true;
618 : }
619 0 : catch( const uno::Exception & ex )
620 : {
621 : ASSERT_EXCEPTION( ex );
622 : }
623 : }
624 :
625 0 : if( bChanged && xDiagram.is() )
626 : {
627 0 : uno::Reference< XAxis > xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis, xDiagram ) );
628 0 : if(!xAxis.is()) //create an axis if necessary
629 0 : xAxis = AxisHelper::createAxis( 1, bAttachToMainAxis, xDiagram, xContext );
630 0 : if( bAdaptAxes )
631 : {
632 0 : AxisHelper::makeAxisVisible( xAxis );
633 0 : AxisHelper::hideAxisIfNoDataIsAttached( xOldAxis, xDiagram );
634 0 : }
635 : }
636 :
637 0 : return bChanged;
638 : }
639 :
640 0 : uno::Reference< XAxis > DiagramHelper::getAttachedAxis(
641 : const uno::Reference< XDataSeries >& xSeries,
642 : const uno::Reference< XDiagram >& xDiagram )
643 : {
644 0 : return AxisHelper::getAxis( 1, DiagramHelper::isSeriesAttachedToMainAxis( xSeries ), xDiagram );
645 : }
646 :
647 0 : uno::Reference< XChartType > DiagramHelper::getChartTypeOfSeries(
648 : const uno::Reference< chart2::XDiagram >& xDiagram
649 : , const uno::Reference< XDataSeries >& xGivenDataSeries )
650 : {
651 0 : if( !xGivenDataSeries.is() )
652 0 : return 0;
653 0 : if(!xDiagram.is())
654 0 : return 0;
655 :
656 : //iterate through the model to find the given xSeries
657 : //the found parent indicates the charttype
658 :
659 : //iterate through all coordinate systems
660 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
661 0 : if( !xCooSysContainer.is())
662 0 : return 0;
663 :
664 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
665 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
666 : {
667 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
668 :
669 : //iterate through all chart types in the current coordinate system
670 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
671 : OSL_ASSERT( xChartTypeContainer.is());
672 0 : if( !xChartTypeContainer.is() )
673 0 : continue;
674 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
675 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
676 : {
677 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
678 :
679 : //iterate through all series in this chart type
680 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
681 : OSL_ASSERT( xDataSeriesContainer.is());
682 0 : if( !xDataSeriesContainer.is() )
683 0 : continue;
684 :
685 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
686 0 : for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
687 : {
688 0 : if( xGivenDataSeries==aSeriesList[nS] )
689 0 : return xChartType;
690 : }
691 0 : }
692 0 : }
693 0 : return 0;
694 : }
695 :
696 : ::std::vector< Reference< XDataSeries > >
697 204 : DiagramHelper::getDataSeriesFromDiagram(
698 : const Reference< XDiagram > & xDiagram )
699 : {
700 204 : ::std::vector< Reference< XDataSeries > > aResult;
701 :
702 : try
703 : {
704 : Reference< XCoordinateSystemContainer > xCooSysCnt(
705 204 : xDiagram, uno::UNO_QUERY_THROW );
706 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
707 204 : xCooSysCnt->getCoordinateSystems());
708 408 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
709 : {
710 204 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
711 204 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
712 408 : for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
713 : {
714 204 : Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
715 204 : Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
716 204 : ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
717 408 : ::std::back_inserter( aResult ));
718 204 : }
719 408 : }
720 : }
721 0 : catch( const uno::Exception & ex )
722 : {
723 : ASSERT_EXCEPTION( ex );
724 : }
725 :
726 204 : return aResult;
727 : }
728 :
729 : Sequence< Sequence< Reference< XDataSeries > > >
730 41 : DiagramHelper::getDataSeriesGroups( const Reference< XDiagram > & xDiagram )
731 : {
732 41 : vector< Sequence< Reference< XDataSeries > > > aResult;
733 :
734 : //iterate through all coordinate systems
735 41 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
736 41 : if( xCooSysContainer.is() )
737 : {
738 41 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
739 82 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
740 : {
741 : //iterate through all chart types in the current coordinate system
742 41 : Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
743 41 : if( !xChartTypeContainer.is() )
744 0 : continue;
745 41 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
746 82 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
747 : {
748 41 : Reference< XDataSeriesContainer > xDataSeriesContainer( aChartTypeList[nT], uno::UNO_QUERY );
749 41 : if( !xDataSeriesContainer.is() )
750 0 : continue;
751 41 : aResult.push_back( xDataSeriesContainer->getDataSeries() );
752 41 : }
753 82 : }
754 : }
755 41 : return ContainerHelper::ContainerToSequence( aResult );
756 : }
757 :
758 : Reference< XChartType >
759 246 : DiagramHelper::getChartTypeByIndex( const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
760 : {
761 246 : Reference< XChartType > xChartType;
762 :
763 : //iterate through all coordinate systems
764 246 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
765 246 : if( ! xCooSysContainer.is())
766 : return xChartType;
767 :
768 246 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
769 246 : sal_Int32 nTypesSoFar = 0;
770 246 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
771 : {
772 246 : Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
773 246 : if( !xChartTypeContainer.is() )
774 0 : continue;
775 246 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
776 246 : if( nIndex >= 0 && nIndex < (nTypesSoFar + aChartTypeList.getLength()) )
777 : {
778 246 : xChartType.set( aChartTypeList[nIndex - nTypesSoFar] );
779 : break;
780 : }
781 0 : nTypesSoFar += aChartTypeList.getLength();
782 246 : }
783 :
784 246 : return xChartType;
785 : }
786 :
787 : namespace
788 : {
789 :
790 81 : std::vector< Reference< XAxis > > lcl_getAxisHoldingCategoriesFromDiagram(
791 : const Reference< XDiagram > & xDiagram )
792 : {
793 81 : std::vector< Reference< XAxis > > aRet;
794 :
795 81 : Reference< XAxis > xResult;
796 : // return first x-axis as fall-back
797 81 : Reference< XAxis > xFallBack;
798 : try
799 : {
800 : Reference< XCoordinateSystemContainer > xCooSysCnt(
801 81 : xDiagram, uno::UNO_QUERY_THROW );
802 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
803 81 : xCooSysCnt->getCoordinateSystems());
804 162 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
805 : {
806 81 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
807 : OSL_ASSERT( xCooSys.is());
808 324 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
809 : {
810 162 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
811 324 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
812 : {
813 162 : Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
814 : OSL_ASSERT( xAxis.is());
815 162 : if( xAxis.is())
816 : {
817 162 : ScaleData aScaleData = xAxis->getScaleData();
818 162 : if( aScaleData.Categories.is() || (aScaleData.AxisType == AxisType::CATEGORY) )
819 : {
820 81 : aRet.push_back(xAxis);
821 : }
822 162 : if( (nN == 0) && !xFallBack.is())
823 81 : xFallBack.set( xAxis );
824 : }
825 162 : }
826 : }
827 162 : }
828 : }
829 0 : catch( const uno::Exception & ex )
830 : {
831 : ASSERT_EXCEPTION( ex );
832 : }
833 :
834 81 : if( aRet.empty() )
835 0 : aRet.push_back(xFallBack);
836 :
837 81 : return aRet;
838 : }
839 :
840 : } // anonymous namespace
841 :
842 0 : bool DiagramHelper::isCategoryDiagram(
843 : const Reference< XDiagram >& xDiagram )
844 : {
845 : try
846 : {
847 : Reference< XCoordinateSystemContainer > xCooSysCnt(
848 0 : xDiagram, uno::UNO_QUERY_THROW );
849 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
850 0 : xCooSysCnt->getCoordinateSystems());
851 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
852 : {
853 0 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
854 : OSL_ASSERT( xCooSys.is());
855 0 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
856 : {
857 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
858 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
859 : {
860 0 : Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
861 : OSL_ASSERT( xAxis.is());
862 0 : if( xAxis.is())
863 : {
864 0 : ScaleData aScaleData = xAxis->getScaleData();
865 0 : if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE )
866 0 : return true;
867 : }
868 0 : }
869 : }
870 0 : }
871 : }
872 0 : catch( const uno::Exception & ex )
873 : {
874 : ASSERT_EXCEPTION( ex );
875 : }
876 :
877 0 : return false;
878 : }
879 :
880 0 : void DiagramHelper::setCategoriesToDiagram(
881 : const Reference< chart2::data::XLabeledDataSequence >& xCategories,
882 : const Reference< XDiagram >& xDiagram,
883 : bool bSetAxisType /* = false */,
884 : bool bCategoryAxis /* = true */ )
885 : {
886 : std::vector< Reference< chart2::XAxis > > aCatAxes(
887 0 : lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
888 :
889 0 : std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
890 0 : std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
891 :
892 0 : for( aIt = aCatAxes.begin(); aIt != aEnd; ++aIt )
893 : {
894 0 : Reference< chart2::XAxis > xCatAxis(*aIt);
895 0 : if( xCatAxis.is())
896 : {
897 0 : ScaleData aScaleData( xCatAxis->getScaleData());
898 0 : aScaleData.Categories = xCategories;
899 0 : if( bSetAxisType )
900 : {
901 0 : if( bCategoryAxis )
902 0 : aScaleData.AxisType = AxisType::CATEGORY;
903 0 : else if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE )
904 0 : aScaleData.AxisType = AxisType::REALNUMBER;
905 : }
906 0 : xCatAxis->setScaleData( aScaleData );
907 : }
908 0 : }
909 0 : }
910 :
911 : Reference< data::XLabeledDataSequence >
912 81 : DiagramHelper::getCategoriesFromDiagram(
913 : const Reference< XDiagram > & xDiagram )
914 : {
915 81 : Reference< data::XLabeledDataSequence > xResult;
916 :
917 : try
918 : {
919 : std::vector< Reference< chart2::XAxis > > aCatAxes(
920 81 : lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
921 81 : std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
922 81 : std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
923 : //search for first categories
924 81 : if( aIt != aEnd )
925 : {
926 81 : Reference< chart2::XAxis > xCatAxis(*aIt);
927 81 : if( xCatAxis.is())
928 : {
929 81 : ScaleData aScaleData( xCatAxis->getScaleData());
930 81 : if( aScaleData.Categories.is() )
931 : {
932 62 : xResult.set( aScaleData.Categories );
933 62 : uno::Reference<beans::XPropertySet> xProp(aScaleData.Categories->getValues(), uno::UNO_QUERY );
934 62 : if( xProp.is() )
935 : {
936 : try
937 : {
938 62 : xProp->setPropertyValue( C2U( "Role" ), uno::makeAny( C2U("categories") ) );
939 : }
940 0 : catch( const uno::Exception & ex )
941 : {
942 : ASSERT_EXCEPTION( ex );
943 : }
944 62 : }
945 81 : }
946 81 : }
947 81 : }
948 : }
949 0 : catch( const uno::Exception & ex )
950 : {
951 : ASSERT_EXCEPTION( ex );
952 : }
953 :
954 81 : return xResult;
955 : }
956 :
957 0 : void lcl_generateAutomaticCategoriesFromChartType(
958 : Sequence< rtl::OUString >& rRet,
959 : const Reference< XChartType >& xChartType )
960 : {
961 0 : if(!xChartType.is())
962 : return;
963 0 : rtl::OUString aMainSeq( xChartType->getRoleOfSequenceForSeriesLabel() );
964 0 : Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY );
965 0 : if( xSeriesCnt.is() )
966 : {
967 0 : Sequence< Reference< XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
968 0 : for( sal_Int32 nS = 0; nS < aSeriesSeq.getLength(); nS++ )
969 : {
970 0 : Reference< data::XDataSource > xDataSource( aSeriesSeq[nS], uno::UNO_QUERY );
971 0 : if( !xDataSource.is() )
972 0 : continue;
973 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
974 0 : ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aMainSeq ));
975 0 : if( !xLabeledSeq.is() )
976 0 : continue;
977 0 : Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
978 0 : if( !xValueSeq.is() )
979 0 : continue;
980 0 : rRet = xValueSeq->generateLabel( chart2::data::LabelOrigin_LONG_SIDE );
981 0 : if( rRet.getLength() )
982 : return;
983 0 : }
984 0 : }
985 : }
986 :
987 0 : Sequence< rtl::OUString > DiagramHelper::generateAutomaticCategoriesFromCooSys( const Reference< XCoordinateSystem > & xCooSys )
988 : {
989 0 : Sequence< rtl::OUString > aRet;
990 :
991 0 : Reference< XChartTypeContainer > xTypeCntr( xCooSys, uno::UNO_QUERY );
992 0 : if( xTypeCntr.is() )
993 : {
994 0 : Sequence< Reference< XChartType > > aChartTypes( xTypeCntr->getChartTypes() );
995 0 : for( sal_Int32 nN=0; nN<aChartTypes.getLength(); nN++ )
996 : {
997 0 : lcl_generateAutomaticCategoriesFromChartType( aRet, aChartTypes[nN] );
998 0 : if( aRet.getLength() )
999 : return aRet;
1000 0 : }
1001 : }
1002 0 : return aRet;
1003 : }
1004 :
1005 0 : Sequence< rtl::OUString > DiagramHelper::getExplicitSimpleCategories(
1006 : const Reference< XChartDocument >& xChartDoc )
1007 : {
1008 0 : Sequence< rtl::OUString > aRet;
1009 0 : uno::Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
1010 0 : if(xChartModel.is())
1011 : {
1012 0 : uno::Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
1013 0 : ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, xChartModel );
1014 0 : aRet = aExplicitCategoriesProvider.getSimpleCategories();
1015 : }
1016 0 : return aRet;
1017 : }
1018 :
1019 : namespace
1020 : {
1021 0 : void lcl_switchToDateCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis )
1022 : {
1023 0 : if( !xAxis.is() )
1024 : return;
1025 0 : if( !xChartDoc.is() )
1026 : return;
1027 :
1028 0 : ScaleData aScale( xAxis->getScaleData() );
1029 0 : if( xChartDoc->hasInternalDataProvider() )
1030 : {
1031 : //remove all content the is not of type double and remove multiple level
1032 0 : Reference< XAnyDescriptionAccess > xDataAccess( xChartDoc->getDataProvider(), uno::UNO_QUERY );
1033 0 : if( xDataAccess.is() )
1034 : {
1035 0 : Sequence< Sequence< Any > > aAnyCategories( xDataAccess->getAnyRowDescriptions() );
1036 0 : double fTest = 0.0;
1037 0 : double fNan = 0.0;
1038 0 : ::rtl::math::setNan( & fNan );
1039 0 : sal_Int32 nN = aAnyCategories.getLength();
1040 0 : for( ; nN--; )
1041 : {
1042 0 : Sequence< Any >& rCat = aAnyCategories[nN];
1043 0 : if( rCat.getLength() > 1 )
1044 0 : rCat.realloc(1);
1045 0 : if( rCat.getLength() == 1 )
1046 : {
1047 0 : Any& rAny = rCat[0];
1048 0 : if( !(rAny>>=fTest) )
1049 : {
1050 0 : rAny = uno::makeAny(fNan);
1051 : }
1052 : }
1053 : }
1054 0 : xDataAccess->setAnyRowDescriptions( aAnyCategories );
1055 : }
1056 : //check the numberformat at the axis
1057 0 : Reference< beans::XPropertySet > xAxisProps( xAxis, uno::UNO_QUERY );
1058 0 : Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartDoc, uno::UNO_QUERY );
1059 0 : if( xAxisProps.is() && xNumberFormatsSupplier.is() )
1060 : {
1061 0 : sal_Int32 nNumberFormat = -1;
1062 0 : xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nNumberFormat;
1063 :
1064 0 : Reference< util::XNumberFormats > xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
1065 0 : if( xNumberFormats.is() )
1066 : {
1067 0 : Reference< beans::XPropertySet > xKeyProps;
1068 : try
1069 : {
1070 0 : xKeyProps = xNumberFormats->getByKey( nNumberFormat );
1071 : }
1072 0 : catch( const uno::Exception & ex )
1073 : {
1074 : ASSERT_EXCEPTION( ex );
1075 : }
1076 0 : sal_Int32 nType = util::NumberFormat::UNDEFINED;
1077 0 : if( xKeyProps.is() )
1078 0 : xKeyProps->getPropertyValue( C2U("Type") ) >>= nType;
1079 0 : if( !( nType & util::NumberFormat::DATE ) )
1080 : {
1081 : //set a date format to the axis
1082 0 : sal_Bool bCreate = sal_True;
1083 0 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1084 0 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::DATE, rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1085 0 : if( aKeySeq.getLength() )
1086 : {
1087 0 : xAxisProps->setPropertyValue( C2U("NumberFormat"), uno::makeAny(aKeySeq[0]) );
1088 0 : }
1089 0 : }
1090 0 : }
1091 0 : }
1092 : }
1093 0 : if( aScale.AxisType != chart2::AxisType::DATE )
1094 0 : AxisHelper::removeExplicitScaling( aScale );
1095 0 : aScale.AxisType = chart2::AxisType::DATE;
1096 0 : xAxis->setScaleData( aScale );
1097 : }
1098 :
1099 0 : void lcl_switchToTextCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis )
1100 : {
1101 0 : if( !xAxis.is() )
1102 : return;
1103 0 : if( !xChartDoc.is() )
1104 : return;
1105 0 : ScaleData aScale( xAxis->getScaleData() );
1106 0 : if( aScale.AxisType != chart2::AxisType::CATEGORY )
1107 0 : AxisHelper::removeExplicitScaling( aScale );
1108 : //todo migrate dates to text?
1109 0 : aScale.AxisType = chart2::AxisType::CATEGORY;
1110 0 : aScale.AutoDateAxis = false;
1111 0 : xAxis->setScaleData( aScale );
1112 : }
1113 :
1114 : }
1115 :
1116 0 : void DiagramHelper::switchToDateCategories( const Reference< XChartDocument >& xChartDoc )
1117 : {
1118 0 : Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
1119 0 : if(xChartModel.is())
1120 : {
1121 0 : ControllerLockGuard aCtrlLockGuard( xChartModel );
1122 :
1123 0 : Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
1124 0 : if( xCooSys.is() )
1125 : {
1126 0 : Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) );
1127 0 : lcl_switchToDateCategories( xChartDoc, xAxis );
1128 0 : }
1129 0 : }
1130 0 : }
1131 :
1132 0 : void DiagramHelper::switchToTextCategories( const Reference< XChartDocument >& xChartDoc )
1133 : {
1134 0 : Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
1135 0 : if(xChartModel.is())
1136 : {
1137 0 : ControllerLockGuard aCtrlLockGuard( xChartModel );
1138 :
1139 0 : Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
1140 0 : if( xCooSys.is() )
1141 : {
1142 0 : Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) );
1143 0 : lcl_switchToTextCategories( xChartDoc, xAxis );
1144 0 : }
1145 0 : }
1146 0 : }
1147 :
1148 123 : bool DiagramHelper::isSupportingDateAxis( const Reference< chart2::XDiagram >& xDiagram )
1149 : {
1150 : return ::chart::ChartTypeHelper::isSupportingDateAxis(
1151 123 : DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), DiagramHelper::getDimension( xDiagram ), 0 );
1152 : }
1153 :
1154 0 : bool DiagramHelper::isDateNumberFormat( sal_Int32 nNumberFormat, const Reference< util::XNumberFormats >& xNumberFormats )
1155 : {
1156 0 : bool bIsDate = false;
1157 0 : if( !xNumberFormats.is() )
1158 0 : return bIsDate;
1159 :
1160 0 : Reference< beans::XPropertySet > xKeyProps = xNumberFormats->getByKey( nNumberFormat );
1161 0 : if( xKeyProps.is() )
1162 : {
1163 0 : sal_Int32 nType = util::NumberFormat::UNDEFINED;
1164 0 : xKeyProps->getPropertyValue( C2U("Type") ) >>= nType;
1165 0 : bIsDate = nType & util::NumberFormat::DATE;
1166 : }
1167 0 : return bIsDate;
1168 : }
1169 :
1170 123 : sal_Int32 DiagramHelper::getDateNumberFormat( const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1171 : {
1172 123 : sal_Int32 nRet=-1;
1173 123 : Reference< util::XNumberFormats > xNumberFormats( xNumberFormatsSupplier->getNumberFormats() );
1174 123 : if( xNumberFormats.is() )
1175 : {
1176 123 : sal_Bool bCreate = sal_True;
1177 123 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1178 123 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::DATE,
1179 123 : rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1180 123 : if( aKeySeq.getLength() )
1181 : {
1182 123 : nRet = aKeySeq[0];
1183 123 : }
1184 : }
1185 :
1186 : //try to get a date format with full year display
1187 123 : NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
1188 123 : SvNumberFormatter* pNumFormatter = aNumberFormatterWrapper.getSvNumberFormatter();
1189 123 : if( pNumFormatter )
1190 : {
1191 123 : const SvNumberformat* pFormat = pNumFormatter->GetEntry( nRet );
1192 123 : if( pFormat )
1193 123 : nRet = pNumFormatter->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, pFormat->GetLanguage() );
1194 : }
1195 123 : return nRet;
1196 : }
1197 :
1198 0 : sal_Int32 DiagramHelper::getPercentNumberFormat( const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1199 : {
1200 0 : sal_Int32 nRet=-1;
1201 0 : Reference< util::XNumberFormats > xNumberFormats( xNumberFormatsSupplier->getNumberFormats() );
1202 0 : if( xNumberFormats.is() )
1203 : {
1204 0 : sal_Bool bCreate = sal_True;
1205 0 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1206 0 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::PERCENT,
1207 0 : rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1208 0 : if( aKeySeq.getLength() )
1209 : {
1210 0 : nRet = aKeySeq[0];
1211 0 : }
1212 : }
1213 0 : return nRet;
1214 : }
1215 :
1216 : Sequence< Reference< XChartType > >
1217 41 : DiagramHelper::getChartTypesFromDiagram(
1218 : const Reference< XDiagram > & xDiagram )
1219 : {
1220 41 : ::std::vector< Reference< XChartType > > aResult;
1221 :
1222 41 : if(xDiagram.is())
1223 : try
1224 : {
1225 : Reference< XCoordinateSystemContainer > xCooSysCnt(
1226 41 : xDiagram, uno::UNO_QUERY_THROW );
1227 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
1228 41 : xCooSysCnt->getCoordinateSystems());
1229 82 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
1230 : {
1231 41 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
1232 41 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
1233 41 : ::std::copy( aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
1234 82 : ::std::back_inserter( aResult ));
1235 82 : }
1236 : }
1237 0 : catch( const uno::Exception & ex )
1238 : {
1239 : ASSERT_EXCEPTION( ex );
1240 : }
1241 :
1242 41 : return ContainerHelper::ContainerToSequence( aResult );
1243 : }
1244 :
1245 0 : bool DiagramHelper::areChartTypesCompatible( const Reference< ::chart2::XChartType >& xFirstType,
1246 : const Reference< ::chart2::XChartType >& xSecondType )
1247 : {
1248 0 : if( !xFirstType.is() || !xSecondType.is() )
1249 0 : return false;
1250 :
1251 0 : ::std::vector< ::rtl::OUString > aFirstRoles( ContainerHelper::SequenceToVector( xFirstType->getSupportedMandatoryRoles() ) );
1252 0 : ::std::vector< ::rtl::OUString > aSecondRoles( ContainerHelper::SequenceToVector( xSecondType->getSupportedMandatoryRoles() ) );
1253 0 : ::std::sort( aFirstRoles.begin(), aFirstRoles.end() );
1254 0 : ::std::sort( aSecondRoles.begin(), aSecondRoles.end() );
1255 0 : return ( aFirstRoles == aSecondRoles );
1256 : }
1257 :
1258 : namespace
1259 : {
1260 : /**
1261 : * This method implements the logic of checking if a series can be moved
1262 : * forward/backward. Depending on the "bDoMove" parameter the series will
1263 : * be moved (bDoMove = true) or the function just will test if the
1264 : * series can be moved without doing the move (bDoMove = false).
1265 : *
1266 : * @param xDiagram
1267 : * Reference to the diagram that contains the series.
1268 : *
1269 : * @param xGivenDataSeries
1270 : * Reference to the series that should moved or tested for moving.
1271 : *
1272 : * @param bForward
1273 : * Direction in which the series should be moved or tested for moving.
1274 : *
1275 : * @param bDoMove
1276 : * Should this function really move the series (true) or just test if it is
1277 : * possible (false).
1278 : *
1279 : *
1280 : * @returns
1281 : * in case of bDoMove == true
1282 : * - True : if the move was done
1283 : * - False : the move failed
1284 : * in case of bDoMove == false
1285 : * - True : the series can be moved
1286 : * - False : the series can not be moved
1287 : *
1288 : */
1289 :
1290 0 : bool lcl_moveSeriesOrCheckIfMoveIsAllowed(
1291 : const Reference< XDiagram >& xDiagram,
1292 : const Reference< XDataSeries >& xGivenDataSeries,
1293 : bool bForward,
1294 : bool bDoMove )
1295 : {
1296 0 : bool bMovedOrMoveAllowed = false;
1297 :
1298 : try
1299 : {
1300 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
1301 :
1302 : //find position of series.
1303 0 : bool bFound = false;
1304 :
1305 0 : if( xGivenDataSeries.is() && xCooSysContainer.is() )
1306 : {
1307 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
1308 :
1309 0 : for( sal_Int32 nCS = 0; !bFound && nCS < aCooSysList.getLength(); ++nCS )
1310 : {
1311 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
1312 :
1313 : //iterate through all chart types in the current coordinate system
1314 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
1315 : OSL_ASSERT( xChartTypeContainer.is());
1316 0 : if( !xChartTypeContainer.is() )
1317 0 : continue;
1318 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
1319 0 : uno::Reference< XChartType > xFormerChartType;
1320 :
1321 0 : for( sal_Int32 nT = 0; !bFound && nT < aChartTypeList.getLength(); ++nT )
1322 : {
1323 0 : uno::Reference< XChartType > xCurrentChartType( aChartTypeList[nT] );
1324 :
1325 : //iterate through all series in this chart type
1326 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xCurrentChartType, uno::UNO_QUERY );
1327 : OSL_ASSERT( xDataSeriesContainer.is());
1328 0 : if( !xDataSeriesContainer.is() )
1329 0 : continue;
1330 :
1331 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
1332 :
1333 0 : for( sal_Int32 nS = 0; !bFound && nS < aSeriesList.getLength(); ++nS )
1334 : {
1335 :
1336 : // We found the series we are interrested in !
1337 0 : if( xGivenDataSeries==aSeriesList[nS] )
1338 : {
1339 0 : sal_Int32 nOldSeriesIndex = nS;
1340 0 : bFound = true;
1341 :
1342 : try
1343 : {
1344 0 : sal_Int32 nNewSeriesIndex = nS;
1345 :
1346 0 : if( bForward )
1347 0 : nNewSeriesIndex--;
1348 : else
1349 0 : nNewSeriesIndex++;
1350 :
1351 :
1352 0 : if( nNewSeriesIndex >= 0 && nNewSeriesIndex < aSeriesList.getLength() )
1353 : {
1354 : //move series in the same charttype
1355 0 : bMovedOrMoveAllowed = true;
1356 0 : if( bDoMove )
1357 : {
1358 0 : aSeriesList[ nOldSeriesIndex ] = aSeriesList[ nNewSeriesIndex ];
1359 0 : aSeriesList[ nNewSeriesIndex ] = xGivenDataSeries;
1360 0 : xDataSeriesContainer->setDataSeries( aSeriesList );
1361 : }
1362 : }
1363 0 : else if( nNewSeriesIndex<0 )
1364 : {
1365 : //exchange series with former charttype
1366 0 : if( xFormerChartType.is() && DiagramHelper::areChartTypesCompatible( xFormerChartType, xCurrentChartType ) )
1367 : {
1368 0 : bMovedOrMoveAllowed = true;
1369 0 : if( bDoMove )
1370 : {
1371 0 : uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xFormerChartType, uno::UNO_QUERY );
1372 0 : if( xOtherDataSeriesContainer.is() )
1373 : {
1374 0 : uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1375 0 : sal_Int32 nOtherSeriesIndex = aOtherSeriesList.getLength()-1;
1376 0 : if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1377 : {
1378 0 : uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1379 0 : aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1380 0 : xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1381 :
1382 0 : aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1383 0 : xDataSeriesContainer->setDataSeries(aSeriesList);
1384 0 : }
1385 0 : }
1386 : }
1387 : }
1388 : }
1389 0 : else if( nT+1 < aChartTypeList.getLength() )
1390 : {
1391 : //exchange series with next charttype
1392 0 : uno::Reference< XChartType > xOtherChartType( aChartTypeList[nT+1] );
1393 0 : if( xOtherChartType.is() && DiagramHelper::areChartTypesCompatible( xOtherChartType, xCurrentChartType ) )
1394 : {
1395 0 : bMovedOrMoveAllowed = true;
1396 0 : if( bDoMove )
1397 : {
1398 0 : uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xOtherChartType, uno::UNO_QUERY );
1399 0 : if( xOtherDataSeriesContainer.is() )
1400 : {
1401 0 : uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1402 0 : sal_Int32 nOtherSeriesIndex = 0;
1403 0 : if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1404 : {
1405 0 : uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1406 0 : aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1407 0 : xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1408 :
1409 0 : aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1410 0 : xDataSeriesContainer->setDataSeries(aSeriesList);
1411 0 : }
1412 0 : }
1413 : }
1414 0 : }
1415 : }
1416 : }
1417 0 : catch( const util::CloseVetoException& )
1418 : {
1419 : }
1420 0 : catch( const uno::RuntimeException& )
1421 : {
1422 : }
1423 : }
1424 : }
1425 0 : xFormerChartType = xCurrentChartType;
1426 0 : }
1427 0 : }
1428 0 : }
1429 : }
1430 0 : catch( const util::CloseVetoException& )
1431 : {
1432 : }
1433 0 : catch( const uno::RuntimeException& )
1434 : {
1435 : }
1436 0 : return bMovedOrMoveAllowed;
1437 : }
1438 : } // anonymous namespace
1439 :
1440 :
1441 0 : bool DiagramHelper::isSeriesMoveable(
1442 : const Reference< XDiagram >& xDiagram,
1443 : const Reference< XDataSeries >& xGivenDataSeries,
1444 : bool bForward )
1445 : {
1446 0 : bool bIsMoveable = false;
1447 0 : const bool bDoMove = false;
1448 :
1449 : bIsMoveable = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1450 0 : xDiagram, xGivenDataSeries, bForward, bDoMove );
1451 :
1452 0 : return bIsMoveable;
1453 : }
1454 :
1455 :
1456 0 : bool DiagramHelper::moveSeries( const Reference< XDiagram >& xDiagram, const Reference< XDataSeries >& xGivenDataSeries, bool bForward )
1457 : {
1458 0 : bool bMoved = false;
1459 0 : const bool bDoMove = true;
1460 :
1461 : bMoved = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1462 0 : xDiagram, xGivenDataSeries, bForward, bDoMove );
1463 :
1464 0 : return bMoved;
1465 : }
1466 :
1467 41 : bool DiagramHelper::isSupportingFloorAndWall( const Reference<
1468 : chart2::XDiagram >& xDiagram )
1469 : {
1470 : //pies and donuts currently do not support this because of wrong files from older versions
1471 : //todo: allow this in future again, if fileversion are available for ole objects (metastream)
1472 : //thus the wrong bottom can be removed on import
1473 :
1474 : Sequence< Reference< chart2::XChartType > > aTypes(
1475 41 : ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ) );
1476 82 : for( sal_Int32 nN = 0; nN < aTypes.getLength(); nN++ )
1477 : {
1478 41 : Reference< chart2::XChartType > xType( aTypes[nN] );
1479 41 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1480 0 : return false;
1481 41 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
1482 0 : return false;
1483 41 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
1484 0 : return false;
1485 41 : }
1486 41 : return true;
1487 : }
1488 :
1489 41 : bool DiagramHelper::isPieOrDonutChart( const ::com::sun::star::uno::Reference<
1490 : ::com::sun::star::chart2::XDiagram >& xDiagram )
1491 : {
1492 : uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex(
1493 41 : xDiagram, 0 ) );
1494 :
1495 41 : if( xChartType .is() )
1496 : {
1497 41 : rtl::OUString aChartType = xChartType->getChartType();
1498 41 : if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1499 0 : return true;
1500 : }
1501 41 : return false;
1502 : }
1503 :
1504 0 : sal_Int32 DiagramHelper::getGeometry3D(
1505 : const uno::Reference< chart2::XDiagram > & xDiagram,
1506 : bool& rbFound, bool& rbAmbiguous )
1507 : {
1508 0 : sal_Int32 nCommonGeom( DataPointGeometry3D::CUBOID );
1509 0 : rbFound = false;
1510 0 : rbAmbiguous = false;
1511 :
1512 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1513 0 : DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1514 :
1515 0 : if( aSeriesVec.empty())
1516 0 : rbAmbiguous = true;
1517 :
1518 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1519 0 : aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1520 : {
1521 : try
1522 : {
1523 0 : sal_Int32 nGeom = 0;
1524 0 : Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY_THROW );
1525 0 : if( xProp->getPropertyValue( C2U( "Geometry3D" )) >>= nGeom )
1526 : {
1527 0 : if( ! rbFound )
1528 : {
1529 : // first series
1530 0 : nCommonGeom = nGeom;
1531 0 : rbFound = true;
1532 : }
1533 : // further series: compare for uniqueness
1534 0 : else if( nCommonGeom != nGeom )
1535 : {
1536 0 : rbAmbiguous = true;
1537 : break;
1538 : }
1539 0 : }
1540 : }
1541 0 : catch( const uno::Exception & ex )
1542 : {
1543 : ASSERT_EXCEPTION( ex );
1544 : }
1545 : }
1546 :
1547 0 : return nCommonGeom;
1548 : }
1549 :
1550 0 : void DiagramHelper::setGeometry3D(
1551 : const Reference< chart2::XDiagram > & xDiagram,
1552 : sal_Int32 nNewGeometry )
1553 : {
1554 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1555 0 : DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1556 :
1557 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1558 0 : aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1559 : {
1560 : DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(
1561 0 : *aIt, C2U( "Geometry3D" ), uno::makeAny( nNewGeometry ));
1562 0 : }
1563 0 : }
1564 :
1565 41 : sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment(
1566 : const Reference< chart2::XDiagram > & xDiagram,
1567 : const Reference< chart2::XChartType >& xChartType )
1568 : {
1569 41 : sal_Int32 nResult = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
1570 : uno::Sequence < sal_Int32 > aAvailableMissingValueTreatments(
1571 41 : ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
1572 :
1573 41 : uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
1574 41 : if( xDiaProp.is() && (xDiaProp->getPropertyValue( C2U( "MissingValueTreatment" ) ) >>= nResult) )
1575 : {
1576 : //ensure that the set value is supported by this charttype
1577 41 : for( sal_Int32 nN = 0; nN < aAvailableMissingValueTreatments.getLength(); nN++ )
1578 41 : if( aAvailableMissingValueTreatments[nN] == nResult )
1579 41 : return nResult; //ok
1580 : }
1581 :
1582 : //otherwise use the first supported one
1583 0 : if( aAvailableMissingValueTreatments.getLength() )
1584 : {
1585 0 : nResult = aAvailableMissingValueTreatments[0];
1586 0 : return nResult;
1587 : }
1588 :
1589 0 : return nResult;
1590 : }
1591 :
1592 41 : DiagramPositioningMode DiagramHelper::getDiagramPositioningMode( const uno::Reference<
1593 : chart2::XDiagram > & xDiagram )
1594 : {
1595 41 : DiagramPositioningMode eMode = DiagramPositioningMode_AUTO;
1596 41 : uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY );
1597 41 : if( xDiaProps.is() )
1598 : {
1599 41 : RelativePosition aRelPos;
1600 41 : RelativeSize aRelSize;
1601 82 : if( (xDiaProps->getPropertyValue(C2U("RelativePosition")) >>= aRelPos ) &&
1602 41 : (xDiaProps->getPropertyValue(C2U("RelativeSize")) >>= aRelSize ) )
1603 : {
1604 0 : bool bPosSizeExcludeAxes=false;
1605 0 : xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxes;
1606 0 : if( bPosSizeExcludeAxes )
1607 0 : eMode = DiagramPositioningMode_EXCLUDING;
1608 : else
1609 0 : eMode = DiagramPositioningMode_INCLUDING;
1610 : }
1611 : }
1612 41 : return eMode;
1613 : }
1614 :
1615 156 : void lcl_ensureRange0to1( double& rValue )
1616 : {
1617 156 : if(rValue<0.0)
1618 0 : rValue=0.0;
1619 156 : if(rValue>1.0)
1620 0 : rValue=1.0;
1621 156 : }
1622 :
1623 39 : bool DiagramHelper::setDiagramPositioning( const uno::Reference< frame::XModel >& xChartModel,
1624 : const awt::Rectangle& rPosRect /*100th mm*/ )
1625 : {
1626 39 : ControllerLockGuard aCtrlLockGuard( xChartModel );
1627 :
1628 39 : bool bChanged = false;
1629 39 : awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
1630 39 : uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
1631 39 : if( !xDiaProps.is() )
1632 0 : return bChanged;
1633 :
1634 39 : RelativePosition aOldPos;
1635 39 : RelativeSize aOldSize;
1636 39 : xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aOldPos;
1637 39 : xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aOldSize;
1638 :
1639 39 : RelativePosition aNewPos;
1640 39 : aNewPos.Anchor = drawing::Alignment_TOP_LEFT;
1641 39 : aNewPos.Primary = double(rPosRect.X)/double(aPageSize.Width);
1642 39 : aNewPos.Secondary = double(rPosRect.Y)/double(aPageSize.Height);
1643 :
1644 39 : chart2::RelativeSize aNewSize;
1645 39 : aNewSize.Primary = double(rPosRect.Width)/double(aPageSize.Width);
1646 39 : aNewSize.Secondary = double(rPosRect.Height)/double(aPageSize.Height);
1647 :
1648 39 : lcl_ensureRange0to1( aNewPos.Primary );
1649 39 : lcl_ensureRange0to1( aNewPos.Secondary );
1650 39 : lcl_ensureRange0to1( aNewSize.Primary );
1651 39 : lcl_ensureRange0to1( aNewSize.Secondary );
1652 39 : if( (aNewPos.Primary + aNewSize.Primary) > 1.0 )
1653 0 : aNewPos.Primary = 1.0 - aNewSize.Primary;
1654 39 : if( (aNewPos.Secondary + aNewSize.Secondary) > 1.0 )
1655 0 : aNewPos.Secondary = 1.0 - aNewSize.Secondary;
1656 :
1657 39 : xDiaProps->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aNewPos) );
1658 39 : xDiaProps->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aNewSize) );
1659 :
1660 : bChanged = (aOldPos.Anchor!=aNewPos.Anchor) ||
1661 : (aOldPos.Primary!=aNewPos.Primary) ||
1662 : (aOldPos.Secondary!=aNewPos.Secondary) ||
1663 : (aOldSize.Primary!=aNewSize.Primary) ||
1664 39 : (aOldSize.Secondary!=aNewSize.Secondary);
1665 39 : return bChanged;
1666 : }
1667 :
1668 0 : awt::Rectangle DiagramHelper::getDiagramRectangleFromModel( const uno::Reference< frame::XModel >& xChartModel )
1669 : {
1670 0 : awt::Rectangle aRet(-1,-1,-1,-1);
1671 :
1672 0 : uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
1673 0 : if( !xDiaProps.is() )
1674 : return aRet;
1675 :
1676 0 : awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
1677 :
1678 0 : RelativePosition aRelPos;
1679 0 : RelativeSize aRelSize;
1680 0 : xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aRelPos;
1681 0 : xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aRelSize;
1682 :
1683 : awt::Size aAbsSize(
1684 : static_cast< sal_Int32 >( aRelSize.Primary * aPageSize.Width ),
1685 0 : static_cast< sal_Int32 >( aRelSize.Secondary * aPageSize.Height ));
1686 :
1687 : awt::Point aAbsPos(
1688 : static_cast< sal_Int32 >( aRelPos.Primary * aPageSize.Width ),
1689 0 : static_cast< sal_Int32 >( aRelPos.Secondary * aPageSize.Height ));
1690 :
1691 0 : awt::Point aAbsPosLeftTop = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos, aAbsSize, aRelPos.Anchor );
1692 :
1693 0 : aRet = awt::Rectangle(aAbsPosLeftTop.X, aAbsPosLeftTop.Y, aAbsSize.Width, aAbsSize.Height );
1694 :
1695 0 : return aRet;
1696 : }
1697 :
1698 41 : bool DiagramHelper::switchDiagramPositioningToExcludingPositioning(
1699 : const uno::Reference< frame::XModel >& xChartModel
1700 : , bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning )
1701 : {
1702 : //return true if something was changed
1703 41 : const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1704 41 : if( nCurrentODFVersion > SvtSaveOptions::ODFVER_012 )
1705 : {
1706 41 : uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartModel, uno::UNO_QUERY ) ;
1707 41 : if( xOldDoc.is() )
1708 : {
1709 41 : uno::Reference< ::com::sun::star::chart::XDiagramPositioning > xDiagramPositioning( xOldDoc->getDiagram(), uno::UNO_QUERY );
1710 41 : if( xDiagramPositioning.is() && ( bConvertAlsoFromAutoPositioning || !xDiagramPositioning->isAutomaticDiagramPositioning() )
1711 0 : && !xDiagramPositioning->isExcludingDiagramPositioning() )
1712 : {
1713 0 : ControllerLockGuard aCtrlLockGuard( xChartModel );
1714 0 : uno::Reference< util::XModifiable > xModifiable( xChartModel, uno::UNO_QUERY );
1715 0 : bool bModelWasModified = xModifiable.is() && xModifiable->isModified();
1716 0 : xDiagramPositioning->setDiagramPositionExcludingAxes( xDiagramPositioning->calculateDiagramPositionExcludingAxes() );
1717 0 : if(bResetModifiedState && !bModelWasModified && xModifiable.is() )
1718 0 : xModifiable->setModified(sal_False);
1719 0 : return true;
1720 41 : }
1721 41 : }
1722 : }
1723 41 : return false;
1724 : }
1725 :
1726 : } // namespace chart
1727 :
1728 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|