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