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