1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "DiagramHelper.hxx"
31 #include "LegendHelper.hxx"
32 #include "PropertyHelper.hxx"
34 #include "DataSeriesHelper.hxx"
35 #include "AxisHelper.hxx"
36 #include "ContainerHelper.hxx"
37 #include "ChartTypeHelper.hxx"
38 #include "ChartModelHelper.hxx"
39 #include "CommonConverters.hxx"
40 #include "ExplicitCategoriesProvider.hxx"
41 #include "servicenames_charttypes.hxx"
42 #include "ChartModelHelper.hxx"
43 #include "RelativePositionHelper.hxx"
44 #include "ControllerLockGuard.hxx"
46 #include <com/sun/star/chart/MissingValueTreatment.hpp>
47 #include <com/sun/star/chart/XChartDocument.hpp>
48 #include <com/sun/star/chart/XDiagramPositioning.hpp>
49 #include <com/sun/star/chart2/XTitled.hpp>
50 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
51 #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
52 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
53 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
54 #include <com/sun/star/chart2/InterpretedData.hpp>
55 #include <com/sun/star/chart2/AxisType.hpp>
56 #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
57 #include <com/sun/star/chart2/RelativePosition.hpp>
58 #include <com/sun/star/chart2/RelativeSize.hpp>
60 #include <unotools/saveopt.hxx>
61 #include <rtl/math.hxx>
63 #include <com/sun/star/util/XModifiable.hpp>
65 using namespace ::com::sun::star
;
66 using namespace ::com::sun::star::chart2
;
67 using namespace ::std
;
69 using ::com::sun::star::uno::Reference
;
70 using ::com::sun::star::uno::Sequence
;
71 using ::rtl::OUString
;
77 DiagramHelper::tTemplateWithServiceName
78 DiagramHelper::getTemplateForDiagram(
79 const Reference
< XDiagram
> & xDiagram
,
80 const Reference
< lang::XMultiServiceFactory
> & xChartTypeManager
,
81 const OUString
& rPreferredTemplateName
)
83 DiagramHelper::tTemplateWithServiceName aResult
;
85 if( ! (xChartTypeManager
.is() && xDiagram
.is()))
88 Sequence
< OUString
> aServiceNames( xChartTypeManager
->getAvailableServiceNames());
89 const sal_Int32 nLength
= aServiceNames
.getLength();
91 bool bHasPreferredTemplate
= (rPreferredTemplateName
.getLength() > 0);
92 bool bTemplateFound
= false;
94 if( bHasPreferredTemplate
)
96 Reference
< XChartTypeTemplate
> xTempl(
97 xChartTypeManager
->createInstance( rPreferredTemplateName
), uno::UNO_QUERY
);
100 xTempl
->matchesTemplate( xDiagram
, sal_True
))
102 aResult
.first
= xTempl
;
103 aResult
.second
= rPreferredTemplateName
;
104 bTemplateFound
= true;
108 for( sal_Int32 i
= 0; ! bTemplateFound
&& i
< nLength
; ++i
)
112 if( ! bHasPreferredTemplate
||
113 ! rPreferredTemplateName
.equals( aServiceNames
[ i
] ))
115 Reference
< XChartTypeTemplate
> xTempl(
116 xChartTypeManager
->createInstance( aServiceNames
[ i
] ), uno::UNO_QUERY_THROW
);
118 if( xTempl
->matchesTemplate( xDiagram
, sal_True
))
120 aResult
.first
= xTempl
;
121 aResult
.second
= aServiceNames
[ i
];
122 bTemplateFound
= true;
126 catch( uno::Exception
& ex
)
128 ASSERT_EXCEPTION( ex
);
136 void DiagramHelper::setVertical(
137 const Reference
< XDiagram
> & xDiagram
,
138 bool bVertical
/* = true */ )
142 Reference
< XCoordinateSystemContainer
> xCnt( xDiagram
, uno::UNO_QUERY
);
145 Sequence
< Reference
< XCoordinateSystem
> > aCooSys(
146 xCnt
->getCoordinateSystems());
148 aValue
<<= bVertical
;
149 for( sal_Int32 i
=0; i
<aCooSys
.getLength(); ++i
)
151 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSys
[i
] );
152 Reference
< beans::XPropertySet
> xProp( xCooSys
, uno::UNO_QUERY
);
153 bool bChanged
= false;
156 bool bOldSwap
= sal_False
;
157 if( !(xProp
->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bOldSwap
)
158 || bVertical
!= bOldSwap
)
162 xProp
->setPropertyValue( C2U("SwapXAndYAxis"), aValue
);
166 const sal_Int32
nDimensionCount( xCooSys
->getDimension() );
167 sal_Int32 nDimIndex
= 0;
168 for(nDimIndex
=0; nDimIndex
<nDimensionCount
; ++nDimIndex
)
170 const sal_Int32 nMaximumScaleIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimIndex
);
171 for(sal_Int32 nI
=0; nI
<=nMaximumScaleIndex
; ++nI
)
173 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimIndex
,nI
));
176 //adapt title rotation only when axis swapping has changed
179 Reference
< XTitled
> xTitled( xAxis
, uno::UNO_QUERY
);
182 Reference
< beans::XPropertySet
> xTitleProps( xTitled
->getTitleObject(), uno::UNO_QUERY
);
183 if( !xTitleProps
.is() )
185 double fAngleDegree
= 0.0;
186 xTitleProps
->getPropertyValue( C2U( "TextRotation" ) ) >>= fAngleDegree
;
187 if( !::rtl::math::approxEqual( fAngleDegree
, 0.0 )
188 && !::rtl::math::approxEqual( fAngleDegree
, 90.0 ) )
191 double fNewAngleDegree
= 0.0;
192 if( !bVertical
&& nDimIndex
== 1 )
193 fNewAngleDegree
= 90.0;
194 else if( bVertical
&& nDimIndex
== 0 )
195 fNewAngleDegree
= 90.0;
197 xTitleProps
->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree
));
207 catch( uno::Exception
& ex
)
209 ASSERT_EXCEPTION( ex
);
214 bool DiagramHelper::getVertical( const uno::Reference
< chart2::XDiagram
> & xDiagram
,
215 bool& rbFound
, bool& rbAmbiguous
)
221 Reference
< XCoordinateSystemContainer
> xCnt( xDiagram
, uno::UNO_QUERY
);
224 Sequence
< Reference
< XCoordinateSystem
> > aCooSys(
225 xCnt
->getCoordinateSystems());
226 for( sal_Int32 i
=0; i
<aCooSys
.getLength(); ++i
)
228 Reference
< beans::XPropertySet
> xProp( aCooSys
[i
], uno::UNO_QUERY
);
231 bool bCurrent
= false;
232 if( xProp
->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bCurrent
)
239 else if( bCurrent
!= bValue
)
241 // ambiguous -> choose always first found
252 void DiagramHelper::setStackMode(
253 const Reference
< XDiagram
> & xDiagram
,
254 StackMode eStackMode
,
255 bool bOnlyAtFirstChartType
/* = true */
260 if( eStackMode
== StackMode_AMBIGUOUS
)
263 bool bValueFound
= false;
264 bool bIsAmbiguous
= false;
265 StackMode eOldStackMode
= DiagramHelper::getStackMode( xDiagram
, bValueFound
, bIsAmbiguous
);
267 if( eStackMode
== eOldStackMode
&& !bIsAmbiguous
)
270 StackingDirection eNewDirection
= StackingDirection_NO_STACKING
;
271 if( eStackMode
== StackMode_Y_STACKED
|| eStackMode
== StackMode_Y_STACKED_PERCENT
)
272 eNewDirection
= StackingDirection_Y_STACKING
;
273 else if( eStackMode
== StackMode_Z_STACKED
)
274 eNewDirection
= StackingDirection_Z_STACKING
;
276 uno::Any
aNewDirection( uno::makeAny(eNewDirection
) );
278 sal_Bool bPercent
= sal_False
;
279 if( eStackMode
== StackMode_Y_STACKED_PERCENT
)
282 //iterate through all coordinate systems
283 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
284 if( !xCooSysContainer
.is() )
286 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
287 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
289 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
290 //set correct percent stacking
291 const sal_Int32 nMaximumScaleIndex
= xCooSys
->getMaximumAxisIndexByDimension(1);
292 for(sal_Int32 nI
=0; nI
<=nMaximumScaleIndex
; ++nI
)
294 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1,nI
));
297 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
298 if( (aScaleData
.AxisType
==AxisType::PERCENT
) != bPercent
)
301 aScaleData
.AxisType
= AxisType::PERCENT
;
303 aScaleData
.AxisType
= AxisType::REALNUMBER
;
304 xAxis
->setScaleData( aScaleData
);
308 //iterate through all chart types in the current coordinate system
309 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
310 if( !xChartTypeContainer
.is() )
312 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
313 sal_Int32 nMax
= aChartTypeList
.getLength();
314 if( bOnlyAtFirstChartType
317 for( sal_Int32 nT
= 0; nT
< nMax
; ++nT
)
319 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
321 //iterate through all series in this chart type
322 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
323 OSL_ASSERT( xDataSeriesContainer
.is());
324 if( !xDataSeriesContainer
.is() )
327 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
328 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
330 Reference
< beans::XPropertySet
> xProp( aSeriesList
[nS
], uno::UNO_QUERY
);
332 xProp
->setPropertyValue( C2U( "StackingDirection" ), aNewDirection
);
337 catch( uno::Exception
& ex
)
339 ASSERT_EXCEPTION( ex
);
345 StackMode
DiagramHelper::getStackMode( const Reference
< XDiagram
> & xDiagram
, bool& rbFound
, bool& rbAmbiguous
)
350 StackMode eGlobalStackMode
= StackMode_NONE
;
352 //iterate through all coordinate systems
353 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
354 if( !xCooSysContainer
.is() )
355 return eGlobalStackMode
;
356 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
357 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
359 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
361 //iterate through all chart types in the current coordinate system
362 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
363 if( !xChartTypeContainer
.is() )
365 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
366 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
368 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
370 StackMode eLocalStackMode
= DiagramHelper::getStackModeFromChartType(
371 xChartType
, rbFound
, rbAmbiguous
, xCooSys
);
373 if( rbFound
&& eLocalStackMode
!= eGlobalStackMode
&& nT
>0 )
376 return eGlobalStackMode
;
379 eGlobalStackMode
= eLocalStackMode
;
383 return eGlobalStackMode
;
387 StackMode
DiagramHelper::getStackModeFromChartType(
388 const Reference
< XChartType
> & xChartType
,
389 bool& rbFound
, bool& rbAmbiguous
,
390 const Reference
< XCoordinateSystem
> & xCorrespondingCoordinateSystem
)
392 StackMode eStackMode
= StackMode_NONE
;
398 Reference
< XDataSeriesContainer
> xDSCnt( xChartType
, uno::UNO_QUERY_THROW
);
399 Sequence
< Reference
< chart2::XDataSeries
> > aSeries( xDSCnt
->getDataSeries());
401 chart2::StackingDirection eCommonDirection
= chart2::StackingDirection_NO_STACKING
;
402 bool bDirectionInitialized
= false;
404 // first series is irrelvant for stacking, start with second, unless
405 // there is only one series
406 const sal_Int32 nSeriesCount
= aSeries
.getLength();
407 sal_Int32 i
= (nSeriesCount
== 1) ? 0: 1;
408 for( ; i
<nSeriesCount
; ++i
)
411 Reference
< beans::XPropertySet
> xProp( aSeries
[i
], uno::UNO_QUERY_THROW
);
412 chart2::StackingDirection eCurrentDirection
= eCommonDirection
;
413 // property is not MAYBEVOID
414 bool bSuccess
= ( xProp
->getPropertyValue( C2U("StackingDirection") ) >>= eCurrentDirection
);
415 OSL_ASSERT( bSuccess
);
416 (void)(bSuccess
); // avoid warning in non-debug builds
417 if( ! bDirectionInitialized
)
419 eCommonDirection
= eCurrentDirection
;
420 bDirectionInitialized
= true;
424 if( eCommonDirection
!= eCurrentDirection
)
434 if( eCommonDirection
== chart2::StackingDirection_Z_STACKING
)
435 eStackMode
= StackMode_Z_STACKED
;
436 else if( eCommonDirection
== chart2::StackingDirection_Y_STACKING
)
438 eStackMode
= StackMode_Y_STACKED
;
441 if( xCorrespondingCoordinateSystem
.is() )
443 if( 1 < xCorrespondingCoordinateSystem
->getDimension() )
445 sal_Int32 nAxisIndex
= 0;
447 nAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(aSeries
[0]);
449 Reference
< chart2::XAxis
> xAxis(
450 xCorrespondingCoordinateSystem
->getAxisByDimension( 1,nAxisIndex
));
453 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
454 if( aScaleData
.AxisType
==chart2::AxisType::PERCENT
)
455 eStackMode
= StackMode_Y_STACKED_PERCENT
;
462 catch( uno::Exception
& ex
)
464 ASSERT_EXCEPTION( ex
);
471 sal_Int32
DiagramHelper::getDimension( const Reference
< XDiagram
> & xDiagram
)
474 sal_Int32 nResult
= -1;
478 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY
);
479 if( xCooSysCnt
.is() )
481 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
482 xCooSysCnt
->getCoordinateSystems());
484 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
486 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[i
] );
489 nResult
= xCooSys
->getDimension();
495 catch( uno::Exception
& ex
)
497 ASSERT_EXCEPTION( ex
);
504 void DiagramHelper::setDimension(
505 const Reference
< XDiagram
> & xDiagram
,
506 sal_Int32 nNewDimensionCount
)
511 if( DiagramHelper::getDimension( xDiagram
) == nNewDimensionCount
)
516 bool rbFound
= false;
517 bool rbAmbiguous
= true;
518 StackMode eStackMode
= DiagramHelper::getStackMode( xDiagram
, rbFound
, rbAmbiguous
);
519 bool bIsSupportingOnlyDeepStackingFor3D
=false;
521 //change all coordinate systems:
522 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY_THROW
);
523 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
524 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
526 Reference
< XCoordinateSystem
> xOldCooSys( aCooSysList
[nCS
], uno::UNO_QUERY
);
527 Reference
< XCoordinateSystem
> xNewCooSys
;
529 Reference
< XChartTypeContainer
> xChartTypeContainer( xOldCooSys
, uno::UNO_QUERY
);
530 if( !xChartTypeContainer
.is() )
533 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
534 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
536 Reference
< XChartType
> xChartType( aChartTypeList
[nT
], uno::UNO_QUERY
);
537 bIsSupportingOnlyDeepStackingFor3D
= ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType
);
540 xNewCooSys
= xChartType
->createCoordinateSystem( nNewDimensionCount
);
543 //@todo make sure that all following charttypes are also capable of the new dimension
544 //otherwise separate them in a different group
545 //BM: might be done in replaceCoordinateSystem()
548 // replace the old coordinate system at all places where it was used
549 DiagramHelper::replaceCoordinateSystem( xDiagram
, xOldCooSys
, xNewCooSys
);
552 //correct stack mode if necessary
553 if( nNewDimensionCount
==3 && eStackMode
!= StackMode_Z_STACKED
&& bIsSupportingOnlyDeepStackingFor3D
)
554 DiagramHelper::setStackMode( xDiagram
, StackMode_Z_STACKED
);
555 else if( nNewDimensionCount
==2 && eStackMode
== StackMode_Z_STACKED
)
556 DiagramHelper::setStackMode( xDiagram
, StackMode_NONE
);
558 catch( uno::Exception
& ex
)
560 ASSERT_EXCEPTION( ex
);
565 void DiagramHelper::replaceCoordinateSystem(
566 const Reference
< XDiagram
> & xDiagram
,
567 const Reference
< XCoordinateSystem
> & xCooSysToReplace
,
568 const Reference
< XCoordinateSystem
> & xReplacement
)
570 OSL_ASSERT( xDiagram
.is());
574 // update the coordinate-system container
575 Reference
< XCoordinateSystemContainer
> xCont( xDiagram
, uno::UNO_QUERY
);
580 Reference
< chart2::data::XLabeledDataSequence
> xCategories
= DiagramHelper::getCategoriesFromDiagram( xDiagram
);
582 // move chart types of xCooSysToReplace to xReplacement
583 Reference
< XChartTypeContainer
> xCTCntCooSys( xCooSysToReplace
, uno::UNO_QUERY_THROW
);
584 Reference
< XChartTypeContainer
> xCTCntReplacement( xReplacement
, uno::UNO_QUERY_THROW
);
585 xCTCntReplacement
->setChartTypes( xCTCntCooSys
->getChartTypes());
587 xCont
->removeCoordinateSystem( xCooSysToReplace
);
588 xCont
->addCoordinateSystem( xReplacement
);
590 if( xCategories
.is() )
591 DiagramHelper::setCategoriesToDiagram( xCategories
, xDiagram
);
593 catch( uno::Exception
& ex
)
595 ASSERT_EXCEPTION( ex
);
601 bool DiagramHelper::isSeriesAttachedToMainAxis(
602 const uno::Reference
< chart2::XDataSeries
>& xDataSeries
)
604 sal_Int32 nAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
605 return (nAxisIndex
==0);
609 bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis
610 , const uno::Reference
< chart2::XDataSeries
>& xDataSeries
611 , const uno::Reference
< chart2::XDiagram
>& xDiagram
612 , const uno::Reference
< uno::XComponentContext
> & xContext
615 bool bChanged
= false;
617 //set property at axis
618 Reference
< beans::XPropertySet
> xProp( xDataSeries
, uno::UNO_QUERY_THROW
);
622 sal_Int32 nNewAxisIndex
= bAttachToMainAxis
? 0 : 1;
623 sal_Int32 nOldAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
624 uno::Reference
< chart2::XAxis
> xOldAxis( DiagramHelper::getAttachedAxis( xDataSeries
, xDiagram
) );
626 if( nOldAxisIndex
!= nNewAxisIndex
)
630 xProp
->setPropertyValue( C2U("AttachedAxisIndex"), uno::makeAny( nNewAxisIndex
) );
633 catch( const uno::Exception
& ex
)
635 ASSERT_EXCEPTION( ex
);
639 if( bChanged
&& xDiagram
.is() )
641 uno::Reference
< XAxis
> xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis
, xDiagram
) );
642 if(!xAxis
.is()) //create an axis if necessary
643 xAxis
= AxisHelper::createAxis( 1, bAttachToMainAxis
, xDiagram
, xContext
);
646 AxisHelper::makeAxisVisible( xAxis
);
647 AxisHelper::hideAxisIfNoDataIsAttached( xOldAxis
, xDiagram
);
655 uno::Reference
< XAxis
> DiagramHelper::getAttachedAxis(
656 const uno::Reference
< XDataSeries
>& xSeries
,
657 const uno::Reference
< XDiagram
>& xDiagram
)
659 return AxisHelper::getAxis( 1, DiagramHelper::isSeriesAttachedToMainAxis( xSeries
), xDiagram
);
663 uno::Reference
< XChartType
> DiagramHelper::getChartTypeOfSeries(
664 const uno::Reference
< chart2::XDiagram
>& xDiagram
665 , const uno::Reference
< XDataSeries
>& xGivenDataSeries
)
667 if( !xGivenDataSeries
.is() )
672 //iterate through the model to find the given xSeries
673 //the found parent indicates the charttype
675 //iterate through all coordinate systems
676 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
677 if( !xCooSysContainer
.is())
680 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
681 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
683 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
685 //iterate through all chart types in the current coordinate system
686 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
687 OSL_ASSERT( xChartTypeContainer
.is());
688 if( !xChartTypeContainer
.is() )
690 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
691 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
693 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
695 //iterate through all series in this chart type
696 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
697 OSL_ASSERT( xDataSeriesContainer
.is());
698 if( !xDataSeriesContainer
.is() )
701 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
702 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
704 if( xGivenDataSeries
==aSeriesList
[nS
] )
713 ::std::vector
< Reference
< XDataSeries
> >
714 DiagramHelper::getDataSeriesFromDiagram(
715 const Reference
< XDiagram
> & xDiagram
)
717 ::std::vector
< Reference
< XDataSeries
> > aResult
;
721 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
722 xDiagram
, uno::UNO_QUERY_THROW
);
723 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
724 xCooSysCnt
->getCoordinateSystems());
725 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
727 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[i
], uno::UNO_QUERY_THROW
);
728 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
729 for( sal_Int32 j
=0; j
<aChartTypeSeq
.getLength(); ++j
)
731 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypeSeq
[j
], uno::UNO_QUERY_THROW
);
732 Sequence
< Reference
< XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries() );
733 ::std::copy( aSeriesSeq
.getConstArray(), aSeriesSeq
.getConstArray() + aSeriesSeq
.getLength(),
734 ::std::back_inserter( aResult
));
738 catch( uno::Exception
& ex
)
740 ASSERT_EXCEPTION( ex
);
746 Sequence
< Sequence
< Reference
< XDataSeries
> > >
747 DiagramHelper::getDataSeriesGroups( const Reference
< XDiagram
> & xDiagram
)
749 vector
< Sequence
< Reference
< XDataSeries
> > > aResult
;
751 //iterate through all coordinate systems
752 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
753 if( xCooSysContainer
.is() )
755 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
756 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
758 //iterate through all chart types in the current coordinate system
759 Reference
< XChartTypeContainer
> xChartTypeContainer( aCooSysList
[nCS
], uno::UNO_QUERY
);
760 if( !xChartTypeContainer
.is() )
762 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
763 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
765 Reference
< XDataSeriesContainer
> xDataSeriesContainer( aChartTypeList
[nT
], uno::UNO_QUERY
);
766 if( !xDataSeriesContainer
.is() )
768 aResult
.push_back( xDataSeriesContainer
->getDataSeries() );
772 return ContainerHelper::ContainerToSequence( aResult
);
775 Reference
< XChartType
>
776 DiagramHelper::getChartTypeByIndex( const Reference
< XDiagram
>& xDiagram
, sal_Int32 nIndex
)
778 Reference
< XChartType
> xChartType
;
780 //iterate through all coordinate systems
781 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
782 if( ! xCooSysContainer
.is())
785 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
786 sal_Int32 nTypesSoFar
= 0;
787 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
789 Reference
< XChartTypeContainer
> xChartTypeContainer( aCooSysList
[nCS
], uno::UNO_QUERY
);
790 if( !xChartTypeContainer
.is() )
792 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
793 if( nIndex
>= 0 && nIndex
< (nTypesSoFar
+ aChartTypeList
.getLength()) )
795 xChartType
.set( aChartTypeList
[nIndex
- nTypesSoFar
] );
798 nTypesSoFar
+= aChartTypeList
.getLength();
807 std::vector
< Reference
< XAxis
> > lcl_getAxisHoldingCategoriesFromDiagram(
808 const Reference
< XDiagram
> & xDiagram
)
810 std::vector
< Reference
< XAxis
> > aRet
;
812 Reference
< XAxis
> xResult
;
813 // return first x-axis as fall-back
814 Reference
< XAxis
> xFallBack
;
817 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
818 xDiagram
, uno::UNO_QUERY_THROW
);
819 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
820 xCooSysCnt
->getCoordinateSystems());
821 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
823 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[i
] );
824 OSL_ASSERT( xCooSys
.is());
825 for( sal_Int32 nN
= xCooSys
->getDimension(); nN
--; )
827 const sal_Int32 nMaximumScaleIndex
= xCooSys
->getMaximumAxisIndexByDimension(nN
);
828 for(sal_Int32 nI
=0; nI
<=nMaximumScaleIndex
; ++nI
)
830 Reference
< XAxis
> xAxis
= xCooSys
->getAxisByDimension( nN
,nI
);
831 OSL_ASSERT( xAxis
.is());
834 ScaleData aScaleData
= xAxis
->getScaleData();
835 if( aScaleData
.Categories
.is() || (aScaleData
.AxisType
== AxisType::CATEGORY
) )
837 aRet
.push_back(xAxis
);
839 if( (nN
== 0) && !xFallBack
.is())
840 xFallBack
.set( xAxis
);
846 catch( uno::Exception
& ex
)
848 ASSERT_EXCEPTION( ex
);
852 aRet
.push_back(xFallBack
);
857 } // anonymous namespace
860 bool DiagramHelper::isCategoryDiagram(
861 const Reference
< XDiagram
>& xDiagram
)
865 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
866 xDiagram
, uno::UNO_QUERY_THROW
);
867 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
868 xCooSysCnt
->getCoordinateSystems());
869 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
871 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[i
] );
872 OSL_ASSERT( xCooSys
.is());
873 for( sal_Int32 nN
= xCooSys
->getDimension(); nN
--; )
875 const sal_Int32 nMaximumScaleIndex
= xCooSys
->getMaximumAxisIndexByDimension(nN
);
876 for(sal_Int32 nI
=0; nI
<=nMaximumScaleIndex
; ++nI
)
878 Reference
< XAxis
> xAxis
= xCooSys
->getAxisByDimension( nN
,nI
);
879 OSL_ASSERT( xAxis
.is());
882 ScaleData aScaleData
= xAxis
->getScaleData();
883 if( aScaleData
.AxisType
== AxisType::CATEGORY
)
890 catch( uno::Exception
& ex
)
892 ASSERT_EXCEPTION( ex
);
899 void DiagramHelper::setCategoriesToDiagram(
900 const Reference
< chart2::data::XLabeledDataSequence
>& xCategories
,
901 const Reference
< XDiagram
>& xDiagram
,
902 bool bSetAxisType
/* = false */,
903 bool bCategoryAxis
/* = true */ )
905 std::vector
< Reference
< chart2::XAxis
> > aCatAxes(
906 lcl_getAxisHoldingCategoriesFromDiagram( xDiagram
));
908 std::vector
< Reference
< chart2::XAxis
> >::iterator
aIt( aCatAxes
.begin() );
909 std::vector
< Reference
< chart2::XAxis
> >::const_iterator
aEnd( aCatAxes
.end() );
911 for( aIt
= aCatAxes
.begin(); aIt
!= aEnd
; ++aIt
)
913 Reference
< chart2::XAxis
> xCatAxis(*aIt
);
916 ScaleData
aScaleData( xCatAxis
->getScaleData());
917 aScaleData
.Categories
= xCategories
;
921 aScaleData
.AxisType
= AxisType::CATEGORY
;
922 else if( aScaleData
.AxisType
== AxisType::CATEGORY
)
923 aScaleData
.AxisType
= AxisType::REALNUMBER
;
925 xCatAxis
->setScaleData( aScaleData
);
931 Reference
< data::XLabeledDataSequence
>
932 DiagramHelper::getCategoriesFromDiagram(
933 const Reference
< XDiagram
> & xDiagram
)
935 Reference
< data::XLabeledDataSequence
> xResult
;
939 std::vector
< Reference
< chart2::XAxis
> > aCatAxes(
940 lcl_getAxisHoldingCategoriesFromDiagram( xDiagram
));
941 std::vector
< Reference
< chart2::XAxis
> >::iterator
aIt( aCatAxes
.begin() );
942 std::vector
< Reference
< chart2::XAxis
> >::const_iterator
aEnd( aCatAxes
.end() );
943 //search for first categories
946 Reference
< chart2::XAxis
> xCatAxis(*aIt
);
949 ScaleData
aScaleData( xCatAxis
->getScaleData());
950 if( aScaleData
.Categories
.is() )
952 xResult
.set( aScaleData
.Categories
);
953 uno::Reference
<beans::XPropertySet
> xProp(aScaleData
.Categories
->getValues(), uno::UNO_QUERY
);
958 xProp
->setPropertyValue( C2U( "Role" ), uno::makeAny( C2U("categories") ) );
960 catch( uno::Exception
& ex
)
962 ASSERT_EXCEPTION( ex
);
969 catch( uno::Exception
& ex
)
971 ASSERT_EXCEPTION( ex
);
977 void lcl_generateAutomaticCategoriesFromChartType(
978 Sequence
< rtl::OUString
>& rRet
,
979 const Reference
< XChartType
>& xChartType
)
983 rtl::OUString
aMainSeq( xChartType
->getRoleOfSequenceForSeriesLabel() );
984 Reference
< XDataSeriesContainer
> xSeriesCnt( xChartType
, uno::UNO_QUERY
);
985 if( xSeriesCnt
.is() )
987 Sequence
< Reference
< XDataSeries
> > aSeriesSeq( xSeriesCnt
->getDataSeries() );
988 for( sal_Int32 nS
= 0; nS
< aSeriesSeq
.getLength(); nS
++ )
990 Reference
< data::XDataSource
> xDataSource( aSeriesSeq
[nS
], uno::UNO_QUERY
);
991 if( !xDataSource
.is() )
993 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
994 ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource
, aMainSeq
));
995 if( !xLabeledSeq
.is() )
997 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues() );
998 if( !xValueSeq
.is() )
1000 rRet
= xValueSeq
->generateLabel( chart2::data::LabelOrigin_LONG_SIDE
);
1001 if( rRet
.getLength() )
1007 Sequence
< rtl::OUString
> DiagramHelper::generateAutomaticCategoriesFromCooSys( const Reference
< XCoordinateSystem
> & xCooSys
)
1009 Sequence
< rtl::OUString
> aRet
;
1011 Reference
< XChartTypeContainer
> xTypeCntr( xCooSys
, uno::UNO_QUERY
);
1012 if( xTypeCntr
.is() )
1014 Sequence
< Reference
< XChartType
> > aChartTypes( xTypeCntr
->getChartTypes() );
1015 for( sal_Int32 nN
=0; nN
<aChartTypes
.getLength(); nN
++ )
1017 lcl_generateAutomaticCategoriesFromChartType( aRet
, aChartTypes
[nN
] );
1018 if( aRet
.getLength() )
1026 Sequence
< rtl::OUString
> DiagramHelper::getExplicitSimpleCategories(
1027 const Reference
< XChartDocument
>& xChartDoc
)
1029 Sequence
< rtl::OUString
> aRet
;
1030 uno::Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
1031 if(xChartModel
.is())
1033 uno::Reference
< chart2::XCoordinateSystem
> xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel
) );
1034 ExplicitCategoriesProvider
aExplicitCategoriesProvider( xCooSys
, xChartModel
);
1035 aRet
= aExplicitCategoriesProvider
.getSimpleCategories();
1041 Sequence
< Reference
< XChartType
> >
1042 DiagramHelper::getChartTypesFromDiagram(
1043 const Reference
< XDiagram
> & xDiagram
)
1045 ::std::vector
< Reference
< XChartType
> > aResult
;
1050 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
1051 xDiagram
, uno::UNO_QUERY_THROW
);
1052 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
1053 xCooSysCnt
->getCoordinateSystems());
1054 for( sal_Int32 i
=0; i
<aCooSysSeq
.getLength(); ++i
)
1056 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[i
], uno::UNO_QUERY_THROW
);
1057 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
1058 ::std::copy( aChartTypeSeq
.getConstArray(), aChartTypeSeq
.getConstArray() + aChartTypeSeq
.getLength(),
1059 ::std::back_inserter( aResult
));
1062 catch( uno::Exception
& ex
)
1064 ASSERT_EXCEPTION( ex
);
1067 return ContainerHelper::ContainerToSequence( aResult
);
1071 bool DiagramHelper::areChartTypesCompatible( const Reference
< ::chart2::XChartType
>& xFirstType
,
1072 const Reference
< ::chart2::XChartType
>& xSecondType
)
1074 if( !xFirstType
.is() || !xSecondType
.is() )
1077 ::std::vector
< ::rtl::OUString
> aFirstRoles( ContainerHelper::SequenceToVector( xFirstType
->getSupportedMandatoryRoles() ) );
1078 ::std::vector
< ::rtl::OUString
> aSecondRoles( ContainerHelper::SequenceToVector( xSecondType
->getSupportedMandatoryRoles() ) );
1079 ::std::sort( aFirstRoles
.begin(), aFirstRoles
.end() );
1080 ::std::sort( aSecondRoles
.begin(), aSecondRoles
.end() );
1081 return ( aFirstRoles
== aSecondRoles
);
1087 * This method implements the logic of checking if a series can be moved
1088 * forward/backward. Depending on the "bDoMove" parameter the series will
1089 * be moved (bDoMove = true) or the function just will test if the
1090 * series can be moved without doing the move (bDoMove = false).
1093 * Reference to the diagram that contains the series.
1095 * @param xGivenDataSeries
1096 * Reference to the series that should moved or tested for moving.
1099 * Direction in which the series should be moved or tested for moving.
1102 * Should this function really move the series (true) or just test if it is
1107 * in case of bDoMove == true
1108 * - True : if the move was done
1109 * - False : the move failed
1110 * in case of bDoMove == false
1111 * - True : the series can be moved
1112 * - False : the series can not be moved
1116 bool lcl_moveSeriesOrCheckIfMoveIsAllowed(
1117 const Reference
< XDiagram
>& xDiagram
,
1118 const Reference
< XDataSeries
>& xGivenDataSeries
,
1122 bool bMovedOrMoveAllowed
= false;
1126 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
1128 //find position of series.
1129 bool bFound
= false;
1131 if( xGivenDataSeries
.is() && xCooSysContainer
.is() )
1133 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
1135 for( sal_Int32 nCS
= 0; !bFound
&& nCS
< aCooSysList
.getLength(); ++nCS
)
1137 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
1139 //iterate through all chart types in the current coordinate system
1140 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
1141 OSL_ASSERT( xChartTypeContainer
.is());
1142 if( !xChartTypeContainer
.is() )
1144 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
1145 uno::Reference
< XChartType
> xFormerChartType
;
1147 for( sal_Int32 nT
= 0; !bFound
&& nT
< aChartTypeList
.getLength(); ++nT
)
1149 uno::Reference
< XChartType
> xCurrentChartType( aChartTypeList
[nT
] );
1151 //iterate through all series in this chart type
1152 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xCurrentChartType
, uno::UNO_QUERY
);
1153 OSL_ASSERT( xDataSeriesContainer
.is());
1154 if( !xDataSeriesContainer
.is() )
1157 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
1159 for( sal_Int32 nS
= 0; !bFound
&& nS
< aSeriesList
.getLength(); ++nS
)
1162 // We found the series we are interrested in !
1163 if( xGivenDataSeries
==aSeriesList
[nS
] )
1165 sal_Int32 nOldSeriesIndex
= nS
;
1170 sal_Int32 nNewSeriesIndex
= nS
;
1178 if( nNewSeriesIndex
>= 0 && nNewSeriesIndex
< aSeriesList
.getLength() )
1180 //move series in the same charttype
1181 bMovedOrMoveAllowed
= true;
1184 aSeriesList
[ nOldSeriesIndex
] = aSeriesList
[ nNewSeriesIndex
];
1185 aSeriesList
[ nNewSeriesIndex
] = xGivenDataSeries
;
1186 xDataSeriesContainer
->setDataSeries( aSeriesList
);
1189 else if( nNewSeriesIndex
<0 )
1191 //exchange series with former charttype
1192 if( xFormerChartType
.is() && DiagramHelper::areChartTypesCompatible( xFormerChartType
, xCurrentChartType
) )
1194 bMovedOrMoveAllowed
= true;
1197 uno::Reference
< XDataSeriesContainer
> xOtherDataSeriesContainer( xFormerChartType
, uno::UNO_QUERY
);
1198 if( xOtherDataSeriesContainer
.is() )
1200 uno::Sequence
< uno::Reference
< XDataSeries
> > aOtherSeriesList( xOtherDataSeriesContainer
->getDataSeries() );
1201 sal_Int32 nOtherSeriesIndex
= aOtherSeriesList
.getLength()-1;
1202 if( nOtherSeriesIndex
>= 0 && nOtherSeriesIndex
< aOtherSeriesList
.getLength() )
1204 uno::Reference
< XDataSeries
> xExchangeSeries( aOtherSeriesList
[nOtherSeriesIndex
] );
1205 aOtherSeriesList
[nOtherSeriesIndex
] = xGivenDataSeries
;
1206 xOtherDataSeriesContainer
->setDataSeries(aOtherSeriesList
);
1208 aSeriesList
[nOldSeriesIndex
]=xExchangeSeries
;
1209 xDataSeriesContainer
->setDataSeries(aSeriesList
);
1215 else if( nT
+1 < aChartTypeList
.getLength() )
1217 //exchange series with next charttype
1218 uno::Reference
< XChartType
> xOtherChartType( aChartTypeList
[nT
+1] );
1219 if( xOtherChartType
.is() && DiagramHelper::areChartTypesCompatible( xOtherChartType
, xCurrentChartType
) )
1221 bMovedOrMoveAllowed
= true;
1224 uno::Reference
< XDataSeriesContainer
> xOtherDataSeriesContainer( xOtherChartType
, uno::UNO_QUERY
);
1225 if( xOtherDataSeriesContainer
.is() )
1227 uno::Sequence
< uno::Reference
< XDataSeries
> > aOtherSeriesList( xOtherDataSeriesContainer
->getDataSeries() );
1228 sal_Int32 nOtherSeriesIndex
= 0;
1229 if( nOtherSeriesIndex
>= 0 && nOtherSeriesIndex
< aOtherSeriesList
.getLength() )
1231 uno::Reference
< XDataSeries
> xExchangeSeries( aOtherSeriesList
[nOtherSeriesIndex
] );
1232 aOtherSeriesList
[nOtherSeriesIndex
] = xGivenDataSeries
;
1233 xOtherDataSeriesContainer
->setDataSeries(aOtherSeriesList
);
1235 aSeriesList
[nOldSeriesIndex
]=xExchangeSeries
;
1236 xDataSeriesContainer
->setDataSeries(aSeriesList
);
1243 catch( util::CloseVetoException
& )
1246 catch( uno::RuntimeException
& )
1251 xFormerChartType
= xCurrentChartType
;
1256 catch( util::CloseVetoException
& )
1259 catch( uno::RuntimeException
& )
1262 return bMovedOrMoveAllowed
;
1264 } // anonymous namespace
1267 bool DiagramHelper::isSeriesMoveable(
1268 const Reference
< XDiagram
>& xDiagram
,
1269 const Reference
< XDataSeries
>& xGivenDataSeries
,
1272 bool bIsMoveable
= false;
1273 const bool bDoMove
= false;
1275 bIsMoveable
= lcl_moveSeriesOrCheckIfMoveIsAllowed(
1276 xDiagram
, xGivenDataSeries
, bForward
, bDoMove
);
1282 bool DiagramHelper::moveSeries( const Reference
< XDiagram
>& xDiagram
, const Reference
< XDataSeries
>& xGivenDataSeries
, bool bForward
)
1284 bool bMoved
= false;
1285 const bool bDoMove
= true;
1287 bMoved
= lcl_moveSeriesOrCheckIfMoveIsAllowed(
1288 xDiagram
, xGivenDataSeries
, bForward
, bDoMove
);
1293 bool DiagramHelper::isSupportingFloorAndWall( const Reference
<
1294 chart2::XDiagram
>& xDiagram
)
1296 //pies and donuts currently do not support this because of wrong files from older versions
1297 //todo: allow this in future again, if fileversion are available for ole objects (metastream)
1298 //thus the wrong bottom can be removed on import
1300 Sequence
< Reference
< chart2::XChartType
> > aTypes(
1301 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram
) );
1302 for( sal_Int32 nN
= 0; nN
< aTypes
.getLength(); nN
++ )
1304 Reference
< chart2::XChartType
> xType( aTypes
[nN
] );
1305 if( xType
.is() && xType
->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_PIE
) )
1307 if( xType
.is() && xType
->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_NET
) )
1309 if( xType
.is() && xType
->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET
) )
1315 bool DiagramHelper::isPieOrDonutChart( const ::com::sun::star::uno::Reference
<
1316 ::com::sun::star::chart2::XDiagram
>& xDiagram
)
1318 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex(
1321 if( xChartType
.is() )
1323 rtl::OUString aChartType
= xChartType
->getChartType();
1324 if( aChartType
.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE
) )
1331 sal_Int32
DiagramHelper::getGeometry3D(
1332 const uno::Reference
< chart2::XDiagram
> & xDiagram
,
1333 bool& rbFound
, bool& rbAmbiguous
)
1335 sal_Int32
nCommonGeom( DataPointGeometry3D::CUBOID
);
1337 rbAmbiguous
= false;
1339 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVec(
1340 DiagramHelper::getDataSeriesFromDiagram( xDiagram
));
1342 if( aSeriesVec
.empty())
1345 for( ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator aIt
=
1346 aSeriesVec
.begin(); aIt
!= aSeriesVec
.end(); ++aIt
)
1350 sal_Int32 nGeom
= 0;
1351 Reference
< beans::XPropertySet
> xProp( *aIt
, uno::UNO_QUERY_THROW
);
1352 if( xProp
->getPropertyValue( C2U( "Geometry3D" )) >>= nGeom
)
1357 nCommonGeom
= nGeom
;
1360 // further series: compare for uniqueness
1361 else if( nCommonGeom
!= nGeom
)
1368 catch( uno::Exception
& ex
)
1370 ASSERT_EXCEPTION( ex
);
1378 void DiagramHelper::setGeometry3D(
1379 const Reference
< chart2::XDiagram
> & xDiagram
,
1380 sal_Int32 nNewGeometry
)
1382 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVec(
1383 DiagramHelper::getDataSeriesFromDiagram( xDiagram
));
1385 for( ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator aIt
=
1386 aSeriesVec
.begin(); aIt
!= aSeriesVec
.end(); ++aIt
)
1388 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(
1389 *aIt
, C2U( "Geometry3D" ), uno::makeAny( nNewGeometry
));
1394 sal_Int32
DiagramHelper::getCorrectedMissingValueTreatment(
1395 const Reference
< chart2::XDiagram
> & xDiagram
,
1396 const Reference
< chart2::XChartType
>& xChartType
)
1398 sal_Int32 nResult
= ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP
;
1399 uno::Sequence
< sal_Int32
> aAvailableMissingValueTreatments(
1400 ChartTypeHelper::getSupportedMissingValueTreatments( xChartType
) );
1402 uno::Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
1403 if( xDiaProp
.is() && (xDiaProp
->getPropertyValue( C2U( "MissingValueTreatment" ) ) >>= nResult
) )
1405 //ensure that the set value is supported by this charttype
1406 for( sal_Int32 nN
= 0; nN
< aAvailableMissingValueTreatments
.getLength(); nN
++ )
1407 if( aAvailableMissingValueTreatments
[nN
] == nResult
)
1408 return nResult
; //ok
1411 //otherwise use the first supported one
1412 if( aAvailableMissingValueTreatments
.getLength() )
1414 nResult
= aAvailableMissingValueTreatments
[0];
1422 DiagramPositioningMode
DiagramHelper::getDiagramPositioningMode( const uno::Reference
<
1423 chart2::XDiagram
> & xDiagram
)
1425 DiagramPositioningMode eMode
= DiagramPositioningMode_AUTO
;
1426 uno::Reference
< beans::XPropertySet
> xDiaProps( xDiagram
, uno::UNO_QUERY
);
1427 if( xDiaProps
.is() )
1429 RelativePosition aRelPos
;
1430 RelativeSize aRelSize
;
1431 if( (xDiaProps
->getPropertyValue(C2U("RelativePosition")) >>= aRelPos
) &&
1432 (xDiaProps
->getPropertyValue(C2U("RelativeSize")) >>= aRelSize
) )
1434 bool bPosSizeExcludeAxes
=false;
1435 xDiaProps
->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxes
;
1436 if( bPosSizeExcludeAxes
)
1437 eMode
= DiagramPositioningMode_EXCLUDING
;
1439 eMode
= DiagramPositioningMode_INCLUDING
;
1445 void lcl_ensureRange0to1( double& rValue
)
1454 bool DiagramHelper::setDiagramPositioning( const uno::Reference
< frame::XModel
>& xChartModel
,
1455 const awt::Rectangle
& rPosRect
/*100th mm*/ )
1457 ControllerLockGuard
aCtrlLockGuard( xChartModel
);
1459 bool bChanged
= false;
1460 awt::Size
aPageSize( ChartModelHelper::getPageSize(xChartModel
) );
1461 uno::Reference
< beans::XPropertySet
> xDiaProps( ChartModelHelper::findDiagram( xChartModel
), uno::UNO_QUERY
);
1462 if( !xDiaProps
.is() )
1465 RelativePosition aOldPos
;
1466 RelativeSize aOldSize
;
1467 xDiaProps
->getPropertyValue(C2U("RelativePosition") ) >>= aOldPos
;
1468 xDiaProps
->getPropertyValue(C2U("RelativeSize") ) >>= aOldSize
;
1470 RelativePosition aNewPos
;
1471 aNewPos
.Anchor
= drawing::Alignment_TOP_LEFT
;
1472 aNewPos
.Primary
= double(rPosRect
.X
)/double(aPageSize
.Width
);
1473 aNewPos
.Secondary
= double(rPosRect
.Y
)/double(aPageSize
.Height
);
1475 chart2::RelativeSize aNewSize
;
1476 aNewSize
.Primary
= double(rPosRect
.Width
)/double(aPageSize
.Width
);
1477 aNewSize
.Secondary
= double(rPosRect
.Height
)/double(aPageSize
.Height
);
1479 lcl_ensureRange0to1( aNewPos
.Primary
);
1480 lcl_ensureRange0to1( aNewPos
.Secondary
);
1481 lcl_ensureRange0to1( aNewSize
.Primary
);
1482 lcl_ensureRange0to1( aNewSize
.Secondary
);
1483 if( (aNewPos
.Primary
+ aNewSize
.Primary
) > 1.0 )
1484 aNewPos
.Primary
= 1.0 - aNewSize
.Primary
;
1485 if( (aNewPos
.Secondary
+ aNewSize
.Secondary
) > 1.0 )
1486 aNewPos
.Secondary
= 1.0 - aNewSize
.Secondary
;
1488 xDiaProps
->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aNewPos
) );
1489 xDiaProps
->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aNewSize
) );
1491 bChanged
= (aOldPos
.Anchor
!=aNewPos
.Anchor
) ||
1492 (aOldPos
.Primary
!=aNewPos
.Primary
) ||
1493 (aOldPos
.Secondary
!=aNewPos
.Secondary
) ||
1494 (aOldSize
.Primary
!=aNewSize
.Primary
) ||
1495 (aOldSize
.Secondary
!=aNewSize
.Secondary
);
1500 awt::Rectangle
DiagramHelper::getDiagramRectangleFromModel( const uno::Reference
< frame::XModel
>& xChartModel
)
1502 awt::Rectangle
aRet(-1,-1,-1,-1);
1504 uno::Reference
< beans::XPropertySet
> xDiaProps( ChartModelHelper::findDiagram( xChartModel
), uno::UNO_QUERY
);
1505 if( !xDiaProps
.is() )
1508 awt::Size
aPageSize( ChartModelHelper::getPageSize(xChartModel
) );
1510 RelativePosition aRelPos
;
1511 RelativeSize aRelSize
;
1512 xDiaProps
->getPropertyValue(C2U("RelativePosition") ) >>= aRelPos
;
1513 xDiaProps
->getPropertyValue(C2U("RelativeSize") ) >>= aRelSize
;
1516 aRelSize
.Primary
* aPageSize
.Width
,
1517 aRelSize
.Secondary
* aPageSize
.Height
);
1520 static_cast< sal_Int32
>( aRelPos
.Primary
* aPageSize
.Width
),
1521 static_cast< sal_Int32
>( aRelPos
.Secondary
* aPageSize
.Height
));
1523 awt::Point aAbsPosLeftTop
= RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos
, aAbsSize
, aRelPos
.Anchor
);
1525 aRet
= awt::Rectangle(aAbsPosLeftTop
.X
, aAbsPosLeftTop
.Y
, aAbsSize
.Width
, aAbsSize
.Height
);
1531 bool DiagramHelper::switchDiagramPositioningToExcludingPositioning(
1532 const uno::Reference
< frame::XModel
>& xChartModel
1533 , bool bResetModifiedState
, bool bConvertAlsoFromAutoPositioning
)
1535 //return true if something was changed
1536 const SvtSaveOptions::ODFDefaultVersion
nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1537 if( nCurrentODFVersion
== SvtSaveOptions::ODFVER_LATEST
)//#i100778# todo: change this dependent on fileformat evolution
1539 uno::Reference
< ::com::sun::star::chart::XChartDocument
> xOldDoc( xChartModel
, uno::UNO_QUERY
) ;
1542 uno::Reference
< ::com::sun::star::chart::XDiagramPositioning
> xDiagramPositioning( xOldDoc
->getDiagram(), uno::UNO_QUERY
);
1543 if( xDiagramPositioning
.is() && ( bConvertAlsoFromAutoPositioning
|| !xDiagramPositioning
->isAutomaticDiagramPositioning() )
1544 && !xDiagramPositioning
->isExcludingDiagramPositioning() )
1546 ControllerLockGuard
aCtrlLockGuard( xChartModel
);
1547 uno::Reference
< util::XModifiable
> xModifiable( xChartModel
, uno::UNO_QUERY
);
1548 bool bModelWasModified
= xModifiable
.is() && xModifiable
->isModified();
1549 xDiagramPositioning
->setDiagramPositionExcludingAxes( xDiagramPositioning
->calculateDiagramPositionExcludingAxes() );
1550 if(bResetModifiedState
&& !bModelWasModified
&& xModifiable
.is() )
1551 xModifiable
->setModified(sal_False
);
1559 } // namespace chart