summaryrefslogtreecommitdiff
path: root/chart2/source/tools
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/tools')
-rw-r--r--chart2/source/tools/AxisHelper.cxx976
-rw-r--r--chart2/source/tools/BaseGFXHelper.cxx222
-rw-r--r--chart2/source/tools/CachedDataSequence.cxx409
-rw-r--r--chart2/source/tools/CharacterProperties.cxx608
-rw-r--r--chart2/source/tools/ChartDebugTrace.cxx417
-rw-r--r--chart2/source/tools/ChartModelHelper.cxx267
-rw-r--r--chart2/source/tools/ChartTypeHelper.cxx685
-rw-r--r--chart2/source/tools/ChartViewHelper.cxx72
-rw-r--r--chart2/source/tools/ColorPerPointHelper.cxx97
-rw-r--r--chart2/source/tools/CommonConverters.cxx549
-rw-r--r--chart2/source/tools/ConfigColorScheme.cxx202
-rw-r--r--chart2/source/tools/ControllerLockGuard.cxx89
-rw-r--r--chart2/source/tools/DataSeriesHelper.cxx918
-rw-r--r--chart2/source/tools/DataSource.cxx91
-rw-r--r--chart2/source/tools/DataSourceHelper.cxx552
-rw-r--r--chart2/source/tools/DiagramHelper.cxx1559
-rw-r--r--chart2/source/tools/ErrorBar.cxx363
-rw-r--r--chart2/source/tools/ExplicitCategoriesProvider.cxx422
-rw-r--r--chart2/source/tools/ExponentialRegressionCurveCalculator.cxx183
-rw-r--r--chart2/source/tools/FillProperties.cxx277
-rw-r--r--chart2/source/tools/FormattedStringHelper.cxx80
-rw-r--r--chart2/source/tools/ImplOPropertySet.cxx207
-rw-r--r--chart2/source/tools/ImplOPropertySet.hxx96
-rwxr-xr-xchart2/source/tools/InternalData.cxx530
-rw-r--r--chart2/source/tools/InternalDataProvider.cxx1314
-rw-r--r--chart2/source/tools/LabeledDataSequence.cxx179
-rw-r--r--chart2/source/tools/LegendHelper.cxx147
-rw-r--r--chart2/source/tools/LifeTime.cxx546
-rw-r--r--chart2/source/tools/LineProperties.cxx185
-rw-r--r--chart2/source/tools/LinearRegressionCurveCalculator.cxx179
-rw-r--r--chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx191
-rw-r--r--chart2/source/tools/MeanValueRegressionCurveCalculator.cxx143
-rw-r--r--chart2/source/tools/MediaDescriptorHelper.cxx221
-rw-r--r--chart2/source/tools/ModifyListenerCallBack.cxx134
-rw-r--r--chart2/source/tools/ModifyListenerHelper.cxx213
-rw-r--r--chart2/source/tools/MutexContainer.cxx43
-rw-r--r--chart2/source/tools/NameContainer.cxx189
-rw-r--r--chart2/source/tools/NamedFillProperties.cxx114
-rw-r--r--chart2/source/tools/NamedLineProperties.cxx99
-rw-r--r--chart2/source/tools/NamedProperties.cxx59
-rw-r--r--chart2/source/tools/OPropertySet.cxx530
-rw-r--r--chart2/source/tools/ObjectIdentifier.cxx1491
-rw-r--r--chart2/source/tools/PotentialRegressionCurveCalculator.cxx177
-rw-r--r--chart2/source/tools/PropertyHelper.cxx314
-rw-r--r--chart2/source/tools/RangeHighlighter.cxx406
-rw-r--r--chart2/source/tools/ReferenceSizeProvider.cxx378
-rw-r--r--chart2/source/tools/RegressionCalculationHelper.hxx131
-rw-r--r--chart2/source/tools/RegressionCurveCalculator.cxx168
-rw-r--r--chart2/source/tools/RegressionCurveHelper.cxx736
-rw-r--r--chart2/source/tools/RegressionCurveModel.cxx441
-rw-r--r--chart2/source/tools/RegressionCurveModel.hxx259
-rw-r--r--chart2/source/tools/RegressionEquation.cxx362
-rw-r--r--chart2/source/tools/RegressionEquation.hxx143
-rw-r--r--chart2/source/tools/RelativePositionHelper.cxx399
-rw-r--r--chart2/source/tools/RelativeSizeHelper.cxx100
-rw-r--r--chart2/source/tools/ResId.cxx47
-rw-r--r--chart2/source/tools/RessourceManager.cxx49
-rw-r--r--chart2/source/tools/Scaling.cxx271
-rw-r--r--chart2/source/tools/SceneProperties.cxx382
-rw-r--r--chart2/source/tools/StatisticsHelper.cxx403
-rw-r--r--chart2/source/tools/ThreeDHelper.cxx1527
-rw-r--r--chart2/source/tools/TitleHelper.cxx378
-rw-r--r--chart2/source/tools/TrueGuard.cxx47
-rw-r--r--chart2/source/tools/UncachedDataSequence.cxx379
-rw-r--r--chart2/source/tools/UserDefinedProperties.cxx73
-rw-r--r--chart2/source/tools/WeakListenerAdapter.cxx76
-rw-r--r--chart2/source/tools/WrappedDefaultProperty.cxx92
-rw-r--r--chart2/source/tools/WrappedDirectStateProperty.cxx59
-rw-r--r--chart2/source/tools/WrappedIgnoreProperty.cxx148
-rw-r--r--chart2/source/tools/WrappedProperty.cxx150
-rw-r--r--chart2/source/tools/WrappedPropertySet.cxx495
-rw-r--r--chart2/source/tools/XMLRangeHelper.cxx418
-rw-r--r--chart2/source/tools/_serviceregistration_tools.cxx200
-rw-r--r--chart2/source/tools/exports.flt3
-rw-r--r--chart2/source/tools/makefile.mk189
75 files changed, 25248 insertions, 0 deletions
diff --git a/chart2/source/tools/AxisHelper.cxx b/chart2/source/tools/AxisHelper.cxx
new file mode 100644
index 000000000000..8cdd24e4dc05
--- /dev/null
+++ b/chart2/source/tools/AxisHelper.cxx
@@ -0,0 +1,976 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "AxisHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "ChartTypeHelper.hxx"
+#include "macros.hxx"
+#include "AxisIndexDefines.hxx"
+#include "LineProperties.hxx"
+#include "ContainerHelper.hxx"
+#include "servicenames_coosystems.hxx"
+#include "DataSeriesHelper.hxx"
+#include "Scaling.hxx"
+
+#include <unotools/saveopt.hxx>
+
+#include <com/sun/star/chart/ChartAxisPosition.hpp>
+
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+
+// header for class OUStringBuffer
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+
+#include <map>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+
+//static
+Reference< chart2::XScaling > AxisHelper::createLinearScaling()
+{
+ return new LinearScaling( 1.0, 0.0 );
+}
+
+//static
+Reference< chart2::XScaling > AxisHelper::createLogarithmicScaling( double fBase )
+{
+ return new LogarithmicScaling( fBase );
+}
+
+//static
+ScaleData AxisHelper::createDefaultScale()
+{
+ ScaleData aScaleData;
+ aScaleData.AxisType = chart2::AxisType::REALNUMBER;
+ Sequence< SubIncrement > aSubIncrements(1);
+ aSubIncrements[0] = SubIncrement();
+ aScaleData.IncrementData.SubIncrements = aSubIncrements;
+ return aScaleData;
+}
+
+//static
+void AxisHelper::removeExplicitScaling( ScaleData& rScaleData )
+{
+ uno::Any aEmpty;
+ rScaleData.Minimum = rScaleData.Maximum = rScaleData.Origin = aEmpty;
+ rScaleData.Scaling = 0;
+}
+
+//static
+bool AxisHelper::isLogarithmic( const Reference< XScaling >& xScaling )
+{
+ bool bReturn = false;
+ Reference< lang::XServiceName > xServiceName( xScaling, uno::UNO_QUERY );
+ bReturn =( xServiceName.is() && (xServiceName->getServiceName()).equals(
+ C2U( "com.sun.star.chart2.LogarithmicScaling" )));
+ return bReturn;
+}
+
+//static
+Reference< XAxis > AxisHelper::createAxis(
+ sal_Int32 nDimensionIndex
+ , sal_Int32 nAxisIndex // 0==main or 1==secondary axis
+ , const Reference< XCoordinateSystem >& xCooSys
+ , const Reference< uno::XComponentContext > & xContext
+ , ReferenceSizeProvider * pRefSizeProvider )
+{
+ if( !xContext.is() || !xCooSys.is() )
+ return NULL;
+ if( nDimensionIndex >= xCooSys->getDimension() )
+ return NULL;
+
+ Reference< XAxis > xAxis( xContext->getServiceManager()->createInstanceWithContext(
+ C2U( "com.sun.star.chart2.Axis" ), xContext ), uno::UNO_QUERY );
+
+ OSL_ASSERT( xAxis.is());
+ if( xAxis.is())
+ {
+ xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex );
+
+ if( nAxisIndex>0 )//when inserting secondary axes copy some things from the main axis
+ {
+ ::com::sun::star::chart::ChartAxisPosition eNewAxisPos( ::com::sun::star::chart::ChartAxisPosition_END );
+
+ Reference< XAxis > xMainAxis( xCooSys->getAxisByDimension( nDimensionIndex, 0 ) );
+ if( xMainAxis.is() )
+ {
+ ScaleData aScale = xAxis->getScaleData();
+ ScaleData aMainScale = xMainAxis->getScaleData();
+
+ aScale.AxisType = aMainScale.AxisType;
+ aScale.Categories = aMainScale.Categories;
+ aScale.Orientation = aMainScale.Orientation;
+
+ xAxis->setScaleData( aScale );
+
+ //ensure that the second axis is not placed on the main axis
+ Reference< beans::XPropertySet > xMainProp( xMainAxis, uno::UNO_QUERY );
+ if( xMainProp.is() )
+ {
+ ::com::sun::star::chart::ChartAxisPosition eMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
+ xMainProp->getPropertyValue(C2U( "CrossoverPosition" )) >>= eMainAxisPos;
+ if( ::com::sun::star::chart::ChartAxisPosition_END == eMainAxisPos )
+ eNewAxisPos = ::com::sun::star::chart::ChartAxisPosition_START;
+ }
+ }
+
+ Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
+ if( xProp.is() )
+ xProp->setPropertyValue(C2U( "CrossoverPosition" ), uno::makeAny(eNewAxisPos) );
+ }
+
+ Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
+ if( xProp.is() ) try
+ {
+ // set correct initial AutoScale
+ if( pRefSizeProvider )
+ pRefSizeProvider->setValuesAtPropertySet( xProp );
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ return xAxis;
+}
+
+//static
+Reference< XAxis > AxisHelper::createAxis( sal_Int32 nDimensionIndex, bool bMainAxis
+ , const Reference< chart2::XDiagram >& xDiagram
+ , const Reference< uno::XComponentContext >& xContext
+ , ReferenceSizeProvider * pRefSizeProvider )
+{
+ OSL_ENSURE( xContext.is(), "need a context to create an axis" );
+ if( !xContext.is() )
+ return NULL;
+
+ sal_Int32 nAxisIndex = bMainAxis ? MAIN_AXIS_INDEX : SECONDARY_AXIS_INDEX;
+ sal_Int32 nCooSysIndex = 0;
+ Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
+
+ // create axis
+ return AxisHelper::createAxis(
+ nDimensionIndex, nAxisIndex, xCooSys, xContext, pRefSizeProvider );
+}
+
+//static
+void AxisHelper::showAxis( sal_Int32 nDimensionIndex, bool bMainAxis
+ , const Reference< chart2::XDiagram >& xDiagram
+ , const Reference< uno::XComponentContext >& xContext
+ , ReferenceSizeProvider * pRefSizeProvider )
+{
+ if( !xDiagram.is() )
+ return;
+
+ bool bNewAxisCreated = false;
+ Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
+ if( !xAxis.is() && xContext.is() )
+ {
+ // create axis
+ bNewAxisCreated = true;
+ xAxis.set( AxisHelper::createAxis( nDimensionIndex, bMainAxis, xDiagram, xContext, pRefSizeProvider ) );
+ }
+
+ OSL_ASSERT( xAxis.is());
+ if( !bNewAxisCreated ) //default is true already if created
+ AxisHelper::makeAxisVisible( xAxis );
+}
+
+//static
+void AxisHelper::showGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
+ , const Reference< XDiagram >& xDiagram
+ , const Reference< uno::XComponentContext >& /*xContext*/ )
+{
+ if( !xDiagram.is() )
+ return;
+
+ Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
+ if(!xCooSys.is())
+ return;
+
+ Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
+ if(!xAxis.is())
+ {
+ //hhhh todo create axis without axis visibility
+ }
+ if(!xAxis.is())
+ return;
+
+ if( bMainGrid )
+ AxisHelper::makeGridVisible( xAxis->getGridProperties() );
+ else
+ {
+ Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
+ for( sal_Int32 nN=0; nN<aSubGrids.getLength(); nN++)
+ AxisHelper::makeGridVisible( aSubGrids[nN] );
+ }
+}
+
+//static
+void AxisHelper::makeAxisVisible( const Reference< XAxis >& xAxis )
+{
+ Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_True ) );
+ LineProperties::SetLineVisible( xProps );
+ xProps->setPropertyValue( C2U( "DisplayLabels" ), uno::makeAny( sal_True ) );
+ }
+}
+
+//static
+void AxisHelper::makeGridVisible( const Reference< beans::XPropertySet >& xGridProperties )
+{
+ if( xGridProperties.is() )
+ {
+ xGridProperties->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_True ) );
+ LineProperties::SetLineVisible( xGridProperties );
+ }
+}
+
+//static
+void AxisHelper::hideAxis( sal_Int32 nDimensionIndex, bool bMainAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
+}
+
+//static
+void AxisHelper::makeAxisInvisible( const Reference< XAxis >& xAxis )
+{
+ Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
+ }
+}
+
+//static
+void AxisHelper::hideAxisIfNoDataIsAttached( const Reference< XAxis >& xAxis, const Reference< XDiagram >& xDiagram )
+{
+ //axis is hidden if no data is attached anymore but data is available
+ bool bOtherSeriesAttachedToThisAxis = false;
+ ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt = aSeriesVector.begin();
+ for( ; aIt != aSeriesVector.end(); ++aIt)
+ {
+ uno::Reference< chart2::XAxis > xCurrentAxis( DiagramHelper::getAttachedAxis( *aIt, xDiagram ), uno::UNO_QUERY );
+ if( xCurrentAxis==xAxis )
+ {
+ bOtherSeriesAttachedToThisAxis = true;
+ break;
+ }
+ }
+ if(!bOtherSeriesAttachedToThisAxis && !aSeriesVector.empty() )
+ AxisHelper::makeAxisInvisible( xAxis );
+}
+
+void AxisHelper::hideGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
+ , const Reference< XDiagram >& xDiagram )
+{
+ if( !xDiagram.is() )
+ return;
+
+ Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
+ if(!xCooSys.is())
+ return;
+
+ Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
+ if(!xAxis.is())
+ return;
+
+ if( bMainGrid )
+ AxisHelper::makeGridInvisible( xAxis->getGridProperties() );
+ else
+ {
+ Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
+ for( sal_Int32 nN=0; nN<aSubGrids.getLength(); nN++)
+ AxisHelper::makeGridInvisible( aSubGrids[nN] );
+ }
+}
+
+//static
+void AxisHelper::makeGridInvisible( const Reference< beans::XPropertySet >& xGridProperties )
+{
+ if( xGridProperties.is() )
+ {
+ xGridProperties->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
+ }
+}
+
+sal_Bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
+ , const Reference< ::com::sun::star::chart2::XDiagram >& xDiagram )
+{
+ sal_Bool bRet = false;
+
+ Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
+ if(!xCooSys.is())
+ return bRet;
+
+ Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
+ if(!xAxis.is())
+ return bRet;
+
+ if( bMainGrid )
+ bRet = AxisHelper::isGridVisible( xAxis->getGridProperties() );
+ else
+ {
+ Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
+ if( aSubGrids.getLength() )
+ bRet = AxisHelper::isGridVisible( aSubGrids[0] );
+ }
+
+ return bRet;
+}
+
+//static
+Reference< XCoordinateSystem > AxisHelper::getCoordinateSystemByIndex(
+ const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
+{
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if(!xCooSysContainer.is())
+ return NULL;
+ Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
+ if(0<=nIndex && nIndex<aCooSysList.getLength())
+ return aCooSysList[nIndex];
+ return NULL;
+}
+
+//static
+Reference< XAxis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, bool bMainAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ Reference< XAxis > xRet;
+ try
+ {
+ Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 );
+ xRet.set( AxisHelper::getAxis( nDimensionIndex, bMainAxis ? 0 : 1, xCooSys ) );
+ }
+ catch( const uno::Exception & )
+ {
+ }
+ return xRet;
+}
+
+//static
+Reference< XAxis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex
+ , const Reference< XCoordinateSystem >& xCooSys )
+{
+ Reference< XAxis > xRet;
+ try
+ {
+ if( xCooSys.is() )
+ xRet.set( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
+ }
+ catch( const uno::Exception & )
+ {
+ }
+ return xRet;
+}
+
+//static
+Reference< XAxis > AxisHelper::getCrossingMainAxis( const Reference< XAxis >& xAxis
+ , const Reference< XCoordinateSystem >& xCooSys )
+{
+ sal_Int32 nDimensionIndex = 0;
+ sal_Int32 nAxisIndex = 0;
+ AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
+ if( 2==nDimensionIndex )
+ {
+ nDimensionIndex=1;
+ bool bSwapXY = false;
+ Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
+ if( xCooSysProp.is() && (xCooSysProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bSwapXY) && bSwapXY )
+ nDimensionIndex=0;
+ }
+ else if( 1==nDimensionIndex )
+ nDimensionIndex=0;
+ else
+ nDimensionIndex=1;
+ return AxisHelper::getAxis( nDimensionIndex, 0, xCooSys );
+}
+
+//static
+Reference< XAxis > AxisHelper::getParallelAxis( const Reference< XAxis >& xAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ try
+ {
+ sal_Int32 nCooSysIndex=-1;
+ sal_Int32 nDimensionIndex=-1;
+ sal_Int32 nAxisIndex=-1;
+ if( getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ) )
+ {
+ sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1;
+ return getAxis( nDimensionIndex, nParallelAxisIndex, getCoordinateSystemByIndex( xDiagram, nCooSysIndex ) );
+ }
+ }
+ catch( uno::RuntimeException& )
+ {
+ }
+ return 0;
+}
+
+sal_Bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex, bool bMainAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
+}
+
+//static
+sal_Bool AxisHelper::isAxisVisible( const Reference< XAxis >& xAxis )
+{
+ sal_Bool bRet = false;
+
+ Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ xProps->getPropertyValue( C2U( "Show" ) ) >>= bRet;
+ bRet = bRet && ( LineProperties::IsLineVisible( xProps )
+ || areAxisLabelsVisible( xProps ) );
+ }
+
+ return bRet;
+}
+
+sal_Bool AxisHelper::areAxisLabelsVisible( const Reference< beans::XPropertySet >& xAxisProperties )
+{
+ sal_Bool bRet = false;
+ if( xAxisProperties.is() )
+ {
+ xAxisProperties->getPropertyValue( C2U( "DisplayLabels" ) ) >>= bRet;
+ }
+ return bRet;
+}
+
+//static
+sal_Bool AxisHelper::isGridVisible( const Reference< beans::XPropertySet >& xGridProperies )
+{
+ sal_Bool bRet = false;
+
+ if( xGridProperies.is() )
+ {
+ xGridProperies->getPropertyValue( C2U( "Show" ) ) >>= bRet;
+ bRet = bRet && LineProperties::IsLineVisible( xGridProperies );
+ }
+
+ return bRet;
+}
+
+//static
+Reference< beans::XPropertySet > AxisHelper::getGridProperties(
+ const Reference< XCoordinateSystem >& xCooSys
+ , sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex, sal_Int32 nSubGridIndex )
+{
+ Reference< beans::XPropertySet > xRet;
+
+ Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys ) );
+ if( xAxis.is() )
+ {
+ if( nSubGridIndex<0 )
+ xRet.set( xAxis->getGridProperties() );
+ else
+ {
+ Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
+ if( nSubGridIndex >= 0 && nSubGridIndex < aSubGrids.getLength() )
+ xRet.set( aSubGrids[nSubGridIndex] );
+ }
+ }
+
+ return xRet;
+}
+
+//static
+sal_Int32 AxisHelper::getDimensionIndexOfAxis(
+ const Reference< XAxis >& xAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ sal_Int32 nDimensionIndex = -1;
+ sal_Int32 nCooSysIndex = -1;
+ sal_Int32 nAxisIndex = -1;
+ AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex , nDimensionIndex, nAxisIndex );
+ return nDimensionIndex;
+}
+
+//static
+bool AxisHelper::getIndicesForAxis(
+ const Reference< XAxis >& xAxis
+ , const Reference< XCoordinateSystem >& xCooSys
+ , sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
+{
+ //returns true if indices are found
+
+ rOutDimensionIndex = -1;
+ rOutAxisIndex = -1;
+
+ if( xCooSys.is() && xAxis.is() )
+ {
+ Reference< XAxis > xCurrentAxis;
+ sal_Int32 nDimensionCount( xCooSys->getDimension() );
+ for( sal_Int32 nDimensionIndex = 0; nDimensionIndex < nDimensionCount; nDimensionIndex++ )
+ {
+ sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
+ for( sal_Int32 nAxisIndex = 0; nAxisIndex <= nMaxAxisIndex; nAxisIndex++ )
+ {
+ xCurrentAxis = xCooSys->getAxisByDimension(nDimensionIndex,nAxisIndex);
+ if( xCurrentAxis == xAxis )
+ {
+ rOutDimensionIndex = nDimensionIndex;
+ rOutAxisIndex = nAxisIndex;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+//static
+bool AxisHelper::getIndicesForAxis( const Reference< XAxis >& xAxis, const Reference< XDiagram >& xDiagram
+ , sal_Int32& rOutCooSysIndex, sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
+{
+ //returns true if indices are found
+
+ rOutCooSysIndex = -1;
+ rOutDimensionIndex = -1;
+ rOutAxisIndex = -1;
+
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if(xCooSysContainer.is())
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
+ for( sal_Int32 nC=0; nC<aCooSysList.getLength(); ++nC )
+ {
+ if( AxisHelper::getIndicesForAxis( xAxis, aCooSysList[nC], rOutDimensionIndex, rOutAxisIndex ) )
+ {
+ rOutCooSysIndex = nC;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//static
+std::vector< Reference< XAxis > > AxisHelper::getAllAxesOfCoordinateSystem(
+ const Reference< XCoordinateSystem >& xCooSys
+ , bool bOnlyVisible /* = false */ )
+{
+ std::vector< Reference< XAxis > > aAxisVector;
+
+ if(xCooSys.is())
+ {
+ sal_Int32 nDimensionIndex = 0;
+ sal_Int32 nMaxDimensionIndex = xCooSys->getDimension() -1;
+ if( nMaxDimensionIndex>=0 )
+ {
+ for(nDimensionIndex=0; nDimensionIndex<=nMaxDimensionIndex; ++nDimensionIndex)
+ {
+ const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
+ for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
+ {
+ try
+ {
+ Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
+ bool bAddAxis = true;
+ if( xAxis.is() )
+ {
+ if( bOnlyVisible )
+ {
+ Reference< beans::XPropertySet > xAxisProp( xAxis, uno::UNO_QUERY );
+ if( !xAxisProp.is() ||
+ !(xAxisProp->getPropertyValue( C2U("Show")) >>= bAddAxis) )
+ bAddAxis = false;
+ }
+ if( bAddAxis )
+ aAxisVector.push_back( xAxis );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+ }
+ }
+
+ return aAxisVector;
+}
+
+//static
+Sequence< Reference< XAxis > > AxisHelper::getAllAxesOfDiagram(
+ const Reference< XDiagram >& xDiagram
+ , bool bOnlyVisible )
+{
+ std::vector< Reference< XAxis > > aAxisVector;
+
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if(xCooSysContainer.is())
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
+ sal_Int32 nC = 0;
+ for( nC=0; nC<aCooSysList.getLength(); ++nC )
+ {
+ std::vector< Reference< XAxis > > aAxesPerCooSys( AxisHelper::getAllAxesOfCoordinateSystem( aCooSysList[nC], bOnlyVisible ) );
+ aAxisVector.insert( aAxisVector.end(), aAxesPerCooSys.begin(), aAxesPerCooSys.end() );
+ }
+ }
+
+ return ContainerHelper::ContainerToSequence( aAxisVector );
+}
+
+//static
+Sequence< Reference< beans::XPropertySet > > AxisHelper::getAllGrids( const Reference< XDiagram >& xDiagram )
+{
+ Sequence< Reference< XAxis > > aAllAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
+ std::vector< Reference< beans::XPropertySet > > aGridVector;
+
+ sal_Int32 nA = 0;
+ for( nA=0; nA<aAllAxes.getLength(); ++nA )
+ {
+ Reference< XAxis > xAxis( aAllAxes[nA] );
+ if(!xAxis.is())
+ continue;
+ Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
+ if( xGridProperties.is() )
+ aGridVector.push_back( xGridProperties );
+
+ Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
+ sal_Int32 nSubGrid = 0;
+ for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
+ {
+ Reference< beans::XPropertySet > xSubGrid( aSubGrids[nSubGrid] );
+ if( xSubGrid.is() )
+ aGridVector.push_back( xSubGrid );
+ }
+ }
+
+ return ContainerHelper::ContainerToSequence( aGridVector );
+}
+
+//static
+void AxisHelper::getAxisOrGridPossibilities( Sequence< sal_Bool >& rPossibilityList
+ , const Reference< XDiagram>& xDiagram, sal_Bool bAxis )
+{
+ rPossibilityList.realloc(6);
+
+ sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
+
+ //set possibilities:
+ sal_Int32 nIndex=0;
+ Reference< XChartType > xChartType = DiagramHelper::getChartTypeByIndex( xDiagram, 0 );
+ for(nIndex=0;nIndex<3;nIndex++)
+ rPossibilityList[nIndex]=ChartTypeHelper::isSupportingMainAxis(xChartType,nDimensionCount,nIndex);
+ for(nIndex=3;nIndex<6;nIndex++)
+ if( bAxis )
+ rPossibilityList[nIndex]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType,nDimensionCount,nIndex-3);
+ else
+ rPossibilityList[nIndex] = rPossibilityList[nIndex-3];
+}
+
+//static
+bool AxisHelper::isSecondaryYAxisNeeded( const Reference< XCoordinateSystem >& xCooSys )
+{
+ Reference< chart2::XChartTypeContainer > xCTCnt( xCooSys, uno::UNO_QUERY );
+ if( xCTCnt.is() )
+ {
+ Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes() );
+ for( sal_Int32 i=0; i<aChartTypes.getLength(); ++i )
+ {
+ Reference< XDataSeriesContainer > xSeriesContainer( aChartTypes[i] , uno::UNO_QUERY );
+ if( !xSeriesContainer.is() )
+ continue;
+
+ Sequence< Reference< XDataSeries > > aSeriesList( xSeriesContainer->getDataSeries() );
+ for( sal_Int32 nS = aSeriesList.getLength(); nS-- ; )
+ {
+ Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
+ if(xProp.is())
+ {
+ sal_Int32 nAttachedAxisIndex = 0;
+ if( ( xProp->getPropertyValue( C2U( "AttachedAxisIndex" ) ) >>= nAttachedAxisIndex ) && nAttachedAxisIndex>0 )
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+//static
+bool AxisHelper::shouldAxisBeDisplayed( const Reference< XAxis >& xAxis
+ , const Reference< XCoordinateSystem >& xCooSys )
+{
+ bool bRet = false;
+
+ if( xAxis.is() && xCooSys.is() )
+ {
+ sal_Int32 nDimensionIndex=-1;
+ sal_Int32 nAxisIndex=-1;
+ if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
+ {
+ sal_Int32 nDimensionCount = xCooSys->getDimension();
+ Reference< XChartType > xChartType( AxisHelper::getChartTypeByIndex( xCooSys, 0 ) );
+
+ bool bMainAxis = (nAxisIndex==MAIN_AXIS_INDEX);
+ if( bMainAxis )
+ bRet = ChartTypeHelper::isSupportingMainAxis(xChartType,nDimensionCount,nDimensionIndex);
+ else
+ bRet = ChartTypeHelper::isSupportingSecondaryAxis(xChartType,nDimensionCount,nDimensionIndex);
+ }
+ }
+
+ return bRet;
+}
+
+//static
+void AxisHelper::getAxisOrGridExcistence( Sequence< sal_Bool >& rExistenceList
+ , const Reference< XDiagram>& xDiagram, sal_Bool bAxis )
+{
+ rExistenceList.realloc(6);
+
+ if(bAxis)
+ {
+ sal_Int32 nN;
+ Reference< XAxis > xAxis;
+ for(nN=0;nN<3;nN++)
+ rExistenceList[nN] = AxisHelper::isAxisShown( nN, true, xDiagram );
+ for(nN=3;nN<6;nN++)
+ rExistenceList[nN] = AxisHelper::isAxisShown( nN%3, false, xDiagram );
+ }
+ else
+ {
+ sal_Int32 nN;
+
+ for(nN=0;nN<3;nN++)
+ rExistenceList[nN] = AxisHelper::isGridShown( nN, 0, true, xDiagram );
+ for(nN=3;nN<6;nN++)
+ rExistenceList[nN] = AxisHelper::isGridShown( nN%3, 0, false, xDiagram );
+ }
+}
+
+//static
+bool AxisHelper::changeVisibilityOfAxes( const Reference< XDiagram >& xDiagram
+ , const Sequence< sal_Bool >& rOldExistenceList
+ , const Sequence< sal_Bool >& rNewExistenceList
+ , const Reference< uno::XComponentContext >& xContext
+ , ReferenceSizeProvider * pRefSizeProvider )
+{
+ bool bChanged = false;
+ for(sal_Int32 nN=0;nN<6;nN++)
+ {
+ if(rOldExistenceList[nN]!=rNewExistenceList[nN])
+ {
+ bChanged = true;
+ if(rNewExistenceList[nN])
+ {
+ AxisHelper::showAxis( nN%3, nN<3, xDiagram, xContext, pRefSizeProvider );
+ }
+ else
+ AxisHelper::hideAxis( nN%3, nN<3, xDiagram );
+ }
+ }
+ return bChanged;
+}
+
+//static
+bool AxisHelper::changeVisibilityOfGrids( const Reference< XDiagram >& xDiagram
+ , const Sequence< sal_Bool >& rOldExistenceList
+ , const Sequence< sal_Bool >& rNewExistenceList
+ , const Reference< uno::XComponentContext >& xContext )
+{
+ bool bChanged = false;
+ for(sal_Int32 nN=0;nN<6;nN++)
+ {
+ if(rOldExistenceList[nN]!=rNewExistenceList[nN])
+ {
+ bChanged = true;
+ if(rNewExistenceList[nN])
+ AxisHelper::showGrid( nN%3, 0, nN<3, xDiagram, xContext );
+ else
+ AxisHelper::hideGrid( nN%3, 0, nN<3, xDiagram );
+ }
+ }
+ return bChanged;
+}
+
+//static
+Reference< XCoordinateSystem > AxisHelper::getCoordinateSystemOfAxis(
+ const Reference< XAxis >& xAxis
+ , const Reference< XDiagram >& xDiagram )
+{
+ Reference< XCoordinateSystem > xRet;
+
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( xCooSysContainer.is() )
+ {
+ Reference< XCoordinateSystem > xCooSys;
+ Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCooSysIndex = 0; nCooSysIndex < aCooSysList.getLength(); ++nCooSysIndex )
+ {
+ xCooSys = aCooSysList[nCooSysIndex];
+ std::vector< Reference< XAxis > > aAllAxis( AxisHelper::getAllAxesOfCoordinateSystem( xCooSys ) );
+
+ ::std::vector< Reference< XAxis > >::iterator aFound =
+ ::std::find( aAllAxis.begin(), aAllAxis.end(), xAxis );
+ if( aFound != aAllAxis.end())
+ {
+ xRet.set( xCooSys );
+ break;
+ }
+ }
+ }
+ return xRet;
+}
+
+Reference< XChartType > AxisHelper::getChartTypeByIndex( const Reference< XCoordinateSystem >& xCooSys, sal_Int32 nIndex )
+{
+ Reference< XChartType > xChartType;
+
+ Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
+ if( xChartTypeContainer.is() )
+ {
+ Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ if( nIndex >= 0 && nIndex < aChartTypeList.getLength() )
+ xChartType.set( aChartTypeList[nIndex] );
+ }
+
+ return xChartType;
+}
+
+void AxisHelper::setRTLAxisLayout( const Reference< XCoordinateSystem >& xCooSys )
+{
+ if( xCooSys.is() )
+ {
+ bool bCartesian = xCooSys->getViewServiceName().equals( CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME );
+ if( bCartesian )
+ {
+ bool bVertical = false;
+ Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
+ if( xCooSysProp.is() )
+ xCooSysProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bVertical;
+
+ sal_Int32 nHorizontalAxisDimension = bVertical ? 1 : 0;
+ sal_Int32 nVerticalAxisDimension = bVertical ? 0 : 1;
+
+ try
+ {
+ //reverse direction for horizontal main axis
+ Reference< chart2::XAxis > xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) );
+ if( xHorizontalMainAxis.is() )
+ {
+ chart2::ScaleData aScale = xHorizontalMainAxis->getScaleData();
+ aScale.Orientation = chart2::AxisOrientation_REVERSE;
+ xHorizontalMainAxis->setScaleData(aScale);
+ }
+
+ //mathematical direction for vertical main axis
+ Reference< chart2::XAxis > xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) );
+ if( xVerticalMainAxis.is() )
+ {
+ chart2::ScaleData aScale = xVerticalMainAxis->getScaleData();
+ aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
+ xVerticalMainAxis->setScaleData(aScale);
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ try
+ {
+ //reverse direction for horizontal secondary axis
+ Reference< chart2::XAxis > xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) );
+ if( xHorizontalSecondaryAxis.is() )
+ {
+ chart2::ScaleData aScale = xHorizontalSecondaryAxis->getScaleData();
+ aScale.Orientation = chart2::AxisOrientation_REVERSE;
+ xHorizontalSecondaryAxis->setScaleData(aScale);
+ }
+
+ //mathematical direction for vertical secondary axis
+ Reference< chart2::XAxis > xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) );
+ if( xVerticalSecondaryAxis.is() )
+ {
+ chart2::ScaleData aScale = xVerticalSecondaryAxis->getScaleData();
+ aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
+ xVerticalSecondaryAxis->setScaleData(aScale);
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+}
+
+Reference< XChartType > AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference< chart2::XDiagram >& xDiagram, const sal_Int32 nAttachedAxisIndex )
+{
+ Reference< XChartType > xChartType;
+ ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin();
+ for( ; aIter != aSeriesVector.end(); aIter++ )
+ {
+ sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter );
+ if( nAttachedAxisIndex == nCurrentIndex )
+ {
+ xChartType = DiagramHelper::getChartTypeOfSeries( xDiagram, *aIter );
+ if(xChartType.is())
+ break;
+ }
+ }
+ return xChartType;
+}
+
+bool AxisHelper::isAxisPositioningEnabled()
+{
+ const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
+ return nCurrentVersion >= SvtSaveOptions::ODFVER_012;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/BaseGFXHelper.cxx b/chart2/source/tools/BaseGFXHelper.cxx
new file mode 100644
index 000000000000..0ec7df9b7d71
--- /dev/null
+++ b/chart2/source/tools/BaseGFXHelper.cxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "BaseGFXHelper.hxx"
+#include <com/sun/star/drawing/DoubleSequence.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::drawing;
+using namespace ::basegfx;
+
+namespace chart
+{
+namespace BaseGFXHelper
+{
+
+::basegfx::B3DRange getBoundVolume( const drawing::PolyPolygonShape3D& rPolyPoly )
+{
+ ::basegfx::B3DRange aRet;
+
+ bool bInited = false;
+ sal_Int32 nPolyCount = rPolyPoly.SequenceX.getLength();
+ for(sal_Int32 nPoly = 0; nPoly < nPolyCount; nPoly++)
+ {
+ sal_Int32 nPointCount = rPolyPoly.SequenceX[nPoly].getLength();
+ for( sal_Int32 nPoint = 0; nPoint < nPointCount; nPoint++)
+ {
+ if(!bInited)
+ {
+ aRet = ::basegfx::B3DRange(::basegfx::B3DTuple(
+ rPolyPoly.SequenceX[nPoly][nPoint]
+ , rPolyPoly.SequenceY[nPoly][nPoint]
+ , rPolyPoly.SequenceZ[nPoly][nPoint]));
+ bInited = true;
+ }
+ else
+ {
+ aRet.expand( ::basegfx::B3DTuple(
+ rPolyPoly.SequenceX[nPoly][nPoint]
+ , rPolyPoly.SequenceY[nPoly][nPoint]
+ , rPolyPoly.SequenceZ[nPoly][nPoint]));
+ }
+ }
+ }
+
+ return aRet;
+}
+
+B2IRectangle makeRectangle( const awt::Point& rPos, const awt::Size& rSize )
+{
+ return B2IRectangle(rPos.X,rPos.Y,rPos.X+rSize.Width,rPos.Y+rSize.Height);
+}
+
+awt::Point B2IRectangleToAWTPoint( const ::basegfx::B2IRectangle& rB2IRectangle )
+{
+ return awt::Point( rB2IRectangle.getMinX(), rB2IRectangle.getMinY() );
+}
+
+awt::Size B2IRectangleToAWTSize( const ::basegfx::B2IRectangle& rB2IRectangle )
+{
+ return awt::Size( static_cast< sal_Int32 >( rB2IRectangle.getWidth()),
+ static_cast< sal_Int32 >( rB2IRectangle.getHeight()));
+}
+
+awt::Rectangle B2IRectangleToAWTRectangle(
+ const ::basegfx::B2IRectangle& rB2IRectangle )
+{
+ return awt::Rectangle( rB2IRectangle.getMinX(), rB2IRectangle.getMinY(),
+ static_cast< sal_Int32 >( rB2IRectangle.getWidth()),
+ static_cast< sal_Int32 >( rB2IRectangle.getHeight()));
+}
+
+B3DVector Direction3DToB3DVector( const Direction3D& rDirection )
+{
+ return B3DVector(
+ rDirection.DirectionX
+ , rDirection.DirectionY
+ , rDirection.DirectionZ
+ );
+}
+
+Direction3D B3DVectorToDirection3D( const B3DVector& rB3DVector )
+{
+ return Direction3D(
+ rB3DVector.getX()
+ , rB3DVector.getY()
+ , rB3DVector.getZ()
+ );
+}
+
+B3DVector Position3DToB3DVector( const Position3D& rPosition )
+{
+ return B3DVector(
+ rPosition.PositionX
+ , rPosition.PositionY
+ , rPosition.PositionZ
+ );
+}
+
+Position3D B3DVectorToPosition3D( const B3DVector& rB3DVector )
+{
+ return Position3D(
+ rB3DVector.getX()
+ , rB3DVector.getY()
+ , rB3DVector.getZ()
+ );
+}
+
+B3DHomMatrix HomogenMatrixToB3DHomMatrix( const HomogenMatrix & rHomogenMatrix )
+{
+ B3DHomMatrix aResult;
+
+ aResult.set( 0, 0, rHomogenMatrix.Line1.Column1 );
+ aResult.set( 0, 1, rHomogenMatrix.Line1.Column2 );
+ aResult.set( 0, 2, rHomogenMatrix.Line1.Column3 );
+ aResult.set( 0, 3, rHomogenMatrix.Line1.Column4 );
+
+ aResult.set( 1, 0, rHomogenMatrix.Line2.Column1 );
+ aResult.set( 1, 1, rHomogenMatrix.Line2.Column2 );
+ aResult.set( 1, 2, rHomogenMatrix.Line2.Column3 );
+ aResult.set( 1, 3, rHomogenMatrix.Line2.Column4 );
+
+ aResult.set( 2, 0, rHomogenMatrix.Line3.Column1 );
+ aResult.set( 2, 1, rHomogenMatrix.Line3.Column2 );
+ aResult.set( 2, 2, rHomogenMatrix.Line3.Column3 );
+ aResult.set( 2, 3, rHomogenMatrix.Line3.Column4 );
+
+ aResult.set( 3, 0, rHomogenMatrix.Line4.Column1 );
+ aResult.set( 3, 1, rHomogenMatrix.Line4.Column2 );
+ aResult.set( 3, 2, rHomogenMatrix.Line4.Column3 );
+ aResult.set( 3, 3, rHomogenMatrix.Line4.Column4 );
+
+ return aResult;
+}
+
+HomogenMatrix B3DHomMatrixToHomogenMatrix( const B3DHomMatrix & rB3DMatrix )
+{
+ HomogenMatrix aResult;
+
+ aResult.Line1.Column1 = rB3DMatrix.get( 0, 0 );
+ aResult.Line1.Column2 = rB3DMatrix.get( 0, 1 );
+ aResult.Line1.Column3 = rB3DMatrix.get( 0, 2 );
+ aResult.Line1.Column4 = rB3DMatrix.get( 0, 3 );
+
+ aResult.Line2.Column1 = rB3DMatrix.get( 1, 0 );
+ aResult.Line2.Column2 = rB3DMatrix.get( 1, 1 );
+ aResult.Line2.Column3 = rB3DMatrix.get( 1, 2 );
+ aResult.Line2.Column4 = rB3DMatrix.get( 1, 3 );
+
+ aResult.Line3.Column1 = rB3DMatrix.get( 2, 0 );
+ aResult.Line3.Column2 = rB3DMatrix.get( 2, 1 );
+ aResult.Line3.Column3 = rB3DMatrix.get( 2, 2 );
+ aResult.Line3.Column4 = rB3DMatrix.get( 2, 3 );
+
+ aResult.Line4.Column1 = rB3DMatrix.get( 3, 0 );
+ aResult.Line4.Column2 = rB3DMatrix.get( 3, 1 );
+ aResult.Line4.Column3 = rB3DMatrix.get( 3, 2 );
+ aResult.Line4.Column4 = rB3DMatrix.get( 3, 3 );
+
+ return aResult;
+}
+
+B3DTuple GetRotationFromMatrix( const B3DHomMatrix & rB3DMatrix )
+{
+ B3DTuple aScale, aTranslation, aRotation, aShearing;
+ rB3DMatrix.decompose( aScale, aTranslation, aRotation, aShearing );
+ return aRotation;
+}
+
+B3DTuple GetScaleFromMatrix( const B3DHomMatrix & rB3DMatrix )
+{
+ B3DTuple aScale, aTranslation, aRotation, aShearing;
+ rB3DMatrix.decompose( aScale, aTranslation, aRotation, aShearing );
+ return aScale;
+}
+
+void ReduceToRotationMatrix( ::basegfx::B3DHomMatrix & rB3DMatrix )
+{
+ B3DTuple aR( GetRotationFromMatrix( rB3DMatrix ) );
+ ::basegfx::B3DHomMatrix aRotationMatrix;
+ aRotationMatrix.rotate(aR.getX(),aR.getY(),aR.getZ());
+ rB3DMatrix = aRotationMatrix;
+}
+
+double Deg2Rad( double fDegrees )
+{
+ return fDegrees * ( F_PI / 180.0 );
+}
+
+double Rad2Deg( double fRadians )
+{
+ return fRadians * ( 180.0 / F_PI );
+}
+
+} // namespace BaseGFXHelper
+} // namespace chart
diff --git a/chart2/source/tools/CachedDataSequence.cxx b/chart2/source/tools/CachedDataSequence.cxx
new file mode 100644
index 000000000000..678cd8ba8314
--- /dev/null
+++ b/chart2/source/tools/CachedDataSequence.cxx
@@ -0,0 +1,409 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "CachedDataSequence.hxx"
+#include "macros.hxx"
+#include "PropertyHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "CommonFunctors.hxx"
+#include "ModifyListenerHelper.hxx"
+
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <algorithm>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <rtl/math.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::chart::ContainerHelper;
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::osl::MutexGuard;
+
+// necessary for MS compiler
+using ::comphelper::OPropertyContainer;
+using ::comphelper::OMutexAndBroadcastHelper;
+using ::comphelper::OPropertyArrayUsageHelper;
+using ::chart::impl::CachedDataSequence_Base;
+
+namespace
+{
+static const OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.CachedDataSequence" ));
+
+enum
+{
+// PROP_SOURCE_IDENTIFIER,
+ PROP_NUMBERFORMAT_KEY,
+ PROP_PROPOSED_ROLE
+};
+} // anonymous namespace
+
+
+// ____________________
+namespace chart
+{
+
+CachedDataSequence::CachedDataSequence()
+ : OPropertyContainer( GetBroadcastHelper()),
+ CachedDataSequence_Base( GetMutex()),
+ m_eCurrentDataType( NUMERICAL ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ registerProperties();
+}
+CachedDataSequence::CachedDataSequence( const Reference< uno::XComponentContext > & /*xContext*/ )
+ : OPropertyContainer( GetBroadcastHelper()),
+ CachedDataSequence_Base( GetMutex()),
+ m_eCurrentDataType( MIXED ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder( ))
+{
+ registerProperties();
+}
+
+CachedDataSequence::CachedDataSequence( const OUString & rSingleText )
+ : OPropertyContainer( GetBroadcastHelper()),
+ CachedDataSequence_Base( GetMutex()),
+ m_eCurrentDataType( TEXTUAL ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ m_aTextualSequence.realloc(1);
+ m_aTextualSequence[0] = rSingleText;
+ registerProperties();
+}
+
+CachedDataSequence::CachedDataSequence( const CachedDataSequence & rSource )
+ : OMutexAndBroadcastHelper(),
+ OPropertyContainer( GetBroadcastHelper()),
+ OPropertyArrayUsageHelper< CachedDataSequence >(),
+ CachedDataSequence_Base( GetMutex()),
+ m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
+ m_sRole( rSource.m_sRole ),
+ m_eCurrentDataType( rSource.m_eCurrentDataType ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ switch( m_eCurrentDataType )
+ {
+ case TEXTUAL:
+ m_aTextualSequence = rSource.m_aTextualSequence;
+ break;
+ case NUMERICAL:
+ m_aNumericalSequence = rSource.m_aNumericalSequence;
+ break;
+ case MIXED:
+ m_aMixedSequence = rSource.m_aMixedSequence;
+ break;
+ }
+
+ registerProperties();
+}
+
+CachedDataSequence::~CachedDataSequence()
+{}
+
+void CachedDataSequence::registerProperties()
+{
+ registerProperty( C2U( "NumberFormatKey" ),
+ PROP_NUMBERFORMAT_KEY,
+ 0, // PropertyAttributes
+ & m_nNumberFormatKey,
+ ::getCppuType( & m_nNumberFormatKey ) );
+
+ registerProperty( C2U( "Role" ),
+ PROP_PROPOSED_ROLE,
+ 0, // PropertyAttributes
+ & m_sRole,
+ ::getCppuType( & m_sRole ) );
+}
+
+Sequence< double > CachedDataSequence::Impl_getNumericalData() const
+{
+ if( m_eCurrentDataType == NUMERICAL )
+ return m_aNumericalSequence;
+
+ sal_Int32 nSize = ( m_eCurrentDataType == TEXTUAL )
+ ? m_aTextualSequence.getLength()
+ : m_aMixedSequence.getLength();
+
+ Sequence< double > aResult( nSize );
+ double * pResultArray = aResult.getArray();
+
+ if( m_eCurrentDataType == TEXTUAL )
+ {
+ const OUString * pTextArray = m_aTextualSequence.getConstArray();
+ ::std::transform( pTextArray, pTextArray + nSize,
+ pResultArray,
+ CommonFunctors::OUStringToDouble() );
+ }
+ else
+ {
+ OSL_ASSERT( m_eCurrentDataType == MIXED );
+ const Any * pMixedArray = m_aMixedSequence.getConstArray();
+ ::std::transform( pMixedArray, pMixedArray + nSize,
+ pResultArray,
+ CommonFunctors::AnyToDouble() );
+ }
+ return aResult;
+}
+
+Sequence< OUString > CachedDataSequence::Impl_getTextualData() const
+{
+ if( m_eCurrentDataType == TEXTUAL )
+ return m_aTextualSequence;
+
+ sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
+ ? m_aNumericalSequence.getLength()
+ : m_aMixedSequence.getLength();
+
+ Sequence< OUString > aResult( nSize );
+ OUString * pResultArray = aResult.getArray();
+
+ if( m_eCurrentDataType == NUMERICAL )
+ {
+ const double * pTextArray = m_aNumericalSequence.getConstArray();
+ ::std::transform( pTextArray, pTextArray + nSize,
+ pResultArray,
+ CommonFunctors::DoubleToOUString() );
+ }
+ else
+ {
+ OSL_ASSERT( m_eCurrentDataType == MIXED );
+ const Any * pMixedArray = m_aMixedSequence.getConstArray();
+ ::std::transform( pMixedArray, pMixedArray + nSize,
+ pResultArray,
+ CommonFunctors::AnyToString() );
+ }
+
+ return aResult;
+}
+
+Sequence< Any > CachedDataSequence::Impl_getMixedData() const
+{
+ if( m_eCurrentDataType == MIXED )
+ return m_aMixedSequence;
+
+ sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
+ ? m_aNumericalSequence.getLength()
+ : m_aTextualSequence.getLength();
+
+ Sequence< Any > aResult( nSize );
+ Any * pResultArray = aResult.getArray();
+
+ if( m_eCurrentDataType == NUMERICAL )
+ {
+ const double * pTextArray = m_aNumericalSequence.getConstArray();
+ ::std::transform( pTextArray, pTextArray + nSize,
+ pResultArray,
+ CommonFunctors::makeAny< double >() );
+ }
+ else
+ {
+ OSL_ASSERT( m_eCurrentDataType == TEXTUAL );
+ const OUString * pMixedArray = m_aTextualSequence.getConstArray();
+ ::std::transform( pMixedArray, pMixedArray + nSize,
+ pResultArray,
+ CommonFunctors::makeAny< OUString >() );
+ }
+
+ return aResult;
+}
+
+// ================================================================================
+
+Sequence< OUString > CachedDataSequence::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 4 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.data.DataSequence" );
+ aServices[ 2 ] = C2U( "com.sun.star.chart2.data.NumericalDataSequence" );
+ aServices[ 3 ] = C2U( "com.sun.star.chart2.data.TextualDataSequence" );
+ return aServices;
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
+
+// ____ XPropertySet ____
+Reference< beans::XPropertySetInfo > SAL_CALL CachedDataSequence::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) );
+}
+
+// ____ ::comphelper::OPropertySetHelper ____
+// __________________________________________
+::cppu::IPropertyArrayHelper& CachedDataSequence::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+// ____ ::comphelper::OPropertyArrayHelper ____
+// ____________________________________________
+::cppu::IPropertyArrayHelper* CachedDataSequence::createArrayHelper() const
+{
+ Sequence< beans::Property > aProps;
+ // describes all properties which have been registered in the ctor
+ describeProperties( aProps );
+
+ return new ::cppu::OPropertyArrayHelper( aProps );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( CachedDataSequence, lcl_aServiceName )
+
+// ================================================================================
+
+// ________ XNumericalDataSequence ________
+Sequence< double > SAL_CALL CachedDataSequence::getNumericalData()
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+
+ if( m_eCurrentDataType == NUMERICAL )
+ return m_aNumericalSequence;
+ else
+ return Impl_getNumericalData();
+ // \--
+}
+
+// ________ XTextualDataSequence ________
+Sequence< OUString > SAL_CALL CachedDataSequence::getTextualData()
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+
+ if( m_eCurrentDataType == TEXTUAL )
+ return m_aTextualSequence;
+ else
+ return Impl_getTextualData();
+ // \--
+}
+
+// void SAL_CALL CachedDataSequence::setTextualData( const Sequence< OUString >& aData )
+// throw (uno::RuntimeException)
+// {
+// // /--
+// MutexGuard aGuard( GetMutex() );
+// Impl_setTextualData( aData );
+// // \--
+// }
+
+// ________ XDataSequence ________
+Sequence< Any > SAL_CALL CachedDataSequence::getData()
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ return Impl_getMixedData();
+ // \--
+}
+
+OUString SAL_CALL CachedDataSequence::getSourceRangeRepresentation()
+ throw (uno::RuntimeException)
+{
+ return m_sRole;
+}
+
+Sequence< OUString > SAL_CALL CachedDataSequence::generateLabel( chart2::data::LabelOrigin /*eLabelOrigin*/ )
+ throw (uno::RuntimeException)
+{
+ // return empty label, as we have no range representaions to determine something useful
+ return Sequence< OUString >();
+}
+
+::sal_Int32 SAL_CALL CachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 /*nIndex*/ )
+ throw (lang::IndexOutOfBoundsException,
+ uno::RuntimeException)
+{
+ return 0;
+}
+
+Reference< util::XCloneable > SAL_CALL CachedDataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ CachedDataSequence * pNewSeq = new CachedDataSequence( *this );
+
+ return Reference< util::XCloneable >( pNewSeq );
+}
+
+void SAL_CALL CachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL CachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// lang::XInitialization:
+void SAL_CALL CachedDataSequence::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
+{
+ ::comphelper::SequenceAsHashMap aMap(_aArguments);
+ m_aNumericalSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aNumericalSequence);
+ if ( m_aNumericalSequence.getLength() )
+ m_eCurrentDataType = NUMERICAL;
+ else
+ {
+ m_aTextualSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aTextualSequence);
+ if ( m_aTextualSequence.getLength() )
+ m_eCurrentDataType = TEXTUAL;
+ else
+ {
+ m_aMixedSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aMixedSequence);
+ if ( m_aMixedSequence.getLength() )
+ m_eCurrentDataType = MIXED;
+ }
+ }
+}
+} // namespace chart
diff --git a/chart2/source/tools/CharacterProperties.cxx b/chart2/source/tools/CharacterProperties.cxx
new file mode 100644
index 000000000000..cca655780a79
--- /dev/null
+++ b/chart2/source/tools/CharacterProperties.cxx
@@ -0,0 +1,608 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "CharacterProperties.hxx"
+#include "ContainerHelper.hxx"
+#include "macros.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontPitch.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/style/CaseMap.hpp>
+#include <com/sun/star/text/FontRelief.hpp>
+#include <com/sun/star/text/FontEmphasis.hpp>
+#include <com/sun/star/text/RubyAdjust.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+
+#include <comphelper/InlineContainer.hxx>
+
+
+// header for struct SvtLinguConfig
+#ifndef _SVTOOLS_LINGUCFG_HXX_
+#include <unotools/lingucfg.hxx>
+#endif
+#ifndef INCLUDED_I18NPOOL_MSLANGID_HXX
+#include <i18npool/mslangid.hxx>
+#endif
+#ifndef _SV_OUTDEV_HXX
+#include <vcl/outdev.hxx>
+#endif
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+
+using ::rtl::OUString;
+
+namespace chart
+{
+
+void CharacterProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ // CharacterProperties
+ rOutProperties.push_back(
+ Property( C2U( "CharFontName" ),
+ PROP_CHAR_FONT_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "CharFontStyleName" ),
+ PROP_CHAR_FONT_STYLE_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharFontFamily (see awt.FontFamily)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontFamily" ),
+ PROP_CHAR_FONT_FAMILY,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontCharSet (see awt.CharSet)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontCharSet" ),
+ PROP_CHAR_FONT_CHAR_SET,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontPitch (see awt.FontPitch)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontPitch" ),
+ PROP_CHAR_FONT_PITCH,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharColor
+ rOutProperties.push_back(
+ Property( C2U( "CharColor" ),
+ PROP_CHAR_COLOR,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharBackColor
+// rOutProperties.push_back(
+// Property( C2U( "CharBackColor" ),
+// PROP_CHAR_BACKGROUND_COLOR,
+// ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT));
+ // CharEscapement
+ rOutProperties.push_back(
+ Property( C2U( "CharEscapement" ),
+ PROP_CHAR_ESCAPEMENT,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharHeight
+ rOutProperties.push_back(
+ Property( C2U( "CharHeight" ),
+ PROP_CHAR_CHAR_HEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharUnderline (see awt.FontUnderline)
+ rOutProperties.push_back(
+ Property( C2U( "CharUnderline" ),
+ PROP_CHAR_UNDERLINE,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharUnderlineColor
+ rOutProperties.push_back(
+ Property( C2U( "CharUnderlineColor" ),
+ PROP_CHAR_UNDERLINE_COLOR,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharUnderlineHasColor
+ rOutProperties.push_back(
+ Property( C2U( "CharUnderlineHasColor" ),
+ PROP_CHAR_UNDERLINE_HAS_COLOR,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharWeight (see awt.FontWeight)
+ rOutProperties.push_back(
+ Property( C2U( "CharWeight" ),
+ PROP_CHAR_WEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharPosture
+ rOutProperties.push_back(
+ Property( C2U( "CharPosture" ),
+ PROP_CHAR_POSTURE,
+ ::getCppuType( reinterpret_cast< const awt::FontSlant * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "CharAutoKerning" ),
+ PROP_CHAR_AUTO_KERNING,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ rOutProperties.push_back(
+ Property( C2U( "CharKerning" ),
+ PROP_CHAR_KERNING,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharCaseMap (see style.CaseMap)
+// rOutProperties.push_back(
+// Property( C2U( "CharCaseMap" ),
+// PROP_CHAR_CASE_MAPPING,
+// ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+
+ // CharRotation
+// rOutProperties.push_back(
+// Property( C2U( "CharRotation" ),
+// PROP_CHAR_ROTATION,
+// ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+// // CharScaleWidth
+// rOutProperties.push_back(
+// Property( C2U( "CharScaleWidth" ),
+// PROP_CHAR_SCALE_WIDTH,
+// ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharEscapementHeight
+ rOutProperties.push_back(
+ Property( C2U( "CharEscapementHeight" ),
+ PROP_CHAR_ESCAPEMENT_HEIGHT,
+ ::getCppuType( reinterpret_cast< const sal_Int8 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ // CharCrossedOut
+// rOutProperties.push_back(
+// Property( C2U( "CharCrossedOut" ),
+// PROP_CHAR_CROSSED_OUT,
+// ::getBooleanCppuType(),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharStrikeout (see awt.FontStrikeout)
+ rOutProperties.push_back(
+ Property( C2U( "CharStrikeout" ),
+ PROP_CHAR_STRIKE_OUT,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharWordMode
+ rOutProperties.push_back(
+ Property( C2U( "CharWordMode" ),
+ PROP_CHAR_WORD_MODE,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFlash
+// rOutProperties.push_back(
+// Property( C2U( "CharFlash" ),
+// PROP_CHAR_FLASH,
+// ::getBooleanCppuType(),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharLocale
+ rOutProperties.push_back(
+ Property( C2U( "CharLocale" ),
+ PROP_CHAR_LOCALE,
+ ::getCppuType( reinterpret_cast< const lang::Locale * >(0)),
+ //#i111967# no PropertyChangeEvent is fired on change so far
+ beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharShadowed
+ rOutProperties.push_back(
+ Property( C2U( "CharShadowed" ),
+ PROP_CHAR_SHADOWED,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharContoured
+ rOutProperties.push_back(
+ Property( C2U( "CharContoured" ),
+ PROP_CHAR_CONTOURED,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharRelief (see text.FontRelief)
+ rOutProperties.push_back(
+ Property( C2U( "CharRelief" ),
+ PROP_CHAR_RELIEF,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // CharEmphasize (see text.FontEmphasis)
+ rOutProperties.push_back(
+ Property( C2U( "CharEmphasis" ),
+ PROP_CHAR_EMPHASIS,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+// // RubyText
+// rOutProperties.push_back(
+// Property( C2U( "RubyText" ),
+// PROP_CHAR_RUBY_TEXT,
+// ::getCppuType( reinterpret_cast< const OUString * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+// // RubyAdjust (see text.RubyAdjust)
+// rOutProperties.push_back(
+// Property( C2U( "RubyAdjust" ),
+// PROP_CHAR_RUBY_ADJUST,
+// ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+// // RubyCharStyleName
+// rOutProperties.push_back(
+// Property( C2U( "RubyStyleName" ),
+// PROP_CHAR_RUBY_STYLE_NAME,
+// ::getCppuType( reinterpret_cast< const OUString * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+// // RubyIsAbove
+// rOutProperties.push_back(
+// Property( C2U( "RubyIsAbove" ),
+// PROP_CHAR_RUBY_IS_ABOVE,
+// ::getBooleanCppuType(),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+// // CharNoHyphenation
+// rOutProperties.push_back(
+// Property( C2U( "InhibitHyphenation" ),
+// PROP_CHAR_INHIBIT_HYPHENATION,
+// ::getBooleanCppuType(),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // CharacterPropertiesAsian
+ // =====
+ // CharFontNameAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharFontNameAsian" ),
+ PROP_CHAR_ASIAN_FONT_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontStyleNameAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharFontStyleNameAsian" ),
+ PROP_CHAR_ASIAN_FONT_STYLE_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharFontFamilyAsian (see awt.FontFamily)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontFamilyAsian" ),
+ PROP_CHAR_ASIAN_FONT_FAMILY,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontCharSetAsian (see awt.CharSet)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontCharSetAsian" ),
+ PROP_CHAR_ASIAN_CHAR_SET,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontPitchAsian (see awt.FontPitch)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontPitchAsian" ),
+ PROP_CHAR_ASIAN_FONT_PITCH,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharHeightAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharHeightAsian" ),
+ PROP_CHAR_ASIAN_CHAR_HEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharWeightAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharWeightAsian" ),
+ PROP_CHAR_ASIAN_WEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharPostureAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharPostureAsian" ),
+ PROP_CHAR_ASIAN_POSTURE,
+ ::getCppuType( reinterpret_cast< const awt::FontSlant * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharLocaleAsian
+ rOutProperties.push_back(
+ Property( C2U( "CharLocaleAsian" ),
+ PROP_CHAR_ASIAN_LOCALE,
+ ::getCppuType( reinterpret_cast< const lang::Locale * >(0)),
+ //#i111967# no PropertyChangeEvent is fired on change so far
+ beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // CharacterPropertiesComplex
+ // ===
+ // CharFontNameComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharFontNameComplex" ),
+ PROP_CHAR_COMPLEX_FONT_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontStyleNameComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharFontStyleNameComplex" ),
+ PROP_CHAR_COMPLEX_FONT_STYLE_NAME,
+ ::getCppuType( reinterpret_cast< const OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // CharFontFamilyComplex (see awt.FontFamily)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontFamilyComplex" ),
+ PROP_CHAR_COMPLEX_FONT_FAMILY,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontCharSetComplex (see awt.CharSet)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontCharSetComplex" ),
+ PROP_CHAR_COMPLEX_CHAR_SET,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharFontPitchComplex (see awt.FontPitch)
+ rOutProperties.push_back(
+ Property( C2U( "CharFontPitchComplex" ),
+ PROP_CHAR_COMPLEX_FONT_PITCH,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharHeightComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharHeightComplex" ),
+ PROP_CHAR_COMPLEX_CHAR_HEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharWeightComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharWeightComplex" ),
+ PROP_CHAR_COMPLEX_WEIGHT,
+ ::getCppuType( reinterpret_cast< const float * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharPostureComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharPostureComplex" ),
+ PROP_CHAR_COMPLEX_POSTURE,
+ ::getCppuType( reinterpret_cast< const awt::FontSlant * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // CharLocaleComplex
+ rOutProperties.push_back(
+ Property( C2U( "CharLocaleComplex" ),
+ PROP_CHAR_COMPLEX_LOCALE,
+ ::getCppuType( reinterpret_cast< const lang::Locale * >(0)),
+ //#i111967# no PropertyChangeEvent is fired on change so far
+ beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // Writing Mode left to right vs right to left
+ rOutProperties.push_back(
+ Property( C2U( "WritingMode" ),
+ PROP_WRITING_MODE,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)), /*com::sun::star::text::WritingMode2*/
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "ParaIsCharacterDistance" ),
+ PROP_PARA_IS_CHARACTER_DISTANCE,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+void CharacterProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ const float fDefaultFontHeight = 13.0;
+
+ SvtLinguConfig aLinguConfig;
+ lang::Locale aDefaultLocale;
+ aLinguConfig.GetProperty(C2U("DefaultLocale")) >>= aDefaultLocale;
+ lang::Locale aDefaultLocale_CJK;
+ aLinguConfig.GetProperty(C2U("DefaultLocale_CJK")) >>= aDefaultLocale_CJK;
+ lang::Locale aDefaultLocale_CTL;
+ aLinguConfig.GetProperty(C2U("DefaultLocale_CTL")) >>= aDefaultLocale_CTL;
+
+ using namespace ::com::sun::star::i18n::ScriptType;
+ LanguageType nLang;
+ nLang = MsLangId::resolveSystemLanguageByScriptType(MsLangId::convertLocaleToLanguage(aDefaultLocale), LATIN);
+ Font aFont = OutputDevice::GetDefaultFont( DEFAULTFONT_LATIN_SPREADSHEET, nLang, DEFAULTFONT_FLAGS_ONLYONE, 0 );
+ nLang = MsLangId::resolveSystemLanguageByScriptType(MsLangId::convertLocaleToLanguage( aDefaultLocale_CJK), ASIAN);
+ Font aFontCJK = OutputDevice::GetDefaultFont( DEFAULTFONT_CJK_SPREADSHEET, nLang, DEFAULTFONT_FLAGS_ONLYONE, 0 );
+ nLang = MsLangId::resolveSystemLanguageByScriptType(MsLangId::convertLocaleToLanguage( aDefaultLocale_CTL), COMPLEX);
+ Font aFontCTL = OutputDevice::GetDefaultFont( DEFAULTFONT_CTL_SPREADSHEET, nLang, DEFAULTFONT_FLAGS_ONLYONE, 0 );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FONT_NAME, OUString( aFont.GetName() ) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FONT_STYLE_NAME, OUString(aFont.GetStyleName()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FONT_FAMILY, sal_Int16(aFont.GetFamily()) );//awt::FontFamily::SWISS
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FONT_CHAR_SET, sal_Int16(aFont.GetCharSet()) );//use awt::CharSet::DONTKNOW instead of SYSTEM to avoid assertion issue 50249
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FONT_PITCH, sal_Int16(aFont.GetPitch()) );//awt::FontPitch::VARIABLE
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_CHAR_COLOR, -1 ); //automatic color (COL_AUTO)
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_CHAR_HEIGHT, fDefaultFontHeight );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_UNDERLINE, awt::FontUnderline::NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_CHAR_UNDERLINE_COLOR, -1 ); //automatic color (COL_AUTO)
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_UNDERLINE_HAS_COLOR, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_WEIGHT, awt::FontWeight::NORMAL );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_POSTURE, awt::FontSlant_NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_AUTO_KERNING, true );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_CHAR_KERNING, 0 );
+
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_CASE_MAPPING, style::CaseMap::NONE );
+// ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_CHAR_ROTATION, 0 );
+// ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_CHAR_SCALE_WIDTH, 71 );
+
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_CROSSED_OUT, false );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_CHAR_STRIKE_OUT, awt::FontStrikeout::NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_WORD_MODE, false );
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_FLASH, false );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_LOCALE, aDefaultLocale );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_SHADOWED, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_CONTOURED, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_RELIEF, text::FontRelief::NONE );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_EMPHASIS, text::FontEmphasis::NONE );
+
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_RUBY_ADJUST, text::RubyAdjust_INDENT_BLOCK );
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_RUBY_STYLE_NAME, ?? );
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_RUBY_IS_ABOVE, true );
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_INHIBIT_HYPHENATION, false );
+
+ // Asian (com.sun.star.style.CharacterPropertiesAsian)
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultFontHeight );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_WEIGHT, awt::FontWeight::NORMAL );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_POSTURE, awt::FontSlant_NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_LOCALE, aDefaultLocale_CJK );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_FONT_NAME, OUString( aFontCJK.GetName() ) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_FONT_STYLE_NAME, OUString(aFontCJK.GetStyleName()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_FONT_FAMILY, sal_Int16(aFontCJK.GetFamily()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_CHAR_SET, sal_Int16(aFontCJK.GetCharSet()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_ASIAN_FONT_PITCH, sal_Int16(aFontCJK.GetPitch()) );
+
+ // Complex Text Layout (com.sun.star.style.CharacterPropertiesComplex)
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultFontHeight );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_WEIGHT, awt::FontWeight::NORMAL );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_POSTURE, awt::FontSlant_NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_LOCALE, aDefaultLocale_CTL );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_FONT_NAME, OUString( aFontCTL.GetName() ) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_FONT_STYLE_NAME, OUString(aFontCTL.GetStyleName()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_FONT_FAMILY, sal_Int16(aFontCTL.GetFamily()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_CHAR_SET, sal_Int16(aFontCTL.GetCharSet()) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CHAR_COMPLEX_FONT_PITCH, sal_Int16(aFontCTL.GetPitch()) );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_WRITING_MODE, sal_Int16( com::sun::star::text::WritingMode2::PAGE ) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PARA_IS_CHARACTER_DISTANCE, sal_True );
+}
+
+bool CharacterProperties::IsCharacterPropertyHandle( sal_Int32 nHandle )
+{
+ return ( FAST_PROPERTY_ID_START_CHAR_PROP <= nHandle &&
+ nHandle < CharacterProperties::FAST_PROPERTY_ID_END_CHAR_PROP );
+}
+
+// static
+awt::FontDescriptor CharacterProperties::createFontDescriptorFromPropertySet(
+ const uno::Reference< beans::XMultiPropertySet > & xMultiPropSet )
+{
+ awt::FontDescriptor aResult;
+ // Note: keep this sorted!
+ ::comphelper::MakeVector< OUString > aPropNames
+ ( C2U("CharFontCharSet")); // CharSet
+ aPropNames
+ ( C2U("CharFontFamily")) // Family
+ ( C2U("CharFontName")) // Name
+ ( C2U("CharFontPitch")) // Pitch
+ ( C2U("CharFontStyleName")) // StyleName
+ ( C2U("CharHeight")) // Height
+ ( C2U("CharPosture")) // Slant
+ ( C2U("CharStrikeout")) // Strikeout
+ ( C2U("CharUnderline")) // Underline
+ ( C2U("CharWeight")) // Weight
+ ( C2U("CharWordMode")) // WordLineMode
+ ;
+
+ uno::Sequence< OUString > aPropNameSeq( ContainerHelper::ContainerToSequence( aPropNames ));
+ uno::Sequence< uno::Any > aValues( xMultiPropSet->getPropertyValues( aPropNameSeq ));
+
+ sal_Int32 i=0;
+ // Note keep this sorted according to the list above (comments are the fieldnames)
+ aValues[ i++ ] >>= aResult.CharSet;
+ aValues[ i++ ] >>= aResult.Family;
+ aValues[ i++ ] >>= aResult.Name;
+ aValues[ i++ ] >>= aResult.Pitch;
+ aValues[ i++ ] >>= aResult.StyleName;
+ float fCharHeight = 0;
+ aValues[ i++ ] >>= fCharHeight;
+ aResult.Height = static_cast< sal_Int16 >( fCharHeight );
+ aValues[ i++ ] >>= aResult.Slant;
+ aValues[ i++ ] >>= aResult.Strikeout;
+ aValues[ i++ ] >>= aResult.Underline;
+ aValues[ i++ ] >>= aResult.Weight;
+ aValues[ i++ ] >>= aResult.WordLineMode;
+ OSL_ASSERT( i == aValues.getLength());
+
+ return aResult;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/ChartDebugTrace.cxx b/chart2/source/tools/ChartDebugTrace.cxx
new file mode 100644
index 000000000000..9629138cb2be
--- /dev/null
+++ b/chart2/source/tools/ChartDebugTrace.cxx
@@ -0,0 +1,417 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ChartDebugTrace.hxx"
+#include "macros.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <rtl/math.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
+
+namespace
+{
+/*
+const char lcl_aSpace=' ';
+
+void lcl_IndentedTrace( int nIndent, char* pStr )
+{
+ if( nIndent > 0 )
+ {
+ OSL_TRACE( "%*c%s", nIndent, lcl_aSpace, pStr );
+ }
+ else
+ {
+ OSL_TRACE( pStr );
+ }
+}
+
+void lcl_TraceException( const uno::Exception & aEx )
+{
+ OSL_TRACE(
+ U2C( C2U( "*** Exception caught during trace. Type: " ) +
+ OUString::createFromAscii( typeid( aEx ).name()) +
+ C2U( ", Message: " ) +
+ aEx.Message ));
+}
+
+void lcl_TraceCategories( const Reference< data::XLabeledDataSequence > & xCat, int nIndent )
+{
+ if( ! xCat.is())
+ return;
+ try
+ {
+ Reference< data::XDataSequence > xValues( xCat->getValues());
+ if( xValues.is())
+ {
+ OSL_TRACE( "%*ccategories: source: %s", nIndent, lcl_aSpace,
+ U2C( xValues->getSourceRangeRepresentation()));
+ }
+ Reference< data::XDataSequence > xLabel( xCat->getLabel());
+ if( xLabel.is())
+ {
+ OSL_TRACE( "%*ccategories' label: source: %s", nIndent, lcl_aSpace,
+ U2C( xLabel->getSourceRangeRepresentation()));
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ lcl_TraceException( ex );
+ }
+}
+
+void lcl_TraceDataSeriesSeq( const Sequence< Reference< XDataSeries > > & aSeries, int nIndent )
+{
+ for( sal_Int32 j = 0; j < aSeries.getLength(); ++j )
+ {
+ Reference< beans::XPropertySet > xProp( aSeries[j], uno::UNO_QUERY );
+ OUString aId;
+
+ OSL_TRACE( "%*cindex %ld", nIndent, lcl_aSpace, j );
+
+ StackingDirection aStDir;
+ if( xProp.is() &&
+ ( xProp->getPropertyValue( C2U( "StackingDirection" )) >>= aStDir ) &&
+ aStDir != StackingDirection_NO_STACKING )
+ {
+ OSL_TRACE( "%*cstacking in %s", nIndent + 2, lcl_aSpace,
+ (aStDir == StackingDirection_Y_STACKING)
+ ? "y-direction" : "z-direction" );
+ }
+
+ Reference< data::XDataSource > xSource( aSeries[j], uno::UNO_QUERY );
+ if( xSource.is())
+ {
+ Sequence< Reference< data::XLabeledDataSequence > > aSequences( xSource->getDataSequences());
+ const sal_Int32 nMax = aSequences.getLength();
+ for( sal_Int32 k = 0; k < nMax; ++k )
+ {
+ if( aSequences[k].is())
+ {
+ OUString aSourceId(C2U("<none>"));
+ if( aSequences[k]->getValues().is())
+ aSourceId = aSequences[k]->getValues()->getSourceRangeRepresentation();
+ xProp.set( aSequences[k]->getValues(), uno::UNO_QUERY );
+ if( xProp.is() &&
+ ( xProp->getPropertyValue( C2U( "Role" )) >>= aId ))
+ {
+ OSL_TRACE( "%*cdata sequence %d: role: %s, source: %s",
+ nIndent + 2, lcl_aSpace, k, U2C( aId ), U2C( aSourceId ));
+ }
+ else
+ {
+ OSL_TRACE( "%*cdata sequence %d, unknown role, source: %s",
+ nIndent + 2, lcl_aSpace, k, U2C( aSourceId ) );
+ }
+
+ aSourceId = C2U("<none>");
+ if( aSequences[k]->getLabel().is())
+ aSourceId = OUString( aSequences[k]->getLabel()->getSourceRangeRepresentation());
+ xProp.set( aSequences[k]->getLabel(), uno::UNO_QUERY );
+ if( xProp.is() &&
+ ( xProp->getPropertyValue( C2U( "Role" )) >>= aId ))
+ {
+ OSL_TRACE( "%*cdata sequence label %d: role: %s, source: %s",
+ nIndent + 2, lcl_aSpace, k, U2C( aId ), U2C( aSourceId ));
+ }
+ else
+ {
+ OSL_TRACE( "%*cdata sequence label %d: unknown role, source: %s",
+ nIndent + 2, lcl_aSpace, k, U2C( aSourceId ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+void lcl_TraceChartType( const Reference< XChartType > & xChartType, int nIndent )
+{
+ if( xChartType.is())
+ {
+ OSL_TRACE( "%*c* type: %s", nIndent, lcl_aSpace, U2C( xChartType->getChartType()) );
+
+ lcl_IndentedTrace( nIndent + 2, "Supported Roles" );
+ sal_Int32 i=0;
+ Sequence< OUString > aMandRoles( xChartType->getSupportedMandatoryRoles());
+ if( aMandRoles.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent + 4, "mandatory" );
+ for( i=0; i<aMandRoles.getLength(); ++i )
+ {
+ OSL_TRACE( "%*c%s", nIndent + 6, lcl_aSpace, U2C( aMandRoles[i] ));
+ }
+ }
+ Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
+ if( aOptRoles.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent + 4, "optional" );
+ for( i=0; i<aOptRoles.getLength(); ++i )
+ {
+ OSL_TRACE( "%*c%s", nIndent + 6, lcl_aSpace, U2C( aOptRoles[i] ));
+ }
+ }
+ OSL_TRACE( "%*crole of sequence for label: %s", nIndent + 2, lcl_aSpace,
+ U2C( xChartType->getRoleOfSequenceForSeriesLabel()));
+
+ Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
+ if( xDSCnt.is())
+ {
+ lcl_IndentedTrace( nIndent + 2, "Data Series" );
+ lcl_TraceDataSeriesSeq( xDSCnt->getDataSeries(), nIndent + 4 );
+ }
+ }
+}
+
+void lcl_TraceCoordinateSystem( const Reference< XCoordinateSystem > & xCooSys, int nIndent )
+{
+ if( xCooSys.is()) try
+ {
+ sal_Int32 nDim = xCooSys->getDimension();
+ OSL_TRACE( "%*c* dim: %ld, type: %s", nIndent, lcl_aSpace,
+ nDim, U2C( xCooSys->getCoordinateSystemType() ));
+ nIndent += 2;
+ OSL_TRACE( "%*cview service-name: %s", nIndent, lcl_aSpace,
+ U2C( xCooSys->getViewServiceName() ));
+
+ Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo(), uno::UNO_QUERY );
+ sal_Bool bSwap;
+ if( xInfo.is() &&
+ xInfo->hasPropertyByName( C2U("SwapXAndYAxis")) &&
+ (xProp->getPropertyValue( C2U("SwapXAndYAxis")) >>= bSwap) &&
+ bSwap )
+ {
+ lcl_IndentedTrace( nIndent, "swap x-axis and y-axis" );
+ }
+ }
+
+ if( nDim >= 2 )
+ {
+ const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(1);
+ for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
+ {
+ Reference< XScale > xScale( xCooSys->getAxisByDimension( 1, nI ));
+ if( xScale.is())
+ {
+ ScaleData aData( xScale->getScaleData());
+ if( aData.AxisType==AxisType::PERCENT )
+ lcl_IndentedTrace( nIndent, "percent stacking at y-scale" );
+ }
+ }
+ }
+
+ Sequence< uno::Any > aOrigin( xCooSys->getOrigin());
+ double x, y, z;
+ ::rtl::math::setNan( &x ), ::rtl::math::setNan( &y ), ::rtl::math::setNan( &z );
+ if( aOrigin.getLength() > 0 &&
+ aOrigin[0].hasValue() )
+ aOrigin[0] >>= x;
+ if( aOrigin.getLength() > 1 &&
+ aOrigin[1].hasValue() )
+ aOrigin[1] >>= y;
+ if( aOrigin.getLength() > 2 &&
+ aOrigin[2].hasValue() )
+ aOrigin[2] >>= z;
+ OSL_TRACE( "%*corigin: (%f, %f, %f)", nIndent, lcl_aSpace, x, y, z );
+
+ Reference< XChartTypeContainer > xCTCnt( xCooSys, uno::UNO_QUERY );
+ if( xCTCnt.is())
+ {
+ Sequence< Reference< XChartType > > aChartTypes( xCTCnt->getChartTypes());
+ if( aChartTypes.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent, "Chart Types" );
+ for( sal_Int32 i=0; i<aChartTypes.getLength(); ++i )
+ {
+ lcl_TraceChartType( aChartTypes[i], nIndent + 2 );
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ lcl_TraceException( ex );
+ }
+}
+
+void lcl_TraceMeter(
+ const Reference< XMeter > & xMeter,
+ const Sequence< Reference< XCoordinateSystem > > & aCooSys,
+ bool bWithCategories,
+ int nIndent )
+{
+ try
+ {
+ Reference< XCoordinateSystem > xCooSys( xMeter->getCoordinateSystem());
+ for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
+ if( aCooSys[i] == xCooSys )
+ {
+ OSL_TRACE( "%*cbelongs to Coordinate System %ld.", nIndent + 2, lcl_aSpace, i );
+ }
+ OSL_TRACE( "%*crepresents Dimension %ld.", nIndent + 2, lcl_aSpace, xMeter->getRepresentedDimension());
+ if( bWithCategories )
+ {
+ Reference< XScale > xScale( xCooSys->getAxisByDimension( xMeter->getRepresentedDimension(), xMeter->getIndex() ));
+ if( xScale.is())
+ {
+ ScaleData aData = xScale->getScaleData();
+ if( aData.Categories.is())
+ {
+ lcl_TraceCategories( aData.Categories, nIndent + 2 );
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ lcl_TraceException( ex );
+ }
+}
+*/
+} // anonymous namespace
+#endif
+
+
+namespace chart
+{
+namespace debug
+{
+
+#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
+
+void ChartDebugTraceDocument(
+ const Reference< XChartDocument > & /*xDoc*/,
+ int /*nIndent*/ )
+{
+ /*
+#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
+ try
+ {
+ OSL_TRACE( "%*cas %sternal data", nIndent, 'h',
+ xDoc->hasInternalDataProvider() ? "in": "ex" );
+
+ Reference< lang::XMultiServiceFactory > xCTManager( xDoc->getChartTypeManager(), uno::UNO_QUERY );
+ if( xCTManager.is())
+ {
+ Sequence< OUString > aServiceNames( xCTManager->getAvailableServiceNames());
+ OSL_TRACE( "%*c ChartTypeManager has %ld entries", nIndent, '*', aServiceNames.getLength());
+# if OSL_DEBUG_LEVEL >= (CHART_TRACE_OSL_DEBUG_LEVEL + 1)
+ for( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
+ {
+ OSL_TRACE( "%*c%s", nIndent + 2, lcl_aSpace, U2C( aServiceNames[i] ));
+ }
+# endif
+ }
+ Reference< XDiagram > xDiagram( xDoc->getFirstDiagram());
+ lcl_IndentedTrace( nIndent, "* Diagram" );
+ ChartDebugTraceDiagram( xDiagram, nIndent + 2 );
+ }
+ catch( uno::Exception & ex )
+ {
+ lcl_TraceException( ex );
+ }
+#endif
+ */
+}
+
+void ChartDebugTraceDiagram(
+ const Reference< XDiagram > & /*xDiagram*/,
+ int /*nIndent*/ )
+{
+ /*
+#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSys( xCooSysCnt->getCoordinateSystems() );
+ if( aCooSys.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent, "CoordinateSystems" );
+ for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
+ lcl_TraceCoordinateSystem( aCooSys[i], nIndent + 2 );
+ }
+ else
+ {
+ lcl_IndentedTrace( nIndent, "<No Coordinate Systems>" );
+ }
+
+ Reference< XAxisContainer > xAxisCnt( xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XAxis > > aAxes( xAxisCnt->getAxes() );
+ if( aAxes.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent, "Axes" );
+ for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
+ lcl_TraceMeter( Reference< XMeter >( aAxes[i], uno::UNO_QUERY ), aCooSys, true, nIndent + 2 );
+ }
+ else
+ {
+ lcl_IndentedTrace( nIndent, "<No Axes>" );
+ }
+
+ Reference< XGridContainer > xGridCnt( xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XGrid > > aGrids( xGridCnt->getGrids() );
+ if( aGrids.getLength() > 0 )
+ {
+ lcl_IndentedTrace( nIndent, "Grids" );
+ for( sal_Int32 i=0; i<aGrids.getLength(); ++i )
+ lcl_TraceMeter( Reference< XMeter >( aGrids[i], uno::UNO_QUERY ), aCooSys, false, nIndent + 2 );
+ }
+ else
+ {
+ lcl_IndentedTrace( nIndent, "<No Grids>" );
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ lcl_TraceException( ex );
+ }
+
+#endif
+
+*/
+}
+#endif
+
+} // namespace debug
+} // namespace chart
diff --git a/chart2/source/tools/ChartModelHelper.cxx b/chart2/source/tools/ChartModelHelper.cxx
new file mode 100644
index 000000000000..a49b2abeac98
--- /dev/null
+++ b/chart2/source/tools/ChartModelHelper.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "ChartModelHelper.hxx"
+#include "macros.hxx"
+#include "DiagramHelper.hxx"
+#include "DataSourceHelper.hxx"
+#include "ControllerLockGuard.hxx"
+#include "RangeHighlighter.hxx"
+#include "InternalDataProvider.hxx"
+
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/view/XSelectionChangeListener.hpp>
+
+// header for define DBG_ASSERT
+#include <tools/debug.hxx>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+//static
+uno::Reference< chart2::data::XRangeHighlighter > ChartModelHelper::createRangeHighlighter(
+ const uno::Reference< view::XSelectionSupplier > & xSelectionSupplier )
+{
+ return new RangeHighlighter( xSelectionSupplier );
+}
+
+//static
+uno::Reference< chart2::data::XDataProvider > ChartModelHelper::createInternalDataProvider(
+ const uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDoc, bool bConnectToModel )
+{
+ return new InternalDataProvider( xChartDoc, bConnectToModel );
+}
+
+//static
+uno::Reference< XDiagram > ChartModelHelper::findDiagram( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
+ if( xChartDoc.is())
+ return ChartModelHelper::findDiagram( xChartDoc );
+ return NULL;
+}
+
+// static
+uno::Reference< XDiagram > ChartModelHelper::findDiagram( const uno::Reference< chart2::XChartDocument >& xChartDoc )
+{
+ try
+ {
+ if( xChartDoc.is())
+ return xChartDoc->getFirstDiagram();
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return NULL;
+}
+
+//static
+uno::Reference< XCoordinateSystem > ChartModelHelper::getFirstCoordinateSystem( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< XCoordinateSystem > XCooSys;
+ uno::Reference< XCoordinateSystemContainer > xCooSysCnt( ChartModelHelper::findDiagram( xModel ), uno::UNO_QUERY );
+ if( xCooSysCnt.is() )
+ {
+ uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
+ if( aCooSysSeq.getLength() )
+ XCooSys = aCooSysSeq[0];
+ }
+ return XCooSys;
+}
+
+// static
+::std::vector< uno::Reference< XDataSeries > > ChartModelHelper::getDataSeries(
+ const uno::Reference< XChartDocument > & xChartDoc )
+{
+ ::std::vector< uno::Reference< XDataSeries > > aResult;
+
+ uno::Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( xChartDoc );
+ if( xDiagram.is())
+ aResult = DiagramHelper::getDataSeriesFromDiagram( xDiagram );
+
+ return aResult;
+}
+
+// static
+::std::vector< uno::Reference< XDataSeries > > ChartModelHelper::getDataSeries(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ return getDataSeries( uno::Reference< chart2::XChartDocument >( xModel, uno::UNO_QUERY ));
+}
+
+
+uno::Reference< XChartType > ChartModelHelper::getChartTypeOfSeries(
+ const uno::Reference< frame::XModel >& xModel
+ , const uno::Reference< XDataSeries >& xGivenDataSeries )
+{
+ return DiagramHelper::getChartTypeOfSeries( ChartModelHelper::findDiagram( xModel ), xGivenDataSeries );
+}
+
+awt::Size ChartModelHelper::getDefaultPageSize()
+{
+ return awt::Size( 16000, 9000 );
+}
+
+awt::Size ChartModelHelper::getPageSize( const uno::Reference< frame::XModel >& xModel )
+{
+ awt::Size aPageSize( ChartModelHelper::getDefaultPageSize() );
+ uno::Reference< embed::XVisualObject > xVisualObject(xModel,uno::UNO_QUERY);
+ DBG_ASSERT(xVisualObject.is(),"need xVisualObject for page size");
+ if( xVisualObject.is() )
+ aPageSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
+ return aPageSize;
+}
+
+void ChartModelHelper::setPageSize( const awt::Size& rSize, const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< embed::XVisualObject > xVisualObject(xModel,uno::UNO_QUERY);
+ DBG_ASSERT(xVisualObject.is(),"need xVisualObject for page size");
+ if( xVisualObject.is() )
+ xVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, rSize );
+}
+
+void ChartModelHelper::triggerRangeHighlighting( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xModel, uno::UNO_QUERY );
+ if( xDataReceiver.is() )
+ {
+ uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY );
+ //trigger selection of cell range
+ if( xSelectionChangeListener.is() )
+ {
+ lang::EventObject aEvent( xSelectionChangeListener );
+ xSelectionChangeListener->selectionChanged( aEvent );
+ }
+ }
+}
+
+bool ChartModelHelper::isIncludeHiddenCells( const uno::Reference< frame::XModel >& xChartModel )
+{
+ bool bIncluded = true; // hidden cells are included by default.
+
+ uno::Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram(xChartModel) );
+ if (!xDiagram.is())
+ return bIncluded;
+
+ uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
+ if (!xProp.is())
+ return bIncluded;
+
+ try
+ {
+ xProp->getPropertyValue(C2U("IncludeHiddenCells")) >>= bIncluded;
+ }
+ catch( const beans::UnknownPropertyException& )
+ {
+ }
+
+ return bIncluded;
+}
+
+bool ChartModelHelper::setIncludeHiddenCells( bool bIncludeHiddenCells, const uno::Reference< frame::XModel >& xChartModel )
+{
+ bool bChanged = false;
+ try
+ {
+ ControllerLockGuard aLockedControllers( xChartModel );
+
+ uno::Reference< beans::XPropertySet > xDiagramProperties( ChartModelHelper::findDiagram(xChartModel), uno::UNO_QUERY );
+ if (xDiagramProperties.is())
+ {
+ bool bOldValue = bIncludeHiddenCells;
+ xDiagramProperties->getPropertyValue( C2U("IncludeHiddenCells") ) >>= bOldValue;
+ if( bOldValue == bIncludeHiddenCells )
+ bChanged = true;
+
+ //set the property on all instances in all cases to get the different objects in sync!
+
+ uno::Any aNewValue = uno::makeAny(bIncludeHiddenCells);
+
+ try
+ {
+ uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
+ if( xChartDoc.is() )
+ {
+ uno::Reference< beans::XPropertySet > xDataProviderProperties( xChartDoc->getDataProvider(), uno::UNO_QUERY );
+ if( xDataProviderProperties.is() )
+ xDataProviderProperties->setPropertyValue(C2U("IncludeHiddenCells"), aNewValue );
+ }
+ }
+ catch( const beans::UnknownPropertyException& )
+ {
+ //the property is optional!
+ }
+
+ try
+ {
+ uno::Reference< chart2::data::XDataSource > xUsedData( DataSourceHelper::getUsedData( xChartModel ) );
+ if( xUsedData.is() )
+ {
+ uno::Reference< beans::XPropertySet > xProp;
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aData( xUsedData->getDataSequences());
+ for( sal_Int32 i=0; i<aData.getLength(); ++i )
+ {
+ xProp.set( uno::Reference< beans::XPropertySet >( aData[i]->getValues(), uno::UNO_QUERY ) );
+ if(xProp.is())
+ xProp->setPropertyValue(C2U("IncludeHiddenCells"), aNewValue );
+ xProp.set( uno::Reference< beans::XPropertySet >( aData[i]->getLabel(), uno::UNO_QUERY ) );
+ if(xProp.is())
+ xProp->setPropertyValue(C2U("IncludeHiddenCells"), aNewValue );
+ }
+ }
+ }
+ catch( const beans::UnknownPropertyException& )
+ {
+ //the property is optional!
+ }
+
+ xDiagramProperties->setPropertyValue( C2U("IncludeHiddenCells"), aNewValue);
+ }
+ }
+ catch (uno::Exception& e)
+ {
+ ASSERT_EXCEPTION(e);
+ }
+ return bChanged;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx
new file mode 100644
index 000000000000..b851a3864b97
--- /dev/null
+++ b/chart2/source/tools/ChartTypeHelper.cxx
@@ -0,0 +1,685 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ChartTypeHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "DataSeriesHelper.hxx"
+#include "macros.hxx"
+#include "servicenames_charttypes.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+//.............................................................................
+namespace chart
+{
+
+bool ChartTypeHelper::isSupportingAxisSideBySide(
+ const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ bool bResult = false;
+
+ if( xChartType.is() &&
+ nDimensionCount < 3 )
+ {
+ bool bFound=false;
+ bool bAmbiguous=false;
+ StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, 0 );
+ if( eStackMode == StackMode_NONE && !bAmbiguous )
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ bResult = ( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) );
+ }
+ }
+
+ return bResult;
+}
+
+sal_Bool ChartTypeHelper::isSupportingGeometryProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //form tab only for 3D-bar and 3D-column charts.
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.equals(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ return sal_True;
+ if( aChartTypeName.equals(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) )
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool ChartTypeHelper::isSupportingStatisticProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //3D charts, pie, net and stock do not support statistic properties
+
+ //@todo ask charttype itself (and series? --> stock chart?) --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ return sal_False;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) ) //todo: BubbleChart support error bars and trend lines
+ return sal_False;
+ }
+ return sal_True;
+}
+
+sal_Bool ChartTypeHelper::isSupportingRegressionProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ // note: old chart: only scatter chart
+ return isSupportingStatisticProperties( xChartType, nDimensionCount );
+}
+
+sal_Bool ChartTypeHelper::isSupportingAreaProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //2D line charts, net and stock do not support area properties
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==2)
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+
+sal_Bool ChartTypeHelper::isSupportingSymbolProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //2D line charts, 2D scatter charts and 2D net charts do support symbols
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ return sal_False;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) )
+ return sal_True;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ return sal_True;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool ChartTypeHelper::isSupportingMainAxis( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex )
+{
+ //pie charts do not support axis at all
+ //no 3rd axis for 2D charts
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return sal_False;
+
+ if( nDimensionIndex == 2 )
+ return nDimensionCount == 3;
+ }
+ return sal_True;
+}
+
+sal_Bool ChartTypeHelper::isSupportingSecondaryAxis( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 /*nDimensionIndex*/ )
+{
+ //3D, pie and net charts do not support a secondary axis at all
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ return sal_False;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return sal_False;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+sal_Bool ChartTypeHelper::isSupportingOverlapAndGapWidthProperties(
+ const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //2D bar charts do support a this special properties
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ return sal_False;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) )
+ return sal_True;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool ChartTypeHelper::isSupportingBarConnectors(
+ const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount )
+{
+ //2D bar charts with stacked series support this
+
+ //@todo ask charttype itself --> need model change first
+ if(xChartType.is())
+ {
+ if(nDimensionCount==3)
+ return sal_False;
+
+ bool bFound=false;
+ bool bAmbiguous=false;
+ StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, 0 );
+ if( eStackMode != StackMode_Y_STACKED || bAmbiguous )
+ return sal_False;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) )
+ return sal_True;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ return sal_True; // note: old chart was false here
+ }
+ return sal_False;
+}
+
+uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedLabelPlacements( const uno::Reference< chart2::XChartType >& xChartType
+ , sal_Int32 nDimensionCount, sal_Bool bSwapXAndY
+ , const uno::Reference< chart2::XDataSeries >& xSeries )
+{
+ (void)nDimensionCount;
+
+ uno::Sequence < sal_Int32 > aRet;
+ if( !xChartType.is() )
+ return aRet;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ {
+ bool bDonut = false;
+ uno::Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY_THROW );
+ if(xChartTypeProp.is())
+ xChartTypeProp->getPropertyValue( C2U("UseRings")) >>= bDonut;
+
+ if(!bDonut)
+ {
+ aRet.realloc(4);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::AVOID_OVERLAP;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::INSIDE;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::CENTER;
+ }
+ else
+ {
+ aRet.realloc(1);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::CENTER;
+ }
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE)
+ )
+ {
+ aRet.realloc(5);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::TOP;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::BOTTOM;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::LEFT;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::RIGHT;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::CENTER;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ {
+
+ bool bStacked = false;
+ {
+ uno::Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
+ chart2::StackingDirection eStacking = chart2::StackingDirection_NO_STACKING;
+ xSeriesProp->getPropertyValue( C2U("StackingDirection") ) >>= eStacking;
+ bStacked = (chart2::StackingDirection_Y_STACKING == eStacking);
+ }
+
+ aRet.realloc( bStacked ? 3 : 6 );
+ sal_Int32* pSeq = aRet.getArray();
+ if(!bStacked)
+ {
+ if(bSwapXAndY)
+ {
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::RIGHT;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::LEFT;
+ }
+ else
+ {
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::TOP;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::BOTTOM;
+ }
+ }
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::CENTER;
+ if(!bStacked)
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::INSIDE;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::NEAR_ORIGIN;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
+ {
+ aRet.realloc(1);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::TOP;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ {
+ aRet.realloc(6);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::TOP;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::BOTTOM;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::LEFT;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::RIGHT;
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::CENTER;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ {
+ aRet.realloc(1);
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ {
+ aRet.realloc( 1 );
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::DataLabelPlacement::OUTSIDE;
+ }
+ else
+ {
+ OSL_ENSURE( false, "unknown charttype" );
+ }
+
+ return aRet;
+}
+
+sal_Bool ChartTypeHelper::isSupportingRightAngledAxes( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+bool ChartTypeHelper::isSupportingStartingAngle( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return true;
+ }
+ return false;
+}
+bool ChartTypeHelper::isSupportingBaseValue( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA)
+ )
+ return true;
+ }
+ return false;
+}
+
+bool ChartTypeHelper::isSupportingAxisPositioning( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return false;
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ return false;
+ }
+ if( nDimensionCount==3 )
+ return nDimensionIndex<2;
+ return true;
+}
+
+bool ChartTypeHelper::shiftTicksAtXAxisPerDefault( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
+ return true;
+ }
+ return false;
+}
+
+bool ChartTypeHelper::noBordersForSimpleScheme( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ if(xChartType.is())
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//static
+sal_Int32 ChartTypeHelper::getDefaultDirectLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType )
+{
+ sal_Int32 nRet = static_cast< sal_Int32 >( 0x808080 ); // grey
+ if( xChartType .is() )
+ {
+ rtl::OUString aChartType = xChartType->getChartType();
+ if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ {
+ if( bSimple )
+ nRet = static_cast< sal_Int32 >( 0x333333 ); // grey80
+ else
+ nRet = static_cast< sal_Int32 >( 0xb3b3b3 ); // grey30
+ }
+ else if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
+ || aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60
+ }
+ return nRet;
+}
+
+//static
+sal_Int32 ChartTypeHelper::getDefaultAmbientLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType )
+{
+ sal_Int32 nRet = static_cast< sal_Int32 >( 0x999999 ); // grey40
+ if( xChartType .is() )
+ {
+ rtl::OUString aChartType = xChartType->getChartType();
+ if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ {
+ if( bSimple )
+ nRet = static_cast< sal_Int32 >( 0xcccccc ); // grey20
+ else
+ nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60
+ }
+ }
+ return nRet;
+}
+
+drawing::Direction3D ChartTypeHelper::getDefaultSimpleLightDirection( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ drawing::Direction3D aRet(0.0, 0.0, 1.0);
+ if( xChartType .is() )
+ {
+ rtl::OUString aChartType = xChartType->getChartType();
+ if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ aRet = drawing::Direction3D(0.0, 0.8, 0.5);
+ else if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
+ || aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ aRet = drawing::Direction3D(0.9, 0.5, 0.05);
+ }
+ return aRet;
+}
+
+drawing::Direction3D ChartTypeHelper::getDefaultRealisticLightDirection( const uno::Reference< chart2::XChartType >& xChartType )
+{
+ drawing::Direction3D aRet(0.0, 0.0, 1.0);
+ if( xChartType .is() )
+ {
+ rtl::OUString aChartType = xChartType->getChartType();
+ if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ aRet = drawing::Direction3D(0.6, 0.6, 0.6);
+ else if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
+ || aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ aRet = drawing::Direction3D(0.9, 0.5, 0.05);
+ }
+ return aRet;
+}
+
+sal_Int32 ChartTypeHelper::getAxisType( const uno::Reference<
+ XChartType >& xChartType, sal_Int32 nDimensionIndex )
+{
+ //retruned is a constant from constant group ::com::sun::star::chart2::AxisType
+
+ //@todo ask charttype itself --> need model change first
+ if(!xChartType.is())
+ return AxisType::CATEGORY;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if(2==nDimensionIndex)//z-axis
+ return AxisType::SERIES;
+ if(1==nDimensionIndex)//y-axis
+ return AxisType::REALNUMBER;
+ if(0==nDimensionIndex)//x-axis
+ {
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ return AxisType::REALNUMBER;
+ return AxisType::CATEGORY;
+ }
+ return AxisType::CATEGORY;
+}
+
+sal_Int32 ChartTypeHelper::getNumberOfDisplayedSeries(
+ const uno::Reference< XChartType >& xChartType,
+ sal_Int32 nNumberOfSeries )
+{
+ if( xChartType.is() )
+ {
+ try
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE))
+ {
+ uno::Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY_THROW );
+ bool bDonut = false;
+ if( (xChartTypeProp->getPropertyValue( C2U("UseRings")) >>= bDonut)
+ && !bDonut )
+ {
+ return nNumberOfSeries>0 ? 1 : 0;
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ return nNumberOfSeries;
+}
+
+uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedMissingValueTreatments( const uno::Reference< XChartType >& xChartType )
+{
+ uno::Sequence < sal_Int32 > aRet;
+ if( !xChartType.is() )
+ return aRet;
+
+ bool bStacked = false;
+ bool bFound=false;
+ bool bAmbiguous=false;
+ StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, 0 );
+ bStacked = bFound && (StackMode_Y_STACKED == eStackMode);
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ {
+ aRet.realloc( 2 );
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::USE_ZERO;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
+ {
+ aRet.realloc( bStacked ? 1 : 2 );
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::USE_ZERO;
+ if( !bStacked )
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::CONTINUE;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ {
+ aRet.realloc( bStacked ? 2 : 3 );
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::USE_ZERO;
+ if( !bStacked )
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::CONTINUE;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
+ {
+ aRet.realloc( 3 );
+ sal_Int32* pSeq = aRet.getArray();
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::CONTINUE;
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
+ *pSeq++ = ::com::sun::star::chart::MissingValueTreatment::USE_ZERO;
+ }
+ else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ {
+ aRet.realloc( 0 );
+ }
+ else
+ {
+ OSL_ENSURE( false, "unknown charttype" );
+ }
+
+ return aRet;
+}
+
+bool ChartTypeHelper::isSeriesInFrontOfAxisLine( const uno::Reference< XChartType >& xChartType )
+{
+ if( xChartType.is() )
+ {
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) )
+ return false;
+ }
+ return true;
+}
+
+rtl::OUString ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
+{
+ rtl::OUString aRet( C2U( "values-y" ) );
+ if( !xChartType.is() )
+ return aRet;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ aRet = xChartType->getRoleOfSequenceForSeriesLabel();
+ return aRet;
+}
+
+rtl::OUString ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
+{
+ rtl::OUString aRet( C2U( "values-y" ) );
+ if( !xChartType.is() )
+ return aRet;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK)
+ || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ aRet = xChartType->getRoleOfSequenceForSeriesLabel();
+ return aRet;
+}
+
+bool ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( const uno::Reference< XChartType >& xChartType )
+{
+ bool bRet = true;
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
+ bRet = false;
+ return bRet;
+}
+
+bool ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( const uno::Reference< XChartType >& xChartType )
+{
+ bool bRet = false;
+ if( !xChartType.is() )
+ return bRet;
+
+ rtl::OUString aChartTypeName = xChartType->getChartType();
+ if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) ||
+ aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/ChartViewHelper.cxx b/chart2/source/tools/ChartViewHelper.cxx
new file mode 100644
index 000000000000..55fbd368426a
--- /dev/null
+++ b/chart2/source/tools/ChartViewHelper.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ChartViewHelper.hxx"
+#include "macros.hxx"
+#include "servicenames.hxx"
+
+// header for define DBG_ASSERT
+#include <tools/debug.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+//static
+void ChartViewHelper::setViewToDirtyState( const uno::Reference< frame::XModel >& xChartModel )
+{
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFact( xChartModel, uno::UNO_QUERY );
+ if( xFact.is() )
+ {
+ Reference< util::XModifyListener > xModifyListener(
+ xFact->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
+ if( xModifyListener.is() )
+ {
+ lang::EventObject aEvent( Reference< lang::XComponent >( xChartModel, uno::UNO_QUERY ) );
+ xModifyListener->modified( aEvent );
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/ColorPerPointHelper.cxx b/chart2/source/tools/ColorPerPointHelper.cxx
new file mode 100644
index 000000000000..762cb436a9a7
--- /dev/null
+++ b/chart2/source/tools/ColorPerPointHelper.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ColorPerPointHelper.hxx"
+#include "macros.hxx"
+#include <com/sun/star/chart2/XDataSeries.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+
+#include <algorithm>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+//static
+bool ColorPerPointHelper::hasPointOwnColor(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xDataSeriesProperties
+ , sal_Int32 nPointIndex
+ , const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xDataPointProperties //may be NULL this is just for performance
+ )
+{
+ if( !xDataSeriesProperties.is() )
+ return false;
+
+ if( hasPointOwnProperties( xDataSeriesProperties, nPointIndex ))
+ {
+ uno::Reference< beans::XPropertyState > xPointState( xDataPointProperties, uno::UNO_QUERY );
+ if( !xPointState.is() )
+ {
+ uno::Reference< XDataSeries > xSeries( xDataSeriesProperties, uno::UNO_QUERY );
+ if(xSeries.is())
+ xPointState.set( xSeries->getDataPointByIndex( nPointIndex ), uno::UNO_QUERY );
+ }
+ if( !xPointState.is() )
+ return false;
+
+ return (xPointState->getPropertyState( C2U("Color")) != beans::PropertyState_DEFAULT_VALUE );
+ }
+
+ return false;
+}
+
+// static
+bool ColorPerPointHelper::hasPointOwnProperties(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xSeriesProperties
+ , sal_Int32 nPointIndex )
+{
+ if( xSeriesProperties.is() )
+ {
+ uno::Sequence< sal_Int32 > aIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aIndexList )
+ {
+ const sal_Int32 * pBegIt = aIndexList.getConstArray();
+ const sal_Int32 * pEndIt = pBegIt + aIndexList.getLength();
+ return ( ::std::find( pBegIt, pEndIt, nPointIndex ) != pEndIt );
+ }
+ }
+
+ return false;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/CommonConverters.cxx b/chart2/source/tools/CommonConverters.cxx
new file mode 100644
index 000000000000..e9d90248ce84
--- /dev/null
+++ b/chart2/source/tools/CommonConverters.cxx
@@ -0,0 +1,549 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "CommonConverters.hxx"
+#include <com/sun/star/drawing/DoubleSequence.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
+#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
+#include <rtl/math.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+
+#include <cstdarg>
+
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// diverse methods for class conversions; e.g. ::basegfx::B3DHomMatrix to HomogenMatrix
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+drawing::HomogenMatrix B3DHomMatrixToHomogenMatrix( const ::basegfx::B3DHomMatrix& rM )
+{
+ drawing::HomogenMatrix aHM;
+ aHM.Line1.Column1 = rM.get(0, 0);
+ aHM.Line1.Column2 = rM.get(0, 1);
+ aHM.Line1.Column3 = rM.get(0, 2);
+ aHM.Line1.Column4 = rM.get(0, 3);
+ aHM.Line2.Column1 = rM.get(1, 0);
+ aHM.Line2.Column2 = rM.get(1, 1);
+ aHM.Line2.Column3 = rM.get(1, 2);
+ aHM.Line2.Column4 = rM.get(1, 3);
+ aHM.Line3.Column1 = rM.get(2, 0);
+ aHM.Line3.Column2 = rM.get(2, 1);
+ aHM.Line3.Column3 = rM.get(2, 2);
+ aHM.Line3.Column4 = rM.get(2, 3);
+ aHM.Line4.Column1 = rM.get(3, 0);
+ aHM.Line4.Column2 = rM.get(3, 1);
+ aHM.Line4.Column3 = rM.get(3, 2);
+ aHM.Line4.Column4 = rM.get(3, 3);
+ return aHM;
+}
+
+::basegfx::B3DHomMatrix HomogenMatrixToB3DHomMatrix( const drawing::HomogenMatrix& rHM )
+{
+ ::basegfx::B3DHomMatrix aM;
+ aM.set(0, 0, rHM.Line1.Column1);
+ aM.set(0, 1, rHM.Line1.Column2);
+ aM.set(0, 2, rHM.Line1.Column3);
+ aM.set(0, 3, rHM.Line1.Column4);
+ aM.set(1, 0, rHM.Line2.Column1);
+ aM.set(1, 1, rHM.Line2.Column2);
+ aM.set(1, 2, rHM.Line2.Column3);
+ aM.set(1, 3, rHM.Line2.Column4);
+ aM.set(2, 0, rHM.Line3.Column1);
+ aM.set(2, 1, rHM.Line3.Column2);
+ aM.set(2, 2, rHM.Line3.Column3);
+ aM.set(2, 3, rHM.Line3.Column4);
+ aM.set(3, 0, rHM.Line4.Column1);
+ aM.set(3, 1, rHM.Line4.Column2);
+ aM.set(3, 2, rHM.Line4.Column3);
+ aM.set(3, 3, rHM.Line4.Column4);
+ return aM;
+}
+
+::basegfx::B2DHomMatrix IgnoreZ( const ::basegfx::B3DHomMatrix& rM )
+{
+ ::basegfx::B2DHomMatrix aM;
+ aM.set(0, 0, rM.get(0, 0));
+ aM.set(0, 1, rM.get(0, 1));
+ aM.set(0, 2, rM.get(0, 3));
+ aM.set(1, 0, rM.get(1, 0));
+ aM.set(1, 1, rM.get(1, 1));
+ aM.set(1, 2, rM.get(1, 3));
+ aM.set(2, 0, rM.get(3, 0));
+ aM.set(2, 1, rM.get(3, 1));
+ aM.set(2, 2, rM.get(3, 3));
+ return aM;
+}
+
+
+drawing::HomogenMatrix3 B2DHomMatrixToHomogenMatrix3( const ::basegfx::B2DHomMatrix& rM )
+{
+ drawing::HomogenMatrix3 aHM;
+ aHM.Line1.Column1 = rM.get(0, 0);
+ aHM.Line1.Column2 = rM.get(0, 1);
+ aHM.Line1.Column3 = rM.get(0, 2);
+ aHM.Line2.Column1 = rM.get(1, 0);
+ aHM.Line2.Column2 = rM.get(1, 1);
+ aHM.Line2.Column3 = rM.get(1, 2);
+ aHM.Line3.Column1 = rM.get(2, 0);
+ aHM.Line3.Column2 = rM.get(2, 1);
+ aHM.Line3.Column3 = rM.get(2, 2);
+ return aHM;
+}
+
+::basegfx::B3DPoint Position3DToB3DPoint( const drawing::Position3D& rPosition )
+{
+ return ::basegfx::B3DPoint(
+ rPosition.PositionX ,
+ rPosition.PositionY ,
+ rPosition.PositionZ );
+}
+
+drawing::Direction3D B3DVectorToDirection3D( const ::basegfx::B3DVector& rVector)
+{
+ return drawing::Direction3D(
+ rVector.getX()
+ , rVector.getY()
+ , rVector.getZ()
+ );
+}
+
+drawing::Position3D B3DPointToPosition3D( const ::basegfx::B3DPoint& rPoint)
+{
+ return drawing::Position3D(
+ rPoint.getX()
+ , rPoint.getY()
+ , rPoint.getZ()
+ );
+}
+
+::basegfx::B3DVector Direction3DToB3DVector( const drawing::Direction3D& rDirection)
+{
+ return ::basegfx::B3DVector(
+ rDirection.DirectionX
+ , rDirection.DirectionY
+ , rDirection.DirectionZ
+ );
+}
+
+void AddPointToPoly( drawing::PolyPolygonShape3D& rPoly, const drawing::Position3D& rPos, sal_Int32 nPolygonIndex )
+{
+ if(nPolygonIndex<0)
+ {
+ OSL_ENSURE( false, "The polygon index needs to be > 0");
+ nPolygonIndex=0;
+ }
+
+ //make sure that we have enough polygons
+ if(nPolygonIndex >= rPoly.SequenceX.getLength() )
+ {
+ rPoly.SequenceX.realloc(nPolygonIndex+1);
+ rPoly.SequenceY.realloc(nPolygonIndex+1);
+ rPoly.SequenceZ.realloc(nPolygonIndex+1);
+ }
+
+ drawing::DoubleSequence* pOuterSequenceX = &rPoly.SequenceX.getArray()[nPolygonIndex];
+ drawing::DoubleSequence* pOuterSequenceY = &rPoly.SequenceY.getArray()[nPolygonIndex];
+ drawing::DoubleSequence* pOuterSequenceZ = &rPoly.SequenceZ.getArray()[nPolygonIndex];
+
+ sal_Int32 nOldPointCount = pOuterSequenceX->getLength();
+
+ pOuterSequenceX->realloc(nOldPointCount+1);
+ pOuterSequenceY->realloc(nOldPointCount+1);
+ pOuterSequenceZ->realloc(nOldPointCount+1);
+
+ double* pInnerSequenceX = pOuterSequenceX->getArray();
+ double* pInnerSequenceY = pOuterSequenceY->getArray();
+ double* pInnerSequenceZ = pOuterSequenceZ->getArray();
+
+ pInnerSequenceX[nOldPointCount] = rPos.PositionX;
+ pInnerSequenceY[nOldPointCount] = rPos.PositionY;
+ pInnerSequenceZ[nOldPointCount] = rPos.PositionZ;
+}
+
+drawing::Position3D getPointFromPoly( const drawing::PolyPolygonShape3D& rPolygon, sal_Int32 nPointIndex, sal_Int32 nPolyIndex )
+{
+ drawing::Position3D aRet(0.0,0.0,0.0);
+
+ if( nPolyIndex>=0 && nPolyIndex<rPolygon.SequenceX.getLength())
+ {
+ if(nPointIndex<rPolygon.SequenceX[nPolyIndex].getLength())
+ {
+ aRet.PositionX = rPolygon.SequenceX[nPolyIndex][nPointIndex];
+ aRet.PositionY = rPolygon.SequenceY[nPolyIndex][nPointIndex];
+ aRet.PositionZ = rPolygon.SequenceZ[nPolyIndex][nPointIndex];
+ }
+ else
+ {
+ ;DBG_ERROR("polygon was accessed with a wrong index");
+ }
+ }
+ else
+ {
+ ;DBG_ERROR("polygon was accessed with a wrong index");
+ }
+ return aRet;
+}
+
+void addPolygon( drawing::PolyPolygonShape3D& rRet, const drawing::PolyPolygonShape3D& rAdd )
+{
+ sal_Int32 nAddOuterCount = rAdd.SequenceX.getLength();
+ sal_Int32 nOuterCount = rRet.SequenceX.getLength() + nAddOuterCount;
+ rRet.SequenceX.realloc( nOuterCount );
+ rRet.SequenceY.realloc( nOuterCount );
+ rRet.SequenceZ.realloc( nOuterCount );
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nOuter = nOuterCount - nAddOuterCount;
+ for( ; nOuter < nOuterCount; nOuter++ )
+ {
+ if( nIndex >= nAddOuterCount )
+ break;
+
+ rRet.SequenceX[nOuter] = rAdd.SequenceX[nIndex];
+ rRet.SequenceY[nOuter] = rAdd.SequenceY[nIndex];
+ rRet.SequenceZ[nOuter] = rAdd.SequenceZ[nIndex];
+
+ nIndex++;
+ }
+}
+
+void appendPoly( drawing::PolyPolygonShape3D& rRet, const drawing::PolyPolygonShape3D& rAdd )
+{
+ sal_Int32 nOuterCount = Max( rRet.SequenceX.getLength(), rAdd.SequenceX.getLength() );
+ rRet.SequenceX.realloc(nOuterCount);
+ rRet.SequenceY.realloc(nOuterCount);
+ rRet.SequenceZ.realloc(nOuterCount);
+
+ for( sal_Int32 nOuter=0;nOuter<nOuterCount;nOuter++ )
+ {
+ sal_Int32 nOldPointCount = rRet.SequenceX[nOuter].getLength();
+ sal_Int32 nAddPointCount = 0;
+ if(nOuter<rAdd.SequenceX.getLength())
+ nAddPointCount = rAdd.SequenceX[nOuter].getLength();
+ if(!nAddPointCount)
+ continue;
+
+ sal_Int32 nNewPointCount = nOldPointCount + nAddPointCount;
+
+ rRet.SequenceX[nOuter].realloc(nNewPointCount);
+ rRet.SequenceY[nOuter].realloc(nNewPointCount);
+ rRet.SequenceZ[nOuter].realloc(nNewPointCount);
+
+ sal_Int32 nPointTarget=nOldPointCount;
+ sal_Int32 nPointSource=nAddPointCount;
+ for( ; nPointSource-- ; nPointTarget++ )
+ {
+ rRet.SequenceX[nOuter][nPointTarget] = rAdd.SequenceX[nOuter][nPointSource];
+ rRet.SequenceY[nOuter][nPointTarget] = rAdd.SequenceY[nOuter][nPointSource];
+ rRet.SequenceZ[nOuter][nPointTarget] = rAdd.SequenceZ[nOuter][nPointSource];
+ }
+ }
+}
+
+drawing::PolyPolygonShape3D BezierToPoly(
+ const drawing::PolyPolygonBezierCoords& rBezier )
+{
+ const drawing::PointSequenceSequence& rPointSequence = rBezier.Coordinates;
+// const drawing::FlagSequenceSequence& rFlags = rBezier.Flags;
+
+ drawing::PolyPolygonShape3D aRet;
+ aRet.SequenceX.realloc( rPointSequence.getLength() );
+ aRet.SequenceY.realloc( rPointSequence.getLength() );
+ aRet.SequenceZ.realloc( rPointSequence.getLength() );
+
+ sal_Int32 nRealOuter = 0;
+ for(sal_Int32 nN = 0; nN < rPointSequence.getLength(); nN++)
+ {
+ sal_Int32 nInnerLength = rPointSequence[nN].getLength();
+ aRet.SequenceX[nN].realloc( nInnerLength );
+ aRet.SequenceY[nN].realloc( nInnerLength );
+ aRet.SequenceZ[nN].realloc( nInnerLength );
+
+ bool bHasOuterFlags = nN < rBezier.Flags.getLength();
+
+ sal_Int32 nRealInner = 0;
+ for( sal_Int32 nM = 0; nM < nInnerLength; nM++)
+ {
+ bool bHasInnerFlags = bHasOuterFlags && (nM < rBezier.Flags[nN].getLength());
+
+ if( !bHasInnerFlags || (rBezier.Flags[nN][nM] == drawing::PolygonFlags_NORMAL) )
+ {
+ aRet.SequenceX[nRealOuter][nRealInner] = rPointSequence[nN][nM].X;
+ aRet.SequenceY[nRealOuter][nRealInner] = rPointSequence[nN][nM].Y;
+ aRet.SequenceZ[nRealOuter][nRealInner] = 0.0;
+ nRealInner++;
+ }
+ }
+
+ aRet.SequenceX[nRealOuter].realloc( nRealInner );
+ aRet.SequenceY[nRealOuter].realloc( nRealInner );
+ aRet.SequenceZ[nRealOuter].realloc( nRealInner );
+
+ if( nRealInner>0 )
+ nRealOuter++;
+ }
+
+ aRet.SequenceX.realloc( nRealOuter );
+ aRet.SequenceY.realloc( nRealOuter );
+ aRet.SequenceZ.realloc( nRealOuter );
+
+ return aRet;
+}
+
+drawing::PointSequenceSequence PolyToPointSequence(
+ const drawing::PolyPolygonShape3D& rPolyPolygon )
+{
+ drawing::PointSequenceSequence aRet;
+ aRet.realloc( rPolyPolygon.SequenceX.getLength() );
+
+ for(sal_Int32 nN = 0; nN < rPolyPolygon.SequenceX.getLength(); nN++)
+ {
+ sal_Int32 nInnerLength = rPolyPolygon.SequenceX[nN].getLength();
+ aRet[nN].realloc( nInnerLength );
+ for( sal_Int32 nM = 0; nM < nInnerLength; nM++)
+ {
+ aRet[nN][nM].X = static_cast<sal_Int32>(rPolyPolygon.SequenceX[nN][nM]);
+ aRet[nN][nM].Y = static_cast<sal_Int32>(rPolyPolygon.SequenceY[nN][nM]);
+ }
+ }
+ return aRet;
+}
+
+void appendPointSequence( drawing::PointSequenceSequence& rTarget
+ , drawing::PointSequenceSequence& rAdd )
+{
+ sal_Int32 nAddCount = rAdd.getLength();
+ if(!nAddCount)
+ return;
+ sal_Int32 nOldCount = rTarget.getLength();
+
+ rTarget.realloc(nOldCount+nAddCount);
+ for(sal_Int32 nS=0; nS<nAddCount; nS++ )
+ rTarget[nOldCount+nS]=rAdd[nS];
+}
+
+drawing::Position3D operator+( const drawing::Position3D& rPos
+ , const drawing::Direction3D& rDirection)
+{
+ return drawing::Position3D(
+ rPos.PositionX + rDirection.DirectionX
+ , rPos.PositionY + rDirection.DirectionY
+ , rPos.PositionZ + rDirection.DirectionZ
+ );
+}
+
+drawing::Direction3D operator-( const drawing::Position3D& rPos1
+ , const drawing::Position3D& rPos2)
+{
+ return drawing::Direction3D(
+ rPos1.PositionX - rPos2.PositionX
+ , rPos1.PositionY - rPos2.PositionY
+ , rPos1.PositionZ - rPos2.PositionZ
+ );
+}
+
+bool operator==( const drawing::Position3D& rPos1
+ , const drawing::Position3D& rPos2)
+{
+ return rPos1.PositionX == rPos2.PositionX
+ && rPos1.PositionY == rPos2.PositionY
+ && rPos1.PositionZ == rPos2.PositionZ;
+}
+
+awt::Point Position3DToAWTPoint( const drawing::Position3D& rPos )
+{
+ awt::Point aRet;
+ aRet.X = static_cast<sal_Int32>(rPos.PositionX);
+ aRet.Y = static_cast<sal_Int32>(rPos.PositionY);
+ return aRet;
+}
+
+awt::Point ToPoint( const awt::Rectangle& rRectangle )
+{
+ return awt::Point( rRectangle.X, rRectangle.Y );
+}
+
+awt::Size ToSize( const awt::Rectangle& rRectangle )
+{
+ return awt::Size( rRectangle.Width, rRectangle.Height );
+}
+
+awt::Size Direction3DToAWTSize( const drawing::Direction3D& rDirection )
+{
+ awt::Size aRet;
+ aRet.Width = static_cast<sal_Int32>(rDirection.DirectionX);
+ aRet.Height = static_cast<sal_Int32>(rDirection.DirectionY);
+ return aRet;
+}
+
+uno::Sequence< double > B3DPointToSequence( const ::basegfx::B3DPoint& rPoint )
+{
+ uno::Sequence< double > aRet(3);
+ aRet[0] = rPoint.getX();
+ aRet[1] = rPoint.getY();
+ aRet[2] = rPoint.getZ();
+ return aRet;
+}
+
+drawing::Position3D SequenceToPosition3D( const uno::Sequence< double >& rSeq )
+{
+ OSL_ENSURE(rSeq.getLength()==3,"The sequence needs to have length 3 for conversion into vector");
+
+ drawing::Position3D aRet;
+ aRet.PositionX = rSeq.getLength()>0?rSeq[0]:0.0;
+ aRet.PositionY = rSeq.getLength()>1?rSeq[1]:0.0;
+ aRet.PositionZ = rSeq.getLength()>2?rSeq[2]:0.0;
+ return aRet;
+}
+
+uno::Sequence< double > Position3DToSequence( const drawing::Position3D& rPosition )
+{
+ uno::Sequence< double > aRet(3);
+ aRet[0] = rPosition.PositionX;
+ aRet[1] = rPosition.PositionY;
+ aRet[2] = rPosition.PositionZ;
+ return aRet;
+}
+
+using namespace ::com::sun::star::chart2;
+
+uno::Sequence< double > DataSequenceToDoubleSequence(
+ const uno::Reference< data::XDataSequence >& xDataSequence )
+{
+ uno::Sequence< double > aResult;
+ OSL_ASSERT( xDataSequence.is());
+ if(!xDataSequence.is())
+ return aResult;
+
+ uno::Reference< data::XNumericalDataSequence > xNumericalDataSequence( xDataSequence, uno::UNO_QUERY );
+ if( xNumericalDataSequence.is() )
+ {
+ aResult = xNumericalDataSequence->getNumericalData();
+ }
+ else
+ {
+ uno::Sequence< uno::Any > aValues = xDataSequence->getData();
+ aResult.realloc(aValues.getLength());
+ for(sal_Int32 nN=aValues.getLength();nN--;)
+ {
+ if( !(aValues[nN] >>= aResult[nN]) )
+ ::rtl::math::setNan( &aResult[nN] );
+ }
+ }
+
+ return aResult;
+}
+
+uno::Sequence< rtl::OUString > DataSequenceToStringSequence(
+ const uno::Reference< data::XDataSequence >& xDataSequence )
+{
+ uno::Sequence< rtl::OUString > aResult;
+ OSL_ASSERT( xDataSequence.is());
+ if(!xDataSequence.is())
+ return aResult;
+
+ uno::Reference< data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY );
+ if( xTextualDataSequence.is() )
+ {
+ aResult = xTextualDataSequence->getTextualData();
+ }
+ else
+ {
+ uno::Sequence< uno::Any > aValues = xDataSequence->getData();
+ aResult.realloc(aValues.getLength());
+
+ for(sal_Int32 nN=aValues.getLength();nN--;)
+ aValues[nN] >>= aResult[nN];
+ }
+
+ return aResult;
+}
+
+sal_Bool hasDoubleValue( const uno::Any& rAny )
+{
+ sal_Bool bRet = sal_False;
+ double fValue = 0.0;
+ if( rAny >>= fValue )
+ bRet = sal_True;
+ return bRet;
+}
+
+sal_Bool hasLongOrShortValue( const uno::Any& rAny )
+{
+ sal_Bool bRet = sal_False;
+ sal_Int32 n32 = 0;
+ if( rAny >>= n32 )
+ bRet = sal_True;
+ else
+ {
+ sal_Int16 n16 = 0;
+ if( rAny >>= n16 )
+ bRet = sal_True;
+ }
+ return bRet;
+}
+sal_Int16 getShortForLongAlso( const uno::Any& rAny )
+{
+ sal_Int16 nRet = 0;
+
+ if( !(rAny >>= nRet) )
+ {
+ sal_Int32 n32 = 0;
+ if( rAny >>= n32 )
+ nRet = static_cast<sal_Int16>(n32);
+ }
+ return nRet;
+}
+
+bool replaceParamterInString( rtl::OUString & rInOutResourceString,
+ const rtl::OUString & rParamToReplace,
+ const rtl::OUString & rReplaceWith )
+{
+ sal_Int32 nPos = rInOutResourceString.indexOf( rParamToReplace );
+ if( nPos == -1 )
+ return false;
+
+ rInOutResourceString = rInOutResourceString.replaceAt( nPos
+ , rParamToReplace.getLength(), rReplaceWith );
+ return true;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/ConfigColorScheme.cxx b/chart2/source/tools/ConfigColorScheme.cxx
new file mode 100644
index 000000000000..fb7106d87096
--- /dev/null
+++ b/chart2/source/tools/ConfigColorScheme.cxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ConfigColorScheme.hxx"
+#include "ContainerHelper.hxx"
+#include "macros.hxx"
+
+#include <unotools/configitem.hxx>
+
+#include <set>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace
+{
+
+static const OUString aSeriesPropName( RTL_CONSTASCII_USTRINGPARAM("Series"));
+
+} // anonymous namespace
+
+// --------------------------------------------------------------------------------
+
+namespace chart
+{
+
+uno::Reference< chart2::XColorScheme > createConfigColorScheme( const uno::Reference< uno::XComponentContext > & xContext )
+{
+ return new ConfigColorScheme( xContext );
+}
+
+namespace impl
+{
+class ChartConfigItem : public ::utl::ConfigItem
+{
+public:
+ explicit ChartConfigItem( ConfigItemListener & rListener );
+ virtual ~ChartConfigItem();
+
+ void addPropertyNotification( const OUString & rPropertyName );
+
+ uno::Any getProperty( const OUString & aPropertyName );
+
+protected:
+ // ____ ::utl::ConfigItem ____
+ virtual void Commit();
+ virtual void Notify( const Sequence< OUString > & aPropertyNames );
+
+private:
+ ConfigItemListener & m_rListener;
+ ::std::set< OUString > m_aPropertiesToNotify;
+};
+
+ChartConfigItem::ChartConfigItem( ConfigItemListener & rListener ) :
+ ::utl::ConfigItem( C2U("Office.Chart/DefaultColor")),
+ m_rListener( rListener )
+{}
+
+ChartConfigItem::~ChartConfigItem()
+{}
+
+void ChartConfigItem::Notify( const Sequence< OUString > & aPropertyNames )
+{
+ for( sal_Int32 nIdx=0; nIdx<aPropertyNames.getLength(); ++nIdx )
+ {
+ if( m_aPropertiesToNotify.find( aPropertyNames[nIdx] ) != m_aPropertiesToNotify.end())
+ m_rListener.notify( aPropertyNames[nIdx] );
+ }
+}
+
+void ChartConfigItem::Commit()
+{}
+
+void ChartConfigItem::addPropertyNotification( const OUString & rPropertyName )
+{
+ m_aPropertiesToNotify.insert( rPropertyName );
+ EnableNotification( ContainerHelper::ContainerToSequence( m_aPropertiesToNotify ));
+}
+
+uno::Any ChartConfigItem::getProperty( const OUString & aPropertyName )
+{
+ Sequence< uno::Any > aValues(
+ GetProperties( Sequence< OUString >( &aPropertyName, 1 )));
+ if( ! aValues.getLength())
+ return uno::Any();
+ return aValues[0];
+}
+
+} // namespace impl
+
+// --------------------------------------------------------------------------------
+
+// explicit
+ConfigColorScheme::ConfigColorScheme(
+ const Reference< uno::XComponentContext > & xContext ) :
+ m_xContext( xContext ),
+ m_nNumberOfColors( 0 ),
+ m_bNeedsUpdate( true )
+{
+}
+
+ConfigColorScheme::~ConfigColorScheme()
+{}
+
+void ConfigColorScheme::retrieveConfigColors()
+{
+ if( ! m_xContext.is())
+ return;
+
+ // create config item if necessary
+ if( ! m_apChartConfigItem.get())
+ {
+ m_apChartConfigItem.reset(
+ new impl::ChartConfigItem( *this ));
+ m_apChartConfigItem->addPropertyNotification( aSeriesPropName );
+ }
+ OSL_ASSERT( m_apChartConfigItem.get());
+ if( ! m_apChartConfigItem.get())
+ return;
+
+ // retrieve colors
+ uno::Any aValue(
+ m_apChartConfigItem->getProperty( aSeriesPropName ));
+ if( aValue >>= m_aColorSequence )
+ m_nNumberOfColors = m_aColorSequence.getLength();
+ m_bNeedsUpdate = false;
+}
+
+// ____ XColorScheme ____
+::sal_Int32 SAL_CALL ConfigColorScheme::getColorByIndex( ::sal_Int32 nIndex )
+ throw (uno::RuntimeException)
+{
+ if( m_bNeedsUpdate )
+ retrieveConfigColors();
+
+ if( m_nNumberOfColors > 0 )
+ return static_cast< sal_Int32 >( m_aColorSequence[ nIndex % m_nNumberOfColors ] );
+
+ // fall-back: hard-coded standard colors
+ static sal_Int32 nDefaultColors[] = {
+ 0x9999ff, 0x993366, 0xffffcc,
+ 0xccffff, 0x660066, 0xff8080,
+ 0x0066cc, 0xccccff, 0x000080,
+ 0xff00ff, 0x00ffff, 0xffff00
+ };
+
+ static const sal_Int32 nMaxDefaultColors = sizeof( nDefaultColors ) / sizeof( sal_Int32 );
+ return nDefaultColors[ nIndex % nMaxDefaultColors ];
+}
+
+void ConfigColorScheme::notify( const OUString & rPropertyName )
+{
+ if( rPropertyName.equals( aSeriesPropName ))
+ m_bNeedsUpdate = true;
+}
+
+// ================================================================================
+
+Sequence< OUString > ConfigColorScheme::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 1 );
+ aServices[ 0 ] = C2U( "com.sun.star.chart2.ColorScheme" );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( ConfigColorScheme,
+ C2U( "com.sun.star.comp.chart2.ConfigDefaultColorScheme" ))
+
+// ================================================================================
+
+} // namespace chart
diff --git a/chart2/source/tools/ControllerLockGuard.cxx b/chart2/source/tools/ControllerLockGuard.cxx
new file mode 100644
index 000000000000..4ef430c5e483
--- /dev/null
+++ b/chart2/source/tools/ControllerLockGuard.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ControllerLockGuard.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+ControllerLockGuard::ControllerLockGuard( const Reference< frame::XModel > & xModel ) :
+ m_xModel( xModel )
+{
+ if( m_xModel.is())
+ m_xModel->lockControllers();
+}
+
+ControllerLockGuard::~ControllerLockGuard()
+{
+ if( m_xModel.is())
+ m_xModel->unlockControllers();
+}
+
+// ================================================================================
+
+ControllerLockHelper::ControllerLockHelper( const Reference< frame::XModel > & xModel ) :
+ m_xModel( xModel )
+{}
+
+ControllerLockHelper::~ControllerLockHelper()
+{}
+
+void ControllerLockHelper::lockControllers()
+{
+ if( m_xModel.is())
+ m_xModel->lockControllers();
+}
+
+void ControllerLockHelper::unlockControllers()
+{
+ if( m_xModel.is())
+ m_xModel->unlockControllers();
+}
+
+// ================================================================================
+
+ControllerLockHelperGuard::ControllerLockHelperGuard( ControllerLockHelper & rHelper ) :
+ m_rHelper( rHelper )
+{
+ m_rHelper.lockControllers();
+}
+
+ControllerLockHelperGuard::~ControllerLockHelperGuard()
+{
+ m_rHelper.unlockControllers();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/DataSeriesHelper.cxx b/chart2/source/tools/DataSeriesHelper.cxx
new file mode 100644
index 000000000000..acff332d4229
--- /dev/null
+++ b/chart2/source/tools/DataSeriesHelper.cxx
@@ -0,0 +1,918 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "DataSeriesHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "DataSource.hxx"
+#include "macros.hxx"
+#include "ContainerHelper.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
+#include <com/sun/star/chart2/StackingDirection.hpp>
+#include <com/sun/star/chart2/data/LabelOrigin.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/SymbolStyle.hpp>
+#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+
+
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#include <functional>
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <set>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ----------------------------------------
+namespace
+{
+
+class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
+{
+public:
+ explicit lcl_MatchesRole( const OUString & aRole, bool bMatchPrefix ) :
+ m_aRole( aRole ),
+ m_bMatchPrefix( bMatchPrefix )
+ {}
+
+ bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
+ {
+ if(!xSeq.is())
+ return false;
+ Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
+ OUString aRole;
+
+ if( m_bMatchPrefix )
+ return ( xProp.is() &&
+ (xProp->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
+ aRole.match( m_aRole ));
+
+ return ( xProp.is() &&
+ (xProp->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
+ m_aRole.equals( aRole ));
+ }
+
+private:
+ OUString m_aRole;
+ bool m_bMatchPrefix;
+};
+
+Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
+ const Reference< chart2::data::XDataSource > & xDataSource )
+{
+ Reference< chart2::data::XLabeledDataSequence > xResult;
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
+
+ for( sal_Int32 i=0; i<aSequences.getLength(); ++i )
+ {
+ OSL_ENSURE( aSequences[i].is(), "empty LabeledDataSequence" );
+ // no values are set but a label exists
+ if( aSequences[i].is() &&
+ ( ! aSequences[i]->getValues().is() &&
+ aSequences[i]->getLabel().is()))
+ {
+ xResult.set( aSequences[i] );
+ break;
+ }
+ }
+
+ return xResult;
+}
+
+void lcl_getCooSysAndChartTypeOfSeries(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const Reference< chart2::XDiagram > & xDiagram,
+ Reference< chart2::XCoordinateSystem > & xOutCooSys,
+ Reference< chart2::XChartType > & xOutChartType )
+{
+ Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
+ if( xCooSysCnt.is())
+ {
+ Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
+ for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
+ {
+ Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
+ Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
+ for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
+ {
+ Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
+ if( xSeriesCnt.is())
+ {
+ Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
+ for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
+ {
+ if( aSeries[nSeriesIdx] == xSeries )
+ {
+ xOutCooSys.set( aCooSysSeq[nCooSysIdx] );
+ xOutChartType.set( aChartTypes[nCTIdx] );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries, bool bInsert )
+{
+ try
+ {
+ Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
+ if( xSeriesProperties.is() )
+ {
+ DataPointLabel aLabelAtSeries;
+ xSeriesProperties->getPropertyValue( C2U( "Label" ) ) >>= aLabelAtSeries;
+ aLabelAtSeries.ShowNumber = bInsert;
+ if( !bInsert )
+ {
+ aLabelAtSeries.ShowNumberInPercent = false;
+ aLabelAtSeries.ShowCategoryName = false;
+ }
+ xSeriesProperties->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabelAtSeries ) );
+ uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
+ {
+ for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
+ {
+ Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
+ if( xPointProp.is() )
+ {
+ DataPointLabel aLabel;
+ xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
+ aLabel.ShowNumber = bInsert;
+ if( !bInsert )
+ {
+ aLabel.ShowNumberInPercent = false;
+ aLabel.ShowCategoryName = false;
+ }
+ xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+}
+
+} // anonymous namespace
+// ----------------------------------------
+
+namespace chart
+{
+
+namespace DataSeriesHelper
+{
+
+OUString GetRole( const uno::Reference< chart2::data::XLabeledDataSequence >& xLabeledDataSequence )
+{
+ OUString aRet;
+ if( xLabeledDataSequence.is() )
+ {
+ Reference< beans::XPropertySet > xProp( xLabeledDataSequence->getValues(), uno::UNO_QUERY );
+ if( xProp.is() )
+ xProp->getPropertyValue( C2U("Role") ) >>= aRet;
+ }
+ return aRet;
+}
+
+Reference< chart2::data::XLabeledDataSequence >
+ getDataSequenceByRole(
+ const Reference< chart2::data::XDataSource > & xSource, OUString aRole,
+ bool bMatchPrefix /* = false */ )
+{
+ Reference< chart2::data::XLabeledDataSequence > aNoResult;
+ if( ! xSource.is())
+ return aNoResult;
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq( xSource->getDataSequences());
+
+ const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
+ const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
+ const Reference< chart2::data::XLabeledDataSequence > * pMatch =
+ ::std::find_if( pBegin, pEnd, lcl_MatchesRole( aRole, bMatchPrefix ));
+
+ if( pMatch != pEnd )
+ return *pMatch;
+
+ return aNoResult;
+}
+
+::std::vector< Reference< chart2::data::XLabeledDataSequence > >
+ getAllDataSequencesByRole( const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aDataSequences,
+ OUString aRole, bool bMatchPrefix /* = false */ )
+{
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVec;
+ ::std::remove_copy_if( aDataSequences.getConstArray(), aDataSequences.getConstArray() + aDataSequences.getLength(),
+ ::std::back_inserter( aResultVec ),
+ ::std::not1( lcl_MatchesRole( aRole, bMatchPrefix )));
+ return aResultVec;
+}
+
+Reference< chart2::data::XDataSource >
+ getDataSource( const Sequence< Reference< chart2::XDataSeries > > & aSeries )
+{
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVec;
+
+ for( sal_Int32 i = 0; i < aSeries.getLength(); ++i )
+ {
+ Reference< chart2::data::XDataSource > xSource( aSeries[ i ], uno::UNO_QUERY );
+ if( xSource.is())
+ {
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
+ ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
+ ::std::back_inserter( aSeqVec ));
+ }
+ }
+
+ return Reference< chart2::data::XDataSource >(
+ new DataSource( ContainerHelper::ContainerToSequence( aSeqVec )));
+}
+
+namespace
+{
+OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence )
+{
+ OUString aResult;
+
+ Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY );
+ if( xTextSeq.is())
+ {
+ Sequence< OUString > aSeq( xTextSeq->getTextualData());
+
+ const sal_Int32 nMax = aSeq.getLength() - 1;
+ OUString aVal;
+ OUStringBuffer aBuf;
+
+ for( sal_Int32 i = 0; i <= nMax; ++i )
+ {
+ aBuf.append( aSeq[i] );
+ if( i < nMax )
+ aBuf.append( sal_Unicode( ' ' ));
+ }
+ aResult = aBuf.makeStringAndClear();
+ }
+ else if( xSequence.is())
+ {
+ Sequence< uno::Any > aSeq( xSequence->getData());
+
+ const sal_Int32 nMax = aSeq.getLength() - 1;
+ OUString aVal;
+ OUStringBuffer aBuf;
+ double fNum = 0;
+
+ for( sal_Int32 i = 0; i <= nMax; ++i )
+ {
+ if( aSeq[i] >>= aVal )
+ {
+ aBuf.append( aVal );
+ if( i < nMax )
+ aBuf.append( sal_Unicode( ' ' ));
+ }
+ else if( aSeq[ i ] >>= fNum )
+ {
+ aBuf.append( fNum );
+ if( i < nMax )
+ aBuf.append( sal_Unicode( ' ' ));
+ }
+ }
+ aResult = aBuf.makeStringAndClear();
+ }
+
+ return aResult;
+}
+}
+
+OUString getLabelForLabeledDataSequence(
+ const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq )
+{
+ OUString aResult;
+ if( xLabeledSeq.is())
+ {
+ Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
+ if( xSeq.is() )
+ aResult = lcl_getDataSequenceLabel( xSeq );
+ if( !xSeq.is() || !aResult.getLength() )
+ {
+ // no label set or label content is empty -> use auto-generated one
+ Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
+ if( xValueSeq.is() )
+ {
+ Sequence< OUString > aLabels( xValueSeq->generateLabel(
+ chart2::data::LabelOrigin_SHORT_SIDE ) );
+ // no labels returned is interpreted as: auto-generation not
+ // supported by sequence
+ if( aLabels.getLength() )
+ aResult=aLabels[0];
+ else
+ {
+ //todo?: maybe use the index of the series as name
+ //but as the index may change it would be better to have such a name persistent
+ //what is not possible at the moment
+ //--> maybe use the identifier as part of the name ...
+ aResult = lcl_getDataSequenceLabel( xValueSeq );
+ }
+ }
+ }
+ }
+ return aResult;
+}
+
+OUString getDataSeriesLabel(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const OUString & rLabelSequenceRole )
+{
+ OUString aResult;
+
+ Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
+ if( xSource.is())
+ {
+ Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
+ ::chart::DataSeriesHelper::getDataSequenceByRole( xSource, rLabelSequenceRole ));
+ if( xLabeledSeq.is())
+ aResult = getLabelForLabeledDataSequence( xLabeledSeq );
+ else
+ {
+ // special case: labeled data series with only a label and no values may
+ // serve as label
+ xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( xSource ));
+ if( xLabeledSeq.is())
+ {
+ Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
+ if( xSeq.is())
+ aResult = lcl_getDataSequenceLabel( xSeq );
+ }
+ }
+
+ }
+
+ return aResult;
+}
+
+void setStackModeAtSeries(
+ const Sequence< Reference< chart2::XDataSeries > > & aSeries,
+ const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
+ StackMode eStackMode )
+{
+ if( eStackMode == StackMode_AMBIGUOUS )
+ return;
+
+ const OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "StackingDirection" ));
+ const uno::Any aPropValue = uno::makeAny(
+ ( (eStackMode == StackMode_Y_STACKED) ||
+ (eStackMode == StackMode_Y_STACKED_PERCENT) )
+ ? chart2::StackingDirection_Y_STACKING
+ : (eStackMode == StackMode_Z_STACKED )
+ ? chart2::StackingDirection_Z_STACKING
+ : chart2::StackingDirection_NO_STACKING );
+
+ std::set< sal_Int32 > aAxisIndexSet;
+ for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
+ {
+ try
+ {
+ Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ xProp->setPropertyValue( aPropName, aPropValue );
+
+ sal_Int32 nAxisIndex;
+ xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nAxisIndex;
+ aAxisIndexSet.insert(nAxisIndex);
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ if( xCorrespondingCoordinateSystem.is() &&
+ 1 < xCorrespondingCoordinateSystem->getDimension() )
+ {
+ sal_Int32 nAxisIndexCount = aAxisIndexSet.size();
+ if( !nAxisIndexCount )
+ {
+ aAxisIndexSet.insert(0);
+ nAxisIndexCount = aAxisIndexSet.size();
+ }
+
+ for( ::std::set< sal_Int32 >::const_iterator aIt = aAxisIndexSet.begin();
+ aIt != aAxisIndexSet.end(); ++aIt )
+ {
+ sal_Int32 nAxisIndex = *aIt;
+ Reference< chart2::XAxis > xAxis(
+ xCorrespondingCoordinateSystem->getAxisByDimension( 1, nAxisIndex ));
+ if( xAxis.is())
+ {
+ sal_Bool bPercent = (eStackMode == StackMode_Y_STACKED_PERCENT);
+ chart2::ScaleData aScaleData = xAxis->getScaleData();
+
+ if( bPercent != (aScaleData.AxisType==chart2::AxisType::PERCENT) )
+ {
+ if( bPercent )
+ aScaleData.AxisType = chart2::AxisType::PERCENT;
+ else
+ aScaleData.AxisType = chart2::AxisType::REALNUMBER;
+ xAxis->setScaleData( aScaleData );
+ }
+ }
+ }
+ }
+}
+
+sal_Int32 getAttachedAxisIndex( const Reference< chart2::XDataSeries > & xSeries )
+{
+ sal_Int32 nRet = 0;
+ try
+ {
+ Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nRet;
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return nRet;
+}
+
+sal_Int32 getNumberFormatKeyFromAxis(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
+ sal_Int32 nDimensionIndex,
+ sal_Int32 nAxisIndex /* = -1 */ )
+{
+ sal_Int32 nResult = 0;
+ if( nAxisIndex == -1 )
+ nAxisIndex = getAttachedAxisIndex( xSeries );
+ try
+ {
+ Reference< beans::XPropertySet > xAxisProp(
+ xCorrespondingCoordinateSystem->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
+ if( xAxisProp.is())
+ xAxisProp->getPropertyValue( C2U("NumberFormat")) >>= nResult;
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return nResult;
+}
+
+Reference< chart2::XCoordinateSystem > getCoordinateSystemOfSeries(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const Reference< chart2::XDiagram > & xDiagram )
+{
+ Reference< chart2::XCoordinateSystem > xResult;
+ Reference< chart2::XChartType > xDummy;
+ lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xResult, xDummy );
+
+ return xResult;
+}
+
+Reference< chart2::XChartType > getChartTypeOfSeries(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const Reference< chart2::XDiagram > & xDiagram )
+{
+ Reference< chart2::XChartType > xResult;
+ Reference< chart2::XCoordinateSystem > xDummy;
+ lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xDummy, xResult );
+
+ return xResult;
+}
+
+void deleteSeries(
+ const Reference< chart2::XDataSeries > & xSeries,
+ const Reference< chart2::XChartType > & xChartType )
+{
+ try
+ {
+ Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
+ ::std::vector< Reference< chart2::XDataSeries > > aSeries(
+ ContainerHelper::SequenceToVector( xSeriesCnt->getDataSeries()));
+ ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt =
+ ::std::find( aSeries.begin(), aSeries.end(), xSeries );
+ if( aIt != aSeries.end())
+ {
+ aSeries.erase( aIt );
+ xSeriesCnt->setDataSeries( ContainerHelper::ContainerToSequence( aSeries ));
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void switchSymbolsOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties,
+ bool bSymbolsOn, sal_Int32 nSeriesIndex )
+{
+ if( !xSeriesProperties.is() )
+ return;
+
+ chart2::Symbol aSymbProp;
+ if( (xSeriesProperties->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp ) )
+ {
+ if( !bSymbolsOn )
+ aSymbProp.Style = chart2::SymbolStyle_NONE;
+ else if( aSymbProp.Style == chart2::SymbolStyle_NONE )
+ {
+ aSymbProp.Style = chart2::SymbolStyle_STANDARD;
+ aSymbProp.StandardSymbol = nSeriesIndex;
+ }
+ xSeriesProperties->setPropertyValue( C2U( "Symbol" ), uno::makeAny( aSymbProp ));
+ }
+ //todo: check attributed data points
+}
+
+void switchLinesOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bLinesOn )
+{
+ if( !xSeriesProperties.is() )
+ return;
+
+ if( bLinesOn )
+ {
+ // keep line-styles that are not NONE
+ drawing::LineStyle eLineStyle;
+ if( (xSeriesProperties->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle ) &&
+ eLineStyle == drawing::LineStyle_NONE )
+ {
+ xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) );
+ }
+ }
+ else
+ xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
+}
+
+void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesProperties, bool bThick )
+{
+ if( !xSeriesProperties.is() )
+ return;
+
+ sal_Int32 nNewValue = bThick ? 80 : 0;
+ sal_Int32 nOldValue = 0;
+ if( (xSeriesProperties->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue ) &&
+ nOldValue != nNewValue )
+ {
+ if( !(bThick && nOldValue>0))
+ xSeriesProperties->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( nNewValue ) );
+ }
+}
+
+void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSeries >& xSeries,
+ const OUString& rPropertyName, const uno::Any& rPropertyValue )
+{
+ Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
+ if( !xSeriesProperties.is() )
+ return;
+
+ xSeriesProperties->setPropertyValue( rPropertyName, rPropertyValue );
+ uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
+ {
+ for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
+ {
+ Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
+ if(!xPointProp.is())
+ continue;
+ xPointProp->setPropertyValue( rPropertyName, rPropertyValue );
+ }
+ }
+}
+
+bool hasAttributedDataPointDifferentValue( const Reference< chart2::XDataSeries >& xSeries,
+ const OUString& rPropertyName, const uno::Any& rPropertyValue )
+{
+ Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
+ if( !xSeriesProperties.is() )
+ return false;
+
+ uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
+ {
+ for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
+ {
+ Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
+ if(!xPointProp.is())
+ continue;
+ uno::Any aPointValue( xPointProp->getPropertyValue( rPropertyName ) );
+ if( !( rPropertyValue==aPointValue ) )
+ return true;
+ }
+ }
+ return false;
+}
+
+bool areAllSeriesAttachedToSameAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 & rOutAxisIndex )
+{
+ try
+ {
+ uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY_THROW );
+ uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDataSeriesContainer->getDataSeries());
+
+ const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
+ // AxisIndex can only be 0 or 1
+ sal_Int32 nSeriesAtFirstAxis = 0;
+ sal_Int32 nSeriesAtSecondAxis = 0;
+
+ for( sal_Int32 nI = 0; nI < nSeriesCount; ++nI )
+ {
+ uno::Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nI], uno::UNO_QUERY );
+ sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex( xSeries );
+ if( nAxisIndex == 0 )
+ ++nSeriesAtFirstAxis;
+ else if( nAxisIndex == 1 )
+ ++nSeriesAtSecondAxis;
+ }
+ OSL_ENSURE( nSeriesAtFirstAxis + nSeriesAtSecondAxis == nSeriesCount, "Invalid axis index found" );
+
+ if( nSeriesAtFirstAxis == nSeriesCount )
+ rOutAxisIndex = 0;
+ else if( nSeriesAtSecondAxis == nSeriesCount )
+ rOutAxisIndex = 1;
+
+ return ( nSeriesAtFirstAxis == nSeriesCount ||
+ nSeriesAtSecondAxis == nSeriesCount );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ return false;
+ }
+}
+
+namespace
+{
+
+bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
+{
+ if( !xDataSequence.is() )
+ return false;
+ uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ uno::Sequence< sal_Int32 > aHiddenValues;
+ try
+ {
+ xProp->getPropertyValue( C2U( "HiddenValues" ) ) >>= aHiddenValues;
+ if( !aHiddenValues.getLength() )
+ return true;
+ }
+ catch( uno::Exception& e )
+ {
+ (void)e; // avoid warning
+ return true;
+ }
+ }
+ if( xDataSequence->getData().getLength() )
+ return true;
+ return false;
+}
+
+}
+
+bool hasUnhiddenData( const uno::Reference< chart2::XDataSeries >& xSeries )
+{
+ uno::Reference< chart2::data::XDataSource > xDataSource =
+ uno::Reference< chart2::data::XDataSource >( xSeries, uno::UNO_QUERY );
+
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDataSequences = xDataSource->getDataSequences();
+
+ for(sal_Int32 nN = aDataSequences.getLength();nN--;)
+ {
+ if( !aDataSequences[nN].is() )
+ continue;
+ if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getValues() ) )
+ return true;
+ if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getLabel() ) )
+ return true;
+ }
+ return false;
+}
+
+struct lcl_LessIndex
+{
+ inline bool operator() ( const sal_Int32& first, const sal_Int32& second )
+ {
+ return ( first < second );
+ }
+};
+
+sal_Int32 translateIndexFromHiddenToFullSequence( sal_Int32 nIndex, const Reference< chart2::data::XDataSequence >& xDataSequence, bool bTranslate )
+{
+ if( !bTranslate )
+ return nIndex;
+
+ try
+ {
+ uno::Reference<beans::XPropertySet> xProp( xDataSequence, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ Sequence<sal_Int32> aHiddenIndicesSeq;
+ xProp->getPropertyValue( C2U("HiddenValues") ) >>= aHiddenIndicesSeq;
+ if( aHiddenIndicesSeq.getLength() )
+ {
+ ::std::vector< sal_Int32 > aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq ) );
+ ::std::sort( aHiddenIndices.begin(), aHiddenIndices.end(), lcl_LessIndex() );
+
+ sal_Int32 nHiddenCount = static_cast<sal_Int32>(aHiddenIndices.size());
+ for( sal_Int32 nN = 0; nN < nHiddenCount; ++nN)
+ {
+ if( aHiddenIndices[nN] <= nIndex )
+ nIndex += 1;
+ else
+ break;
+ }
+ }
+ }
+ }
+ catch (const beans::UnknownPropertyException&)
+ {
+ }
+ return nIndex;
+}
+
+bool hasDataLabelsAtSeries( const Reference< chart2::XDataSeries >& xSeries )
+{
+ bool bRet = false;
+ try
+ {
+ Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ DataPointLabel aLabel;
+ if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
+ bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ return bRet;
+}
+
+bool hasDataLabelsAtPoints( const Reference< chart2::XDataSeries >& xSeries )
+{
+ bool bRet = false;
+ try
+ {
+ Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
+ if( xSeriesProperties.is() )
+ {
+ uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
+ {
+ for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
+ {
+ Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
+ if( xPointProp.is() )
+ {
+ DataPointLabel aLabel;
+ if( (xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
+ bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
+ if( bRet )
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ return bRet;
+}
+
+bool hasDataLabelAtPoint( const Reference< chart2::XDataSeries >& xSeries, sal_Int32 nPointIndex )
+{
+ bool bRet = false;
+ try
+ {
+ Reference< beans::XPropertySet > xProp;
+ Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
+ if( xSeriesProperties.is() )
+ {
+ uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
+ if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
+ {
+ ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
+ ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
+ if( aIt != aIndices.end())
+ xProp = xSeries->getDataPointByIndex(nPointIndex);
+ else
+ xProp = xSeriesProperties;
+ }
+ if( xProp.is() )
+ {
+ DataPointLabel aLabel;
+ if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
+ bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
+ }
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ return bRet;
+}
+
+void insertDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
+{
+ lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, true /*bInsert*/ );
+}
+
+void deleteDataLabelsFromSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
+{
+ lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, false /*bInsert*/ );
+}
+
+
+void insertDataLabelToPoint( const Reference< beans::XPropertySet >& xPointProp )
+{
+ try
+ {
+ if( xPointProp.is() )
+ {
+ DataPointLabel aLabel;
+ xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
+ aLabel.ShowNumber = true;
+ xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+}
+
+void deleteDataLabelsFromPoint( const Reference< beans::XPropertySet >& xPointProp )
+{
+ try
+ {
+ if( xPointProp.is() )
+ {
+ DataPointLabel aLabel;
+ xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
+ aLabel.ShowNumber = false;
+ aLabel.ShowNumberInPercent = false;
+ aLabel.ShowCategoryName = false;
+ xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
+ }
+ }
+ catch( uno::Exception &e)
+ {
+ ASSERT_EXCEPTION( e );
+ }
+}
+
+} // namespace DataSeriesHelper
+} // namespace chart
diff --git a/chart2/source/tools/DataSource.cxx b/chart2/source/tools/DataSource.cxx
new file mode 100644
index 000000000000..edbf4dfacfeb
--- /dev/null
+++ b/chart2/source/tools/DataSource.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "DataSource.hxx"
+#include "LabeledDataSequence.hxx"
+
+using ::rtl::OUString;
+using ::osl::MutexGuard;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Any;
+
+using namespace ::com::sun::star;
+
+namespace
+{
+static const ::rtl::OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.DataSource" ));
+} // anonymous namespace
+
+namespace chart
+{
+
+DataSource::DataSource(
+ const Reference< uno::XComponentContext > & /*xContext*/ )
+{}
+
+DataSource::DataSource(
+ const Sequence< Reference< chart2::data::XLabeledDataSequence > > & rSequences ) :
+ m_aDataSeq( rSequences )
+{}
+
+DataSource::~DataSource()
+{}
+
+// ____ XDataSource ____
+Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL DataSource::getDataSequences()
+ throw (uno::RuntimeException)
+{
+ return m_aDataSeq;
+}
+
+// ____ XDataSink ____
+void SAL_CALL DataSource::setData( const Sequence< Reference< chart2::data::XLabeledDataSequence > >& aData )
+ throw (uno::RuntimeException)
+{
+ m_aDataSeq = aData;
+}
+
+// ================================================================================
+
+Sequence< OUString > DataSource::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 1 );
+ aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataSource" ));
+ return aServices;
+}
+
+// ================================================================================
+
+APPHELPER_XSERVICEINFO_IMPL( DataSource, lcl_aServiceName );
+
+} // namespace chart
diff --git a/chart2/source/tools/DataSourceHelper.cxx b/chart2/source/tools/DataSourceHelper.cxx
new file mode 100644
index 000000000000..0cc6ef4a4315
--- /dev/null
+++ b/chart2/source/tools/DataSourceHelper.cxx
@@ -0,0 +1,552 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "DataSourceHelper.hxx"
+#include "macros.hxx"
+#include "ChartModelHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "DataSeriesHelper.hxx"
+#include "DataSource.hxx"
+#include "ContainerHelper.hxx"
+#include "ControllerLockGuard.hxx"
+#include "PropertyHelper.hxx"
+#include "CachedDataSequence.hxx"
+#include "LabeledDataSequence.hxx"
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace
+{
+void lcl_addRanges( ::std::vector< ::rtl::OUString > & rOutResult,
+ const uno::Reference< data::XLabeledDataSequence > & xLabeledSeq )
+{
+ if( ! xLabeledSeq.is())
+ return;
+ uno::Reference< data::XDataSequence > xSeq( xLabeledSeq->getLabel());
+ if( xSeq.is())
+ rOutResult.push_back( xSeq->getSourceRangeRepresentation());
+ xSeq.set( xLabeledSeq->getValues());
+ if( xSeq.is())
+ rOutResult.push_back( xSeq->getSourceRangeRepresentation());
+}
+
+void lcl_addDataSourceRanges(
+ ::std::vector< ::rtl::OUString > & rOutResult,
+ const uno::Reference< data::XDataSource > & xDataSource )
+{
+ if( xDataSource.is() )
+ {
+ uno::Sequence< uno::Reference< data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
+ for( sal_Int32 i=0; i<aDataSequences.getLength(); ++i)
+ lcl_addRanges( rOutResult, aDataSequences[i] );
+ }
+}
+
+void lcl_addErrorBarRanges(
+ ::std::vector< ::rtl::OUString > & rOutResult,
+ const uno::Reference< XDataSeries > & xDataSeries )
+{
+ uno::Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
+ if( !xSeriesProp.is())
+ return;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xErrorBarProp;
+ if( ( xSeriesProp->getPropertyValue( C2U("ErrorBarY")) >>= xErrorBarProp ) &&
+ xErrorBarProp.is())
+ {
+ sal_Int32 eStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
+ if( ( xErrorBarProp->getPropertyValue( C2U("ErrorBarStyle")) >>= eStyle ) &&
+ eStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA )
+ {
+ uno::Reference< data::XDataSource > xErrorBarDataSource( xErrorBarProp, uno::UNO_QUERY );
+ if( xErrorBarDataSource.is() )
+ lcl_addDataSourceRanges( rOutResult, xErrorBarDataSource );
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+} // anonymous namespace
+
+Reference< chart2::data::XDataSource > DataSourceHelper::createDataSource(
+ const Sequence< Reference< chart2::data::XLabeledDataSequence > >& rSequences )
+{
+ return new DataSource(rSequences);
+}
+
+Reference< chart2::data::XDataSequence > DataSourceHelper::createCachedDataSequence()
+{
+ return new ::chart::CachedDataSequence();
+}
+
+Reference< chart2::data::XDataSequence > DataSourceHelper::createCachedDataSequence( const ::rtl::OUString& rSingleText )
+{
+ return new ::chart::CachedDataSequence( rSingleText );
+}
+
+Reference< chart2::data::XLabeledDataSequence > DataSourceHelper::createLabeledDataSequence(
+ const Reference< chart2::data::XDataSequence >& xValues ,
+ const Reference< chart2::data::XDataSequence >& xLabels )
+{
+ return new ::chart::LabeledDataSequence( xValues, xLabels );
+}
+
+Reference< chart2::data::XLabeledDataSequence > DataSourceHelper::createLabeledDataSequence(
+ const Reference< chart2::data::XDataSequence >& xValues )
+{
+ return new ::chart::LabeledDataSequence( xValues );
+}
+
+Reference< chart2::data::XLabeledDataSequence > DataSourceHelper::createLabeledDataSequence(
+ const Reference< uno::XComponentContext >& xContext )
+{
+ return new ::chart::LabeledDataSequence( xContext );
+}
+
+uno::Sequence< beans::PropertyValue > DataSourceHelper::createArguments(
+ bool bUseColumns, bool bFirstCellAsLabel, bool bHasCategories )
+{
+ ::com::sun::star::chart::ChartDataRowSource eRowSource = ::com::sun::star::chart::ChartDataRowSource_ROWS;
+ if( bUseColumns )
+ eRowSource = ::com::sun::star::chart::ChartDataRowSource_COLUMNS;
+
+ uno::Sequence< beans::PropertyValue > aArguments(3);
+ aArguments[0] = beans::PropertyValue( C2U("DataRowSource")
+ , -1, uno::makeAny( eRowSource )
+ , beans::PropertyState_DIRECT_VALUE );
+ aArguments[1] = beans::PropertyValue( C2U("FirstCellAsLabel")
+ , -1, uno::makeAny( bFirstCellAsLabel )
+ , beans::PropertyState_DIRECT_VALUE );
+ aArguments[2] = beans::PropertyValue( C2U("HasCategories")
+ , -1, uno::makeAny( bHasCategories )
+ , beans::PropertyState_DIRECT_VALUE );
+
+ return aArguments;
+}
+
+uno::Sequence< beans::PropertyValue > DataSourceHelper::createArguments(
+ const ::rtl::OUString & rRangeRepresentation,
+ const uno::Sequence< sal_Int32 >& rSequenceMapping,
+ bool bUseColumns, bool bFirstCellAsLabel, bool bHasCategories )
+{
+ uno::Sequence< beans::PropertyValue > aArguments( createArguments( bUseColumns, bFirstCellAsLabel, bHasCategories ));
+ aArguments.realloc( aArguments.getLength() + 1 );
+ aArguments[aArguments.getLength() - 1] =
+ beans::PropertyValue( C2U("CellRangeRepresentation")
+ , -1, uno::makeAny( rRangeRepresentation )
+ , beans::PropertyState_DIRECT_VALUE );
+ if( rSequenceMapping.getLength() )
+ {
+ aArguments.realloc( aArguments.getLength() + 1 );
+ aArguments[aArguments.getLength() - 1] =
+ beans::PropertyValue( C2U("SequenceMapping")
+ , -1, uno::makeAny( rSequenceMapping )
+ , beans::PropertyState_DIRECT_VALUE );
+ }
+ return aArguments;
+}
+
+void DataSourceHelper::readArguments( const uno::Sequence< beans::PropertyValue >& rArguments
+ , ::rtl::OUString & rRangeRepresentation, uno::Sequence< sal_Int32 >& rSequenceMapping
+ , bool& bUseColumns, bool& bFirstCellAsLabel, bool& bHasCategories )
+{
+ const beans::PropertyValue* pArguments = rArguments.getConstArray();
+ for(sal_Int32 i=0; i<rArguments.getLength(); ++i, ++pArguments)
+ {
+ const beans::PropertyValue& aProperty = *pArguments;
+ if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DataRowSource" ) ))
+ {
+ ::com::sun::star::chart::ChartDataRowSource eRowSource;
+ if( aProperty.Value >>= eRowSource )
+ bUseColumns = (eRowSource==::com::sun::star::chart::ChartDataRowSource_COLUMNS);
+ }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FirstCellAsLabel" ) ))
+ {
+ aProperty.Value >>= bFirstCellAsLabel;
+ }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasCategories" ) ))
+ {
+ aProperty.Value >>= bHasCategories;
+ }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CellRangeRepresentation" ) ))
+ {
+ aProperty.Value >>= rRangeRepresentation;
+ }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SequenceMapping" ) ))
+ {
+ aProperty.Value >>= rSequenceMapping;
+ }
+ }
+}
+
+uno::Reference< chart2::data::XDataSource > DataSourceHelper::pressUsedDataIntoRectangularFormat(
+ const uno::Reference< chart2::XChartDocument >& xChartDoc, bool bWithCategories )
+{
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVector;
+
+ //categories are always the first sequence
+ Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
+
+ if( bWithCategories )
+ {
+ Reference< chart2::data::XLabeledDataSequence > xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram ) );
+ if( xCategories.is() )
+ aResultVector.push_back( xCategories );
+ }
+
+ ::std::vector< Reference< chart2::XDataSeries > > xSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ uno::Reference< chart2::data::XDataSource > xSeriesSource(
+ DataSeriesHelper::getDataSource( ContainerHelper::ContainerToSequence(xSeriesVector) ) );
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSeqences( xSeriesSource->getDataSequences() );
+
+ //the first x-values is always the next sequence //todo ... other x-values get lost for old format
+ Reference< chart2::data::XLabeledDataSequence > xXValues(
+ DataSeriesHelper::getDataSequenceByRole( xSeriesSource, C2U("values-x") ) );
+ if( xXValues.is() )
+ aResultVector.push_back( xXValues );
+
+ //add all other sequences now without x-values
+ for( sal_Int32 nN=0; nN<aDataSeqences.getLength(); nN++ )
+ {
+ OUString aRole( DataSeriesHelper::GetRole( aDataSeqences[nN] ) );
+ if( !aRole.equals(C2U("values-x")) )
+ aResultVector.push_back( aDataSeqences[nN] );
+ }
+
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aResultSequence( aResultVector.size() );
+ ::std::copy( aResultVector.begin(), aResultVector.end(), aResultSequence.getArray() );
+
+ return new DataSource( aResultSequence );
+}
+
+uno::Sequence< ::rtl::OUString > DataSourceHelper::getUsedDataRanges(
+ const uno::Reference< chart2::XDiagram > & xDiagram )
+{
+ ::std::vector< ::rtl::OUString > aResult;
+
+ if( xDiagram.is())
+ {
+ uno::Reference< data::XLabeledDataSequence > xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram ) );
+ if( xCategories.is() )
+ lcl_addRanges( aResult, xCategories );
+
+ ::std::vector< uno::Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ for( ::std::vector< uno::Reference< XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
+ ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
+ {
+ uno::Reference< data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
+ lcl_addDataSourceRanges( aResult, xDataSource );
+ lcl_addErrorBarRanges( aResult, *aSeriesIt );
+ }
+ }
+
+ return ContainerHelper::ContainerToSequence( aResult );
+}
+
+uno::Sequence< ::rtl::OUString > DataSourceHelper::getUsedDataRanges( const uno::Reference< frame::XModel > & xChartModel )
+{
+ uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ return getUsedDataRanges( xDiagram );
+}
+
+uno::Reference< chart2::data::XDataSource > DataSourceHelper::getUsedData(
+ const uno::Reference< chart2::XChartDocument >& xChartDoc )
+{
+ return pressUsedDataIntoRectangularFormat( xChartDoc );
+}
+
+uno::Reference< chart2::data::XDataSource > DataSourceHelper::getUsedData(
+ const uno::Reference< frame::XModel >& xChartModel )
+{
+ ::std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aResult;
+
+ uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ uno::Reference< data::XLabeledDataSequence > xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram ) );
+ if( xCategories.is() )
+ aResult.push_back( xCategories );
+
+ ::std::vector< uno::Reference< XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartModel ) );
+ for( ::std::vector< uno::Reference< XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
+ ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
+ {
+ uno::Reference< data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
+ if( !xDataSource.is() )
+ continue;
+ uno::Sequence< uno::Reference< data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
+ ::std::copy( aDataSequences.getConstArray(), aDataSequences.getConstArray() + aDataSequences.getLength(),
+ ::std::back_inserter( aResult ));
+ }
+
+ return uno::Reference< chart2::data::XDataSource >(
+ new DataSource( ContainerHelper::ContainerToSequence( aResult )));
+}
+
+bool DataSourceHelper::detectRangeSegmentation(
+ const uno::Reference<
+ frame::XModel >& xChartModel
+ , ::rtl::OUString& rOutRangeString
+ , ::com::sun::star::uno::Sequence< sal_Int32 >& rSequenceMapping
+ , bool& rOutUseColumns
+ , bool& rOutFirstCellAsLabel
+ , bool& rOutHasCategories )
+{
+ bool bSomethingDetected = false;
+
+ uno::Reference< XChartDocument > xChartDocument( xChartModel, uno::UNO_QUERY );
+ if( !xChartDocument.is() )
+ return bSomethingDetected;
+ uno::Reference< data::XDataProvider > xDataProvider( xChartDocument->getDataProvider() );
+ if( !xDataProvider.is() )
+ return bSomethingDetected;
+
+ try
+ {
+ DataSourceHelper::readArguments(
+ xDataProvider->detectArguments( pressUsedDataIntoRectangularFormat( xChartDocument ) ),
+ rOutRangeString, rSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
+ bSomethingDetected = (rOutRangeString.getLength() > 0);
+
+ uno::Reference< chart2::data::XLabeledDataSequence > xCategories(
+ DiagramHelper::getCategoriesFromDiagram( xChartDocument->getFirstDiagram() ));
+ rOutHasCategories = xCategories.is();
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return bSomethingDetected;
+}
+
+bool DataSourceHelper::allArgumentsForRectRangeDetected(
+ const uno::Reference< chart2::XChartDocument >& xChartDocument )
+{
+ bool bHasDataRowSource = false;
+ bool bHasFirstCellAsLabel = false;
+// bool bHasHasCategories = false;
+ bool bHasCellRangeRepresentation = false;
+// bool bHasSequenceMapping = false;
+
+ uno::Reference< data::XDataProvider > xDataProvider( xChartDocument->getDataProvider() );
+ if( !xDataProvider.is() )
+ return false;
+
+ try
+ {
+ const uno::Sequence< beans::PropertyValue > aArguments(
+ xDataProvider->detectArguments( pressUsedDataIntoRectangularFormat( xChartDocument )));
+ const beans::PropertyValue* pArguments = aArguments.getConstArray();
+ for(sal_Int32 i=0; i<aArguments.getLength(); ++i, ++pArguments)
+ {
+ const beans::PropertyValue& aProperty = *pArguments;
+ if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DataRowSource" ) ))
+ {
+ bHasDataRowSource =
+ (aProperty.Value.hasValue() && aProperty.Value.isExtractableTo(
+ ::getCppuType( reinterpret_cast<
+ const ::com::sun::star::chart::ChartDataRowSource * >(0))));
+ }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FirstCellAsLabel" ) ))
+ {
+ bHasFirstCellAsLabel =
+ (aProperty.Value.hasValue() && aProperty.Value.isExtractableTo(::getBooleanCppuType()));
+ }
+// else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HasCategories" ) ))
+// {
+// bHasHasCategories =
+// (aProperty.Value.hasValue() && aProperty.Value.isExtractableTo(::getBooleanCppuType()));
+// }
+ else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CellRangeRepresentation" ) ))
+ {
+ ::rtl::OUString aRange;
+ bHasCellRangeRepresentation =
+ (aProperty.Value.hasValue() && (aProperty.Value >>= aRange) && aRange.getLength() > 0);
+ }
+// else if( aProperty.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SequenceMapping" ) ))
+// {
+// bHasSequenceMapping =
+// (aProperty.Value.hasValue() && aProperty.Value.isExtractableTo(
+// ::getCppuType( reinterpret_cast<
+// const uno::Sequence< sal_Int32 > * >(0))));
+// }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return (bHasCellRangeRepresentation && bHasDataRowSource && bHasFirstCellAsLabel);
+}
+
+void DataSourceHelper::setRangeSegmentation(
+ const uno::Reference< frame::XModel >& xChartModel
+ , const ::com::sun::star::uno::Sequence< sal_Int32 >& rSequenceMapping
+ , bool bUseColumns , bool bFirstCellAsLabel, bool bUseCategories )
+{
+ uno::Reference< XChartDocument > xChartDocument( xChartModel, uno::UNO_QUERY );
+ if( !xChartDocument.is() )
+ return;
+ uno::Reference< data::XDataProvider > xDataProvider( xChartDocument->getDataProvider() );
+ if( !xDataProvider.is() )
+ return;
+ uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ if( !xDiagram.is() )
+ return;
+ uno::Reference< chart2::XChartTypeManager > xChartTypeManager( xChartDocument->getChartTypeManager() );
+ if( !xChartTypeManager.is() )
+ return;
+ uno::Reference< lang::XMultiServiceFactory > xTemplateFactory( xChartTypeManager, uno::UNO_QUERY );
+ if( !xTemplateFactory.is() )
+ return;
+
+ ::rtl::OUString aRangeString;
+ bool bDummy;
+ uno::Sequence< sal_Int32 > aDummy;
+ readArguments( xDataProvider->detectArguments( pressUsedDataIntoRectangularFormat( xChartDocument )),
+ aRangeString, aDummy, bDummy, bDummy, bDummy );
+
+ uno::Sequence< beans::PropertyValue > aArguments(
+ createArguments( aRangeString, rSequenceMapping, bUseColumns, bFirstCellAsLabel, bUseCategories ) );
+
+ uno::Reference< chart2::data::XDataSource > xDataSource( xDataProvider->createDataSource(
+ aArguments ) );
+ if( !xDataSource.is() )
+ return;
+
+ DiagramHelper::tTemplateWithServiceName aTemplateAndService =
+ DiagramHelper::getTemplateForDiagram( xDiagram, xTemplateFactory );
+
+ rtl::OUString aServiceName( aTemplateAndService.second );
+ uno::Reference< chart2::XChartTypeTemplate > xTemplate = aTemplateAndService.first;
+
+ if( !xTemplate.is() )
+ {
+ if( aServiceName.getLength() == 0 )
+ aServiceName = C2U("com.sun.star.chart2.template.Column");
+ xTemplate.set( xTemplateFactory->createInstance( aServiceName ), uno::UNO_QUERY );
+ }
+ if( !xTemplate.is() )
+ return;
+
+ // /-- locked controllers
+ ControllerLockGuard aCtrlLockGuard( xChartModel );
+ xTemplate->changeDiagramData( xDiagram, xDataSource, aArguments );
+ // \-- locked controllers
+}
+
+Sequence< OUString > DataSourceHelper::getRangesFromLabeledDataSequence(
+ const Reference< data::XLabeledDataSequence > & xLSeq )
+{
+ Sequence< OUString > aResult;
+ if( xLSeq.is())
+ {
+ Reference< data::XDataSequence > xLabel( xLSeq->getLabel());
+ Reference< data::XDataSequence > xValues( xLSeq->getValues());
+
+ if( xLabel.is())
+ {
+ if( xValues.is())
+ {
+ aResult.realloc( 2 );
+ aResult[0] = xLabel->getSourceRangeRepresentation();
+ aResult[1] = xValues->getSourceRangeRepresentation();
+ }
+ else
+ {
+ aResult.realloc( 1 );
+ aResult[0] = xLabel->getSourceRangeRepresentation();
+ }
+ }
+ else if( xValues.is())
+ {
+ aResult.realloc( 1 );
+ aResult[0] = xValues->getSourceRangeRepresentation();
+ }
+ }
+ return aResult;
+}
+
+OUString DataSourceHelper::getRangeFromValues(
+ const Reference< data::XLabeledDataSequence > & xLSeq )
+{
+ OUString aResult;
+ if( xLSeq.is() )
+ {
+ Reference< data::XDataSequence > xValues( xLSeq->getValues() );
+ if( xValues.is() )
+ aResult = xValues->getSourceRangeRepresentation();
+ }
+ return aResult;
+}
+
+Sequence< OUString > DataSourceHelper::getRangesFromDataSource( const Reference< data::XDataSource > & xSource )
+{
+ ::std::vector< OUString > aResult;
+ if( xSource.is())
+ {
+ Sequence< Reference< data::XLabeledDataSequence > > aLSeqSeq( xSource->getDataSequences());
+ for( sal_Int32 i=0; i<aLSeqSeq.getLength(); ++i )
+ {
+ Reference< data::XDataSequence > xLabel( aLSeqSeq[i]->getLabel());
+ Reference< data::XDataSequence > xValues( aLSeqSeq[i]->getValues());
+
+ if( xLabel.is())
+ aResult.push_back( xLabel->getSourceRangeRepresentation());
+ if( xValues.is())
+ aResult.push_back( xValues->getSourceRangeRepresentation());
+ }
+ }
+ return ContainerHelper::ContainerToSequence( aResult );
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx
new file mode 100644
index 000000000000..36afef60a6d4
--- /dev/null
+++ b/chart2/source/tools/DiagramHelper.cxx
@@ -0,0 +1,1559 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "DiagramHelper.hxx"
+#include "LegendHelper.hxx"
+#include "PropertyHelper.hxx"
+#include "macros.hxx"
+#include "DataSeriesHelper.hxx"
+#include "AxisHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "ChartTypeHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "CommonConverters.hxx"
+#include "ExplicitCategoriesProvider.hxx"
+#include "servicenames_charttypes.hxx"
+#include "ChartModelHelper.hxx"
+#include "RelativePositionHelper.hxx"
+#include "ControllerLockGuard.hxx"
+
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart/XDiagramPositioning.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/InterpretedData.hpp>
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/RelativeSize.hpp>
+
+#include <unotools/saveopt.hxx>
+#include <rtl/math.hxx>
+
+#include <com/sun/star/util/XModifiable.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using namespace ::std;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+// static
+DiagramHelper::tTemplateWithServiceName
+ DiagramHelper::getTemplateForDiagram(
+ const Reference< XDiagram > & xDiagram,
+ const Reference< lang::XMultiServiceFactory > & xChartTypeManager,
+ const OUString & rPreferredTemplateName )
+{
+ DiagramHelper::tTemplateWithServiceName aResult;
+
+ if( ! (xChartTypeManager.is() && xDiagram.is()))
+ return aResult;
+
+ Sequence< OUString > aServiceNames( xChartTypeManager->getAvailableServiceNames());
+ const sal_Int32 nLength = aServiceNames.getLength();
+
+ bool bHasPreferredTemplate = (rPreferredTemplateName.getLength() > 0);
+ bool bTemplateFound = false;
+
+ if( bHasPreferredTemplate )
+ {
+ Reference< XChartTypeTemplate > xTempl(
+ xChartTypeManager->createInstance( rPreferredTemplateName ), uno::UNO_QUERY );
+
+ if( xTempl.is() &&
+ xTempl->matchesTemplate( xDiagram, sal_True ))
+ {
+ aResult.first = xTempl;
+ aResult.second = rPreferredTemplateName;
+ bTemplateFound = true;
+ }
+ }
+
+ for( sal_Int32 i = 0; ! bTemplateFound && i < nLength; ++i )
+ {
+ try
+ {
+ if( ! bHasPreferredTemplate ||
+ ! rPreferredTemplateName.equals( aServiceNames[ i ] ))
+ {
+ Reference< XChartTypeTemplate > xTempl(
+ xChartTypeManager->createInstance( aServiceNames[ i ] ), uno::UNO_QUERY_THROW );
+
+ if( xTempl->matchesTemplate( xDiagram, sal_True ))
+ {
+ aResult.first = xTempl;
+ aResult.second = aServiceNames[ i ];
+ bTemplateFound = true;
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return aResult;
+}
+
+// static
+void DiagramHelper::setVertical(
+ const Reference< XDiagram > & xDiagram,
+ bool bVertical /* = true */ )
+{
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
+ if( xCnt.is())
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSys(
+ xCnt->getCoordinateSystems());
+ uno::Any aValue;
+ aValue <<= bVertical;
+ for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
+ {
+ uno::Reference< XCoordinateSystem > xCooSys( aCooSys[i] );
+ Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
+ bool bChanged = false;
+ if( xProp.is() )
+ {
+ bool bOldSwap = sal_False;
+ if( !(xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bOldSwap)
+ || bVertical != bOldSwap )
+ bChanged = true;
+
+ if( bChanged )
+ xProp->setPropertyValue( C2U("SwapXAndYAxis"), aValue );
+ }
+ if( xCooSys.is() )
+ {
+ const sal_Int32 nDimensionCount( xCooSys->getDimension() );
+ sal_Int32 nDimIndex = 0;
+ for(nDimIndex=0; nDimIndex<nDimensionCount; ++nDimIndex)
+ {
+ const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex);
+ for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
+ {
+ Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimIndex,nI ));
+ if( xAxis.is() )
+ {
+ //adapt title rotation only when axis swapping has changed
+ if( bChanged )
+ {
+ Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
+ if( xTitled.is())
+ {
+ Reference< beans::XPropertySet > xTitleProps( xTitled->getTitleObject(), uno::UNO_QUERY );
+ if( !xTitleProps.is() )
+ continue;
+ double fAngleDegree = 0.0;
+ xTitleProps->getPropertyValue( C2U( "TextRotation" ) ) >>= fAngleDegree;
+ if( !::rtl::math::approxEqual( fAngleDegree, 0.0 )
+ && !::rtl::math::approxEqual( fAngleDegree, 90.0 ) )
+ continue;
+
+ double fNewAngleDegree = 0.0;
+ if( !bVertical && nDimIndex == 1 )
+ fNewAngleDegree = 90.0;
+ else if( bVertical && nDimIndex == 0 )
+ fNewAngleDegree = 90.0;
+
+ xTitleProps->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree ));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+//static
+bool DiagramHelper::getVertical( const uno::Reference< chart2::XDiagram > & xDiagram,
+ bool& rbFound, bool& rbAmbiguous )
+{
+ bool bValue = false;
+ rbFound = false;
+ rbAmbiguous = false;
+
+ Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
+ if( xCnt.is())
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSys(
+ xCnt->getCoordinateSystems());
+ for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
+ {
+ Reference< beans::XPropertySet > xProp( aCooSys[i], uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ bool bCurrent = false;
+ if( xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bCurrent )
+ {
+ if( !rbFound )
+ {
+ bValue = bCurrent;
+ rbFound = true;
+ }
+ else if( bCurrent != bValue )
+ {
+ // ambiguous -> choose always first found
+ rbAmbiguous = true;
+ }
+ }
+ }
+ }
+ }
+ return bValue;
+}
+
+//static
+void DiagramHelper::setStackMode(
+ const Reference< XDiagram > & xDiagram,
+ StackMode eStackMode,
+ bool bOnlyAtFirstChartType /* = true */
+)
+{
+ try
+ {
+ if( eStackMode == StackMode_AMBIGUOUS )
+ return;
+
+ bool bValueFound = false;
+ bool bIsAmbiguous = false;
+ StackMode eOldStackMode = DiagramHelper::getStackMode( xDiagram, bValueFound, bIsAmbiguous );
+
+ if( eStackMode == eOldStackMode && !bIsAmbiguous )
+ return;
+
+ StackingDirection eNewDirection = StackingDirection_NO_STACKING;
+ if( eStackMode == StackMode_Y_STACKED || eStackMode == StackMode_Y_STACKED_PERCENT )
+ eNewDirection = StackingDirection_Y_STACKING;
+ else if( eStackMode == StackMode_Z_STACKED )
+ eNewDirection = StackingDirection_Z_STACKING;
+
+ uno::Any aNewDirection( uno::makeAny(eNewDirection) );
+
+ sal_Bool bPercent = sal_False;
+ if( eStackMode == StackMode_Y_STACKED_PERCENT )
+ bPercent = sal_True;
+
+ //iterate through all coordinate systems
+ uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( !xCooSysContainer.is() )
+ return;
+ uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
+ //set correct percent stacking
+ const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(1);
+ for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
+ {
+ Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
+ if( xAxis.is())
+ {
+ chart2::ScaleData aScaleData = xAxis->getScaleData();
+ if( (aScaleData.AxisType==AxisType::PERCENT) != bPercent )
+ {
+ if( bPercent )
+ aScaleData.AxisType = AxisType::PERCENT;
+ else
+ aScaleData.AxisType = AxisType::REALNUMBER;
+ xAxis->setScaleData( aScaleData );
+ }
+ }
+ }
+ //iterate through all chart types in the current coordinate system
+ uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+ uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ sal_Int32 nMax = aChartTypeList.getLength();
+ if( bOnlyAtFirstChartType
+ && nMax >= 1 )
+ nMax = 1;
+ for( sal_Int32 nT = 0; nT < nMax; ++nT )
+ {
+ uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
+
+ //iterate through all series in this chart type
+ uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
+ OSL_ASSERT( xDataSeriesContainer.is());
+ if( !xDataSeriesContainer.is() )
+ continue;
+
+ uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
+ for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
+ {
+ Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
+ if(xProp.is())
+ xProp->setPropertyValue( C2U( "StackingDirection" ), aNewDirection );
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+//static
+
+StackMode DiagramHelper::getStackMode( const Reference< XDiagram > & xDiagram, bool& rbFound, bool& rbAmbiguous )
+{
+ rbFound=false;
+ rbAmbiguous=false;
+
+ StackMode eGlobalStackMode = StackMode_NONE;
+
+ //iterate through all coordinate systems
+ uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( !xCooSysContainer.is() )
+ return eGlobalStackMode;
+ uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
+
+ //iterate through all chart types in the current coordinate system
+ uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+ uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
+ {
+ uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
+
+ StackMode eLocalStackMode = DiagramHelper::getStackModeFromChartType(
+ xChartType, rbFound, rbAmbiguous, xCooSys );
+
+ if( rbFound && eLocalStackMode != eGlobalStackMode && nT>0 )
+ {
+ rbAmbiguous = true;
+ return eGlobalStackMode;
+ }
+
+ eGlobalStackMode = eLocalStackMode;
+ }
+ }
+
+ return eGlobalStackMode;
+}
+
+// static
+StackMode DiagramHelper::getStackModeFromChartType(
+ const Reference< XChartType > & xChartType,
+ bool& rbFound, bool& rbAmbiguous,
+ const Reference< XCoordinateSystem > & xCorrespondingCoordinateSystem )
+{
+ StackMode eStackMode = StackMode_NONE;
+ rbFound = false;
+ rbAmbiguous = false;
+
+ try
+ {
+ Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
+ Sequence< Reference< chart2::XDataSeries > > aSeries( xDSCnt->getDataSeries());
+
+ chart2::StackingDirection eCommonDirection = chart2::StackingDirection_NO_STACKING;
+ bool bDirectionInitialized = false;
+
+ // first series is irrelvant for stacking, start with second, unless
+ // there is only one series
+ const sal_Int32 nSeriesCount = aSeries.getLength();
+ sal_Int32 i = (nSeriesCount == 1) ? 0: 1;
+ for( ; i<nSeriesCount; ++i )
+ {
+ rbFound = true;
+ Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY_THROW );
+ chart2::StackingDirection eCurrentDirection = eCommonDirection;
+ // property is not MAYBEVOID
+ bool bSuccess = ( xProp->getPropertyValue( C2U("StackingDirection") ) >>= eCurrentDirection );
+ OSL_ASSERT( bSuccess );
+ (void)(bSuccess); // avoid warning in non-debug builds
+ if( ! bDirectionInitialized )
+ {
+ eCommonDirection = eCurrentDirection;
+ bDirectionInitialized = true;
+ }
+ else
+ {
+ if( eCommonDirection != eCurrentDirection )
+ {
+ rbAmbiguous = true;
+ break;
+ }
+ }
+ }
+
+ if( rbFound )
+ {
+ if( eCommonDirection == chart2::StackingDirection_Z_STACKING )
+ eStackMode = StackMode_Z_STACKED;
+ else if( eCommonDirection == chart2::StackingDirection_Y_STACKING )
+ {
+ eStackMode = StackMode_Y_STACKED;
+
+ // percent stacking
+ if( xCorrespondingCoordinateSystem.is() )
+ {
+ if( 1 < xCorrespondingCoordinateSystem->getDimension() )
+ {
+ sal_Int32 nAxisIndex = 0;
+ if( nSeriesCount )
+ nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(aSeries[0]);
+
+ Reference< chart2::XAxis > xAxis(
+ xCorrespondingCoordinateSystem->getAxisByDimension( 1,nAxisIndex ));
+ if( xAxis.is())
+ {
+ chart2::ScaleData aScaleData = xAxis->getScaleData();
+ if( aScaleData.AxisType==chart2::AxisType::PERCENT )
+ eStackMode = StackMode_Y_STACKED_PERCENT;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return eStackMode;
+}
+
+// static
+sal_Int32 DiagramHelper::getDimension( const Reference< XDiagram > & xDiagram )
+{
+ // -1: not yet set
+ sal_Int32 nResult = -1;
+
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
+ if( xCooSysCnt.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
+ xCooSysCnt->getCoordinateSystems());
+
+ for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
+ {
+ Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
+ if(xCooSys.is())
+ {
+ nResult = xCooSys->getDimension();
+ break;
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return nResult;
+}
+
+// static
+void DiagramHelper::setDimension(
+ const Reference< XDiagram > & xDiagram,
+ sal_Int32 nNewDimensionCount )
+{
+ if( ! xDiagram.is())
+ return;
+
+ if( DiagramHelper::getDimension( xDiagram ) == nNewDimensionCount )
+ return;
+
+ try
+ {
+ bool rbFound = false;
+ bool rbAmbiguous = true;
+ StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous );
+ bool bIsSupportingOnlyDeepStackingFor3D=false;
+
+ //change all coordinate systems:
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ Reference< XCoordinateSystem > xOldCooSys( aCooSysList[nCS], uno::UNO_QUERY );
+ Reference< XCoordinateSystem > xNewCooSys;
+
+ Reference< XChartTypeContainer > xChartTypeContainer( xOldCooSys, uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+
+ Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
+ {
+ Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY );
+ bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType );
+ if(!xNewCooSys.is())
+ {
+ xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount );
+ break;
+ }
+ //@todo make sure that all following charttypes are also capable of the new dimension
+ //otherwise separate them in a different group
+ //BM: might be done in replaceCoordinateSystem()
+ }
+
+ // replace the old coordinate system at all places where it was used
+ DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys );
+ }
+
+ //correct stack mode if necessary
+ if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D )
+ DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED );
+ else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED )
+ DiagramHelper::setStackMode( xDiagram, StackMode_NONE );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// static
+void DiagramHelper::replaceCoordinateSystem(
+ const Reference< XDiagram > & xDiagram,
+ const Reference< XCoordinateSystem > & xCooSysToReplace,
+ const Reference< XCoordinateSystem > & xReplacement )
+{
+ OSL_ASSERT( xDiagram.is());
+ if( ! xDiagram.is())
+ return;
+
+ // update the coordinate-system container
+ Reference< XCoordinateSystemContainer > xCont( xDiagram, uno::UNO_QUERY );
+ if( xCont.is())
+ {
+ try
+ {
+ Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
+
+ // move chart types of xCooSysToReplace to xReplacement
+ Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW );
+ Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW );
+ xCTCntReplacement->setChartTypes( xCTCntCooSys->getChartTypes());
+
+ xCont->removeCoordinateSystem( xCooSysToReplace );
+ xCont->addCoordinateSystem( xReplacement );
+
+ if( xCategories.is() )
+ DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+}
+
+//static
+bool DiagramHelper::isSeriesAttachedToMainAxis(
+ const uno::Reference< chart2::XDataSeries >& xDataSeries )
+{
+ sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
+ return (nAxisIndex==0);
+}
+
+//static
+bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis
+ , const uno::Reference< chart2::XDataSeries >& xDataSeries
+ , const uno::Reference< chart2::XDiagram >& xDiagram
+ , const uno::Reference< uno::XComponentContext > & xContext
+ , bool bAdaptAxes )
+{
+ bool bChanged = false;
+
+ //set property at axis
+ Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
+ if( !xProp.is() )
+ return bChanged;
+
+ sal_Int32 nNewAxisIndex = bAttachToMainAxis ? 0 : 1;
+ sal_Int32 nOldAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
+ uno::Reference< chart2::XAxis > xOldAxis( DiagramHelper::getAttachedAxis( xDataSeries, xDiagram ) );
+
+ if( nOldAxisIndex != nNewAxisIndex )
+ {
+ try
+ {
+ xProp->setPropertyValue( C2U("AttachedAxisIndex"), uno::makeAny( nNewAxisIndex ) );
+ bChanged = true;
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ if( bChanged && xDiagram.is() )
+ {
+ uno::Reference< XAxis > xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis, xDiagram ) );
+ if(!xAxis.is()) //create an axis if necessary
+ xAxis = AxisHelper::createAxis( 1, bAttachToMainAxis, xDiagram, xContext );
+ if( bAdaptAxes )
+ {
+ AxisHelper::makeAxisVisible( xAxis );
+ AxisHelper::hideAxisIfNoDataIsAttached( xOldAxis, xDiagram );
+ }
+ }
+
+ return bChanged;
+}
+
+//static
+uno::Reference< XAxis > DiagramHelper::getAttachedAxis(
+ const uno::Reference< XDataSeries >& xSeries,
+ const uno::Reference< XDiagram >& xDiagram )
+{
+ return AxisHelper::getAxis( 1, DiagramHelper::isSeriesAttachedToMainAxis( xSeries ), xDiagram );
+}
+
+//static
+uno::Reference< XChartType > DiagramHelper::getChartTypeOfSeries(
+ const uno::Reference< chart2::XDiagram >& xDiagram
+ , const uno::Reference< XDataSeries >& xGivenDataSeries )
+{
+ if( !xGivenDataSeries.is() )
+ return 0;
+ if(!xDiagram.is())
+ return 0;
+
+ //iterate through the model to find the given xSeries
+ //the found parent indicates the charttype
+
+ //iterate through all coordinate systems
+ uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( !xCooSysContainer.is())
+ return 0;
+
+ uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
+
+ //iterate through all chart types in the current coordinate system
+ uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
+ OSL_ASSERT( xChartTypeContainer.is());
+ if( !xChartTypeContainer.is() )
+ continue;
+ uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
+ {
+ uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
+
+ //iterate through all series in this chart type
+ uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
+ OSL_ASSERT( xDataSeriesContainer.is());
+ if( !xDataSeriesContainer.is() )
+ continue;
+
+ uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
+ for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
+ {
+ if( xGivenDataSeries==aSeriesList[nS] )
+ return xChartType;
+ }
+ }
+ }
+ return 0;
+}
+
+// static
+::std::vector< Reference< XDataSeries > >
+ DiagramHelper::getDataSeriesFromDiagram(
+ const Reference< XDiagram > & xDiagram )
+{
+ ::std::vector< Reference< XDataSeries > > aResult;
+
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt(
+ xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
+ xCooSysCnt->getCoordinateSystems());
+ for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
+ {
+ Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
+ Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
+ for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
+ {
+ Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
+ Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
+ ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
+ ::std::back_inserter( aResult ));
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return aResult;
+}
+
+Sequence< Sequence< Reference< XDataSeries > > >
+ DiagramHelper::getDataSeriesGroups( const Reference< XDiagram > & xDiagram )
+{
+ vector< Sequence< Reference< XDataSeries > > > aResult;
+
+ //iterate through all coordinate systems
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( xCooSysContainer.is() )
+ {
+ Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ //iterate through all chart types in the current coordinate system
+ Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+ Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
+ {
+ Reference< XDataSeriesContainer > xDataSeriesContainer( aChartTypeList[nT], uno::UNO_QUERY );
+ if( !xDataSeriesContainer.is() )
+ continue;
+ aResult.push_back( xDataSeriesContainer->getDataSeries() );
+ }
+ }
+ }
+ return ContainerHelper::ContainerToSequence( aResult );
+}
+
+Reference< XChartType >
+ DiagramHelper::getChartTypeByIndex( const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
+{
+ Reference< XChartType > xChartType;
+
+ //iterate through all coordinate systems
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( ! xCooSysContainer.is())
+ return xChartType;
+
+ Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ sal_Int32 nTypesSoFar = 0;
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+ Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ if( nIndex >= 0 && nIndex < (nTypesSoFar + aChartTypeList.getLength()) )
+ {
+ xChartType.set( aChartTypeList[nIndex - nTypesSoFar] );
+ break;
+ }
+ nTypesSoFar += aChartTypeList.getLength();
+ }
+
+ return xChartType;
+}
+
+namespace
+{
+
+std::vector< Reference< XAxis > > lcl_getAxisHoldingCategoriesFromDiagram(
+ const Reference< XDiagram > & xDiagram )
+{
+ std::vector< Reference< XAxis > > aRet;
+
+ Reference< XAxis > xResult;
+ // return first x-axis as fall-back
+ Reference< XAxis > xFallBack;
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt(
+ xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
+ xCooSysCnt->getCoordinateSystems());
+ for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
+ {
+ Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
+ OSL_ASSERT( xCooSys.is());
+ for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
+ {
+ const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
+ for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
+ {
+ Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
+ OSL_ASSERT( xAxis.is());
+ if( xAxis.is())
+ {
+ ScaleData aScaleData = xAxis->getScaleData();
+ if( aScaleData.Categories.is() || (aScaleData.AxisType == AxisType::CATEGORY) )
+ {
+ aRet.push_back(xAxis);
+ }
+ if( (nN == 0) && !xFallBack.is())
+ xFallBack.set( xAxis );
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ if( aRet.empty() )
+ aRet.push_back(xFallBack);
+
+ return aRet;
+}
+
+} // anonymous namespace
+
+//static
+bool DiagramHelper::isCategoryDiagram(
+ const Reference< XDiagram >& xDiagram )
+{
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt(
+ xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
+ xCooSysCnt->getCoordinateSystems());
+ for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
+ {
+ Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
+ OSL_ASSERT( xCooSys.is());
+ for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
+ {
+ const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
+ for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
+ {
+ Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
+ OSL_ASSERT( xAxis.is());
+ if( xAxis.is())
+ {
+ ScaleData aScaleData = xAxis->getScaleData();
+ if( aScaleData.AxisType == AxisType::CATEGORY )
+ return true;
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return false;
+}
+
+// static
+void DiagramHelper::setCategoriesToDiagram(
+ const Reference< chart2::data::XLabeledDataSequence >& xCategories,
+ const Reference< XDiagram >& xDiagram,
+ bool bSetAxisType /* = false */,
+ bool bCategoryAxis /* = true */ )
+{
+ std::vector< Reference< chart2::XAxis > > aCatAxes(
+ lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
+
+ std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
+ std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
+
+ for( aIt = aCatAxes.begin(); aIt != aEnd; ++aIt )
+ {
+ Reference< chart2::XAxis > xCatAxis(*aIt);
+ if( xCatAxis.is())
+ {
+ ScaleData aScaleData( xCatAxis->getScaleData());
+ aScaleData.Categories = xCategories;
+ if( bSetAxisType )
+ {
+ if( bCategoryAxis )
+ aScaleData.AxisType = AxisType::CATEGORY;
+ else if( aScaleData.AxisType == AxisType::CATEGORY )
+ aScaleData.AxisType = AxisType::REALNUMBER;
+ }
+ xCatAxis->setScaleData( aScaleData );
+ }
+ }
+}
+
+// static
+Reference< data::XLabeledDataSequence >
+ DiagramHelper::getCategoriesFromDiagram(
+ const Reference< XDiagram > & xDiagram )
+{
+ Reference< data::XLabeledDataSequence > xResult;
+
+ try
+ {
+ std::vector< Reference< chart2::XAxis > > aCatAxes(
+ lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
+ std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
+ std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
+ //search for first categories
+ if( aIt != aEnd )
+ {
+ Reference< chart2::XAxis > xCatAxis(*aIt);
+ if( xCatAxis.is())
+ {
+ ScaleData aScaleData( xCatAxis->getScaleData());
+ if( aScaleData.Categories.is() )
+ {
+ xResult.set( aScaleData.Categories );
+ uno::Reference<beans::XPropertySet> xProp(aScaleData.Categories->getValues(), uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ try
+ {
+ xProp->setPropertyValue( C2U( "Role" ), uno::makeAny( C2U("categories") ) );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return xResult;
+}
+
+void lcl_generateAutomaticCategoriesFromChartType(
+ Sequence< rtl::OUString >& rRet,
+ const Reference< XChartType >& xChartType )
+{
+ if(!xChartType.is())
+ return;
+ rtl::OUString aMainSeq( xChartType->getRoleOfSequenceForSeriesLabel() );
+ Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY );
+ if( xSeriesCnt.is() )
+ {
+ Sequence< Reference< XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
+ for( sal_Int32 nS = 0; nS < aSeriesSeq.getLength(); nS++ )
+ {
+ Reference< data::XDataSource > xDataSource( aSeriesSeq[nS], uno::UNO_QUERY );
+ if( !xDataSource.is() )
+ continue;
+ Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
+ ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aMainSeq ));
+ if( !xLabeledSeq.is() )
+ continue;
+ Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
+ if( !xValueSeq.is() )
+ continue;
+ rRet = xValueSeq->generateLabel( chart2::data::LabelOrigin_LONG_SIDE );
+ if( rRet.getLength() )
+ return;
+ }
+ }
+}
+
+Sequence< rtl::OUString > DiagramHelper::generateAutomaticCategoriesFromCooSys( const Reference< XCoordinateSystem > & xCooSys )
+{
+ Sequence< rtl::OUString > aRet;
+
+ Reference< XChartTypeContainer > xTypeCntr( xCooSys, uno::UNO_QUERY );
+ if( xTypeCntr.is() )
+ {
+ Sequence< Reference< XChartType > > aChartTypes( xTypeCntr->getChartTypes() );
+ for( sal_Int32 nN=0; nN<aChartTypes.getLength(); nN++ )
+ {
+ lcl_generateAutomaticCategoriesFromChartType( aRet, aChartTypes[nN] );
+ if( aRet.getLength() )
+ return aRet;
+ }
+ }
+ return aRet;
+}
+
+//static
+Sequence< rtl::OUString > DiagramHelper::getExplicitSimpleCategories(
+ const Reference< XChartDocument >& xChartDoc )
+{
+ Sequence< rtl::OUString > aRet;
+ uno::Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
+ if(xChartModel.is())
+ {
+ uno::Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
+ ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, xChartModel );
+ aRet = aExplicitCategoriesProvider.getSimpleCategories();
+ }
+ return aRet;
+}
+
+// static
+Sequence< Reference< XChartType > >
+ DiagramHelper::getChartTypesFromDiagram(
+ const Reference< XDiagram > & xDiagram )
+{
+ ::std::vector< Reference< XChartType > > aResult;
+
+ if(xDiagram.is())
+ try
+ {
+ Reference< XCoordinateSystemContainer > xCooSysCnt(
+ xDiagram, uno::UNO_QUERY_THROW );
+ Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
+ xCooSysCnt->getCoordinateSystems());
+ for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
+ {
+ Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
+ Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
+ ::std::copy( aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
+ ::std::back_inserter( aResult ));
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return ContainerHelper::ContainerToSequence( aResult );
+}
+
+//static
+bool DiagramHelper::areChartTypesCompatible( const Reference< ::chart2::XChartType >& xFirstType,
+ const Reference< ::chart2::XChartType >& xSecondType )
+{
+ if( !xFirstType.is() || !xSecondType.is() )
+ return false;
+
+ ::std::vector< ::rtl::OUString > aFirstRoles( ContainerHelper::SequenceToVector( xFirstType->getSupportedMandatoryRoles() ) );
+ ::std::vector< ::rtl::OUString > aSecondRoles( ContainerHelper::SequenceToVector( xSecondType->getSupportedMandatoryRoles() ) );
+ ::std::sort( aFirstRoles.begin(), aFirstRoles.end() );
+ ::std::sort( aSecondRoles.begin(), aSecondRoles.end() );
+ return ( aFirstRoles == aSecondRoles );
+}
+
+namespace
+{
+ /**
+ * This method implements the logic of checking if a series can be moved
+ * forward/backward. Depending on the "bDoMove" parameter the series will
+ * be moved (bDoMove = true) or the function just will test if the
+ * series can be moved without doing the move (bDoMove = false).
+ *
+ * @param xDiagram
+ * Reference to the diagram that contains the series.
+ *
+ * @param xGivenDataSeries
+ * Reference to the series that should moved or tested for moving.
+ *
+ * @param bForward
+ * Direction in which the series should be moved or tested for moving.
+ *
+ * @param bDoMove
+ * Should this function really move the series (true) or just test if it is
+ * possible (false).
+ *
+ *
+ * @returns
+ * in case of bDoMove == true
+ * - True : if the move was done
+ * - False : the move failed
+ * in case of bDoMove == false
+ * - True : the series can be moved
+ * - False : the series can not be moved
+ *
+ */
+
+bool lcl_moveSeriesOrCheckIfMoveIsAllowed(
+ const Reference< XDiagram >& xDiagram,
+ const Reference< XDataSeries >& xGivenDataSeries,
+ bool bForward,
+ bool bDoMove )
+{
+ bool bMovedOrMoveAllowed = false;
+
+ try
+ {
+ uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+
+ //find position of series.
+ bool bFound = false;
+
+ if( xGivenDataSeries.is() && xCooSysContainer.is() )
+ {
+ uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+
+ for( sal_Int32 nCS = 0; !bFound && nCS < aCooSysList.getLength(); ++nCS )
+ {
+ uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
+
+ //iterate through all chart types in the current coordinate system
+ uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
+ OSL_ASSERT( xChartTypeContainer.is());
+ if( !xChartTypeContainer.is() )
+ continue;
+ uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ uno::Reference< XChartType > xFormerChartType;
+
+ for( sal_Int32 nT = 0; !bFound && nT < aChartTypeList.getLength(); ++nT )
+ {
+ uno::Reference< XChartType > xCurrentChartType( aChartTypeList[nT] );
+
+ //iterate through all series in this chart type
+ uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xCurrentChartType, uno::UNO_QUERY );
+ OSL_ASSERT( xDataSeriesContainer.is());
+ if( !xDataSeriesContainer.is() )
+ continue;
+
+ uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
+
+ for( sal_Int32 nS = 0; !bFound && nS < aSeriesList.getLength(); ++nS )
+ {
+
+ // We found the series we are interrested in !
+ if( xGivenDataSeries==aSeriesList[nS] )
+ {
+ sal_Int32 nOldSeriesIndex = nS;
+ bFound = true;
+
+ try
+ {
+ sal_Int32 nNewSeriesIndex = nS;
+
+ if( bForward )
+ nNewSeriesIndex--;
+ else
+ nNewSeriesIndex++;
+
+
+ if( nNewSeriesIndex >= 0 && nNewSeriesIndex < aSeriesList.getLength() )
+ {
+ //move series in the same charttype
+ bMovedOrMoveAllowed = true;
+ if( bDoMove )
+ {
+ aSeriesList[ nOldSeriesIndex ] = aSeriesList[ nNewSeriesIndex ];
+ aSeriesList[ nNewSeriesIndex ] = xGivenDataSeries;
+ xDataSeriesContainer->setDataSeries( aSeriesList );
+ }
+ }
+ else if( nNewSeriesIndex<0 )
+ {
+ //exchange series with former charttype
+ if( xFormerChartType.is() && DiagramHelper::areChartTypesCompatible( xFormerChartType, xCurrentChartType ) )
+ {
+ bMovedOrMoveAllowed = true;
+ if( bDoMove )
+ {
+ uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xFormerChartType, uno::UNO_QUERY );
+ if( xOtherDataSeriesContainer.is() )
+ {
+ uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
+ sal_Int32 nOtherSeriesIndex = aOtherSeriesList.getLength()-1;
+ if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
+ {
+ uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
+ aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
+ xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
+
+ aSeriesList[nOldSeriesIndex]=xExchangeSeries;
+ xDataSeriesContainer->setDataSeries(aSeriesList);
+ }
+ }
+ }
+ }
+ }
+ else if( nT+1 < aChartTypeList.getLength() )
+ {
+ //exchange series with next charttype
+ uno::Reference< XChartType > xOtherChartType( aChartTypeList[nT+1] );
+ if( xOtherChartType.is() && DiagramHelper::areChartTypesCompatible( xOtherChartType, xCurrentChartType ) )
+ {
+ bMovedOrMoveAllowed = true;
+ if( bDoMove )
+ {
+ uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xOtherChartType, uno::UNO_QUERY );
+ if( xOtherDataSeriesContainer.is() )
+ {
+ uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
+ sal_Int32 nOtherSeriesIndex = 0;
+ if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
+ {
+ uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
+ aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
+ xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
+
+ aSeriesList[nOldSeriesIndex]=xExchangeSeries;
+ xDataSeriesContainer->setDataSeries(aSeriesList);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( util::CloseVetoException& )
+ {
+ }
+ catch( uno::RuntimeException& )
+ {
+ }
+ }
+ }
+ xFormerChartType = xCurrentChartType;
+ }
+ }
+ }
+ }
+ catch( util::CloseVetoException& )
+ {
+ }
+ catch( uno::RuntimeException& )
+ {
+ }
+ return bMovedOrMoveAllowed;
+}
+} // anonymous namespace
+
+
+bool DiagramHelper::isSeriesMoveable(
+ const Reference< XDiagram >& xDiagram,
+ const Reference< XDataSeries >& xGivenDataSeries,
+ bool bForward )
+{
+ bool bIsMoveable = false;
+ const bool bDoMove = false;
+
+ bIsMoveable = lcl_moveSeriesOrCheckIfMoveIsAllowed(
+ xDiagram, xGivenDataSeries, bForward, bDoMove );
+
+ return bIsMoveable;
+}
+
+
+bool DiagramHelper::moveSeries( const Reference< XDiagram >& xDiagram, const Reference< XDataSeries >& xGivenDataSeries, bool bForward )
+{
+ bool bMoved = false;
+ const bool bDoMove = true;
+
+ bMoved = lcl_moveSeriesOrCheckIfMoveIsAllowed(
+ xDiagram, xGivenDataSeries, bForward, bDoMove );
+
+ return bMoved;
+}
+
+bool DiagramHelper::isSupportingFloorAndWall( const Reference<
+ chart2::XDiagram >& xDiagram )
+{
+ //pies and donuts currently do not support this because of wrong files from older versions
+ //todo: allow this in future again, if fileversion are available for ole objects (metastream)
+ //thus the wrong bottom can be removed on import
+
+ Sequence< Reference< chart2::XChartType > > aTypes(
+ ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ) );
+ for( sal_Int32 nN = 0; nN < aTypes.getLength(); nN++ )
+ {
+ Reference< chart2::XChartType > xType( aTypes[nN] );
+ if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return false;
+ if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
+ return false;
+ if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
+ return false;
+ }
+ return true;
+}
+
+bool DiagramHelper::isPieOrDonutChart( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XDiagram >& xDiagram )
+{
+ uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex(
+ xDiagram, 0 ) );
+
+ if( xChartType .is() )
+ {
+ rtl::OUString aChartType = xChartType->getChartType();
+ if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
+ return true;
+ }
+ return false;
+}
+
+// static
+sal_Int32 DiagramHelper::getGeometry3D(
+ const uno::Reference< chart2::XDiagram > & xDiagram,
+ bool& rbFound, bool& rbAmbiguous )
+{
+ sal_Int32 nCommonGeom( DataPointGeometry3D::CUBOID );
+ rbFound = false;
+ rbAmbiguous = false;
+
+ ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+
+ if( aSeriesVec.empty())
+ rbAmbiguous = true;
+
+ for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
+ aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
+ {
+ try
+ {
+ sal_Int32 nGeom = 0;
+ Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY_THROW );
+ if( xProp->getPropertyValue( C2U( "Geometry3D" )) >>= nGeom )
+ {
+ if( ! rbFound )
+ {
+ // first series
+ nCommonGeom = nGeom;
+ rbFound = true;
+ }
+ // further series: compare for uniqueness
+ else if( nCommonGeom != nGeom )
+ {
+ rbAmbiguous = true;
+ break;
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return nCommonGeom;
+}
+
+// static
+void DiagramHelper::setGeometry3D(
+ const Reference< chart2::XDiagram > & xDiagram,
+ sal_Int32 nNewGeometry )
+{
+ ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+
+ for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
+ aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
+ {
+ DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(
+ *aIt, C2U( "Geometry3D" ), uno::makeAny( nNewGeometry ));
+ }
+}
+
+//static
+sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment(
+ const Reference< chart2::XDiagram > & xDiagram,
+ const Reference< chart2::XChartType >& xChartType )
+{
+ sal_Int32 nResult = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
+ uno::Sequence < sal_Int32 > aAvailableMissingValueTreatments(
+ ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
+
+ uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
+ if( xDiaProp.is() && (xDiaProp->getPropertyValue( C2U( "MissingValueTreatment" ) ) >>= nResult) )
+ {
+ //ensure that the set value is supported by this charttype
+ for( sal_Int32 nN = 0; nN < aAvailableMissingValueTreatments.getLength(); nN++ )
+ if( aAvailableMissingValueTreatments[nN] == nResult )
+ return nResult; //ok
+ }
+
+ //otherwise use the first supported one
+ if( aAvailableMissingValueTreatments.getLength() )
+ {
+ nResult = aAvailableMissingValueTreatments[0];
+ return nResult;
+ }
+
+ return nResult;
+}
+
+//static
+DiagramPositioningMode DiagramHelper::getDiagramPositioningMode( const uno::Reference<
+ chart2::XDiagram > & xDiagram )
+{
+ DiagramPositioningMode eMode = DiagramPositioningMode_AUTO;
+ uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY );
+ if( xDiaProps.is() )
+ {
+ RelativePosition aRelPos;
+ RelativeSize aRelSize;
+ if( (xDiaProps->getPropertyValue(C2U("RelativePosition")) >>= aRelPos ) &&
+ (xDiaProps->getPropertyValue(C2U("RelativeSize")) >>= aRelSize ) )
+ {
+ bool bPosSizeExcludeAxes=false;
+ xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxes;
+ if( bPosSizeExcludeAxes )
+ eMode = DiagramPositioningMode_EXCLUDING;
+ else
+ eMode = DiagramPositioningMode_INCLUDING;
+ }
+ }
+ return eMode;
+}
+
+void lcl_ensureRange0to1( double& rValue )
+{
+ if(rValue<0.0)
+ rValue=0.0;
+ if(rValue>1.0)
+ rValue=1.0;
+}
+
+//static
+bool DiagramHelper::setDiagramPositioning( const uno::Reference< frame::XModel >& xChartModel,
+ const awt::Rectangle& rPosRect /*100th mm*/ )
+{
+ ControllerLockGuard aCtrlLockGuard( xChartModel );
+
+ bool bChanged = false;
+ awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
+ uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
+ if( !xDiaProps.is() )
+ return bChanged;
+
+ RelativePosition aOldPos;
+ RelativeSize aOldSize;
+ xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aOldPos;
+ xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aOldSize;
+
+ RelativePosition aNewPos;
+ aNewPos.Anchor = drawing::Alignment_TOP_LEFT;
+ aNewPos.Primary = double(rPosRect.X)/double(aPageSize.Width);
+ aNewPos.Secondary = double(rPosRect.Y)/double(aPageSize.Height);
+
+ chart2::RelativeSize aNewSize;
+ aNewSize.Primary = double(rPosRect.Width)/double(aPageSize.Width);
+ aNewSize.Secondary = double(rPosRect.Height)/double(aPageSize.Height);
+
+ lcl_ensureRange0to1( aNewPos.Primary );
+ lcl_ensureRange0to1( aNewPos.Secondary );
+ lcl_ensureRange0to1( aNewSize.Primary );
+ lcl_ensureRange0to1( aNewSize.Secondary );
+ if( (aNewPos.Primary + aNewSize.Primary) > 1.0 )
+ aNewPos.Primary = 1.0 - aNewSize.Primary;
+ if( (aNewPos.Secondary + aNewSize.Secondary) > 1.0 )
+ aNewPos.Secondary = 1.0 - aNewSize.Secondary;
+
+ xDiaProps->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aNewPos) );
+ xDiaProps->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aNewSize) );
+
+ bChanged = (aOldPos.Anchor!=aNewPos.Anchor) ||
+ (aOldPos.Primary!=aNewPos.Primary) ||
+ (aOldPos.Secondary!=aNewPos.Secondary) ||
+ (aOldSize.Primary!=aNewSize.Primary) ||
+ (aOldSize.Secondary!=aNewSize.Secondary);
+ return bChanged;
+}
+
+//static
+awt::Rectangle DiagramHelper::getDiagramRectangleFromModel( const uno::Reference< frame::XModel >& xChartModel )
+{
+ awt::Rectangle aRet(-1,-1,-1,-1);
+
+ uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
+ if( !xDiaProps.is() )
+ return aRet;
+
+ awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
+
+ RelativePosition aRelPos;
+ RelativeSize aRelSize;
+ xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aRelPos;
+ xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aRelSize;
+
+ awt::Size aAbsSize(
+ aRelSize.Primary * aPageSize.Width,
+ aRelSize.Secondary * aPageSize.Height );
+
+ awt::Point aAbsPos(
+ static_cast< sal_Int32 >( aRelPos.Primary * aPageSize.Width ),
+ static_cast< sal_Int32 >( aRelPos.Secondary * aPageSize.Height ));
+
+ awt::Point aAbsPosLeftTop = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos, aAbsSize, aRelPos.Anchor );
+
+ aRet = awt::Rectangle(aAbsPosLeftTop.X, aAbsPosLeftTop.Y, aAbsSize.Width, aAbsSize.Height );
+
+ return aRet;
+}
+
+//static
+bool DiagramHelper::switchDiagramPositioningToExcludingPositioning(
+ const uno::Reference< frame::XModel >& xChartModel
+ , bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning )
+{
+ //return true if something was changed
+ const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
+ if( nCurrentODFVersion == SvtSaveOptions::ODFVER_LATEST )//#i100778# todo: change this dependent on fileformat evolution
+ {
+ uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartModel, uno::UNO_QUERY ) ;
+ if( xOldDoc.is() )
+ {
+ uno::Reference< ::com::sun::star::chart::XDiagramPositioning > xDiagramPositioning( xOldDoc->getDiagram(), uno::UNO_QUERY );
+ if( xDiagramPositioning.is() && ( bConvertAlsoFromAutoPositioning || !xDiagramPositioning->isAutomaticDiagramPositioning() )
+ && !xDiagramPositioning->isExcludingDiagramPositioning() )
+ {
+ ControllerLockGuard aCtrlLockGuard( xChartModel );
+ uno::Reference< util::XModifiable > xModifiable( xChartModel, uno::UNO_QUERY );
+ bool bModelWasModified = xModifiable.is() && xModifiable->isModified();
+ xDiagramPositioning->setDiagramPositionExcludingAxes( xDiagramPositioning->calculateDiagramPositionExcludingAxes() );
+ if(bResetModifiedState && !bModelWasModified && xModifiable.is() )
+ xModifiable->setModified(sal_False);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/ErrorBar.cxx b/chart2/source/tools/ErrorBar.cxx
new file mode 100644
index 000000000000..7468d8bb7896
--- /dev/null
+++ b/chart2/source/tools/ErrorBar.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "ErrorBar.hxx"
+#include "macros.hxx"
+#include "LineProperties.hxx"
+#include "ContainerHelper.hxx"
+#include "EventListenerHelper.hxx"
+#include "PropertyHelper.hxx"
+#include "CloneHelper.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::beans::Property;
+using ::osl::MutexGuard;
+
+namespace
+{
+static const OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ErrorBar" ));
+
+enum
+{
+ PROP_ERROR_BAR_STYLE,
+ PROP_ERROR_BAR_POS_ERROR,
+ PROP_ERROR_BAR_NEG_ERROR,
+ PROP_ERROR_BAR_WEIGHT,
+ PROP_ERROR_BAR_SHOW_POS_ERROR,
+ PROP_ERROR_BAR_SHOW_NEG_ERROR
+};
+
+void lcl_AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ rOutProperties.push_back(
+ Property( C2U( "ErrorBarStyle" ),
+ PROP_ERROR_BAR_STYLE,
+ ::getCppuType( reinterpret_cast< sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "PositiveError" ),
+ PROP_ERROR_BAR_POS_ERROR,
+ ::getCppuType( reinterpret_cast< const double * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "NegativeError" ),
+ PROP_ERROR_BAR_NEG_ERROR,
+ ::getCppuType( reinterpret_cast< const double * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "Weight" ),
+ PROP_ERROR_BAR_WEIGHT,
+ ::getCppuType( reinterpret_cast< const double * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "ShowPositiveError" ),
+ PROP_ERROR_BAR_SHOW_POS_ERROR,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "ShowNegativeError" ),
+ PROP_ERROR_BAR_SHOW_NEG_ERROR,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+void lcl_AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_ERROR_BAR_STYLE, ::com::sun::star::chart::ErrorBarStyle::NONE );
+ ::chart::PropertyHelper::setPropertyValueDefault< double >( rOutMap, PROP_ERROR_BAR_POS_ERROR, 0.0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< double >( rOutMap, PROP_ERROR_BAR_NEG_ERROR, 0.0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< double >( rOutMap, PROP_ERROR_BAR_WEIGHT, 1.0 );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_ERROR_BAR_SHOW_POS_ERROR, true );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_ERROR_BAR_SHOW_NEG_ERROR, true );
+}
+
+const uno::Sequence< Property > & lcl_GetPropertySequence()
+{
+ static uno::Sequence< Property > aPropSeq;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aPropSeq.getLength() )
+ {
+ // get properties
+ ::std::vector< ::com::sun::star::beans::Property > aProperties;
+ lcl_AddPropertiesToVector( aProperties );
+ ::chart::LineProperties::AddPropertiesToVector( aProperties );
+
+ // and sort them for access via bsearch
+ ::std::sort( aProperties.begin(), aProperties.end(),
+ ::chart::PropertyNameLess() );
+
+ // transfer result to static Sequence
+ aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
+ }
+
+ return aPropSeq;
+}
+
+::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper aArrayHelper(
+ lcl_GetPropertySequence(),
+ /* bSorted = */ sal_True );
+
+ return aArrayHelper;
+}
+
+bool lcl_isInternalData( const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq )
+{
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xLSeq, uno::UNO_QUERY );
+ return ( xServiceInfo.is() && xServiceInfo->getImplementationName().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.comp.chart2.LabeledDataSequence")));
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+uno::Reference< beans::XPropertySet > createErrorBar( const uno::Reference< uno::XComponentContext > & xContext )
+{
+ return new ErrorBar( xContext );
+}
+
+ErrorBar::ErrorBar(
+ uno::Reference< uno::XComponentContext > const & xContext ) :
+ ::property::OPropertySet( m_aMutex ),
+ m_xContext( xContext ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{}
+
+ErrorBar::ErrorBar( const ErrorBar & rOther ) :
+ MutexContainer(),
+ impl::ErrorBar_Base(),
+ ::property::OPropertySet( rOther, m_aMutex ),
+ m_xContext( rOther.m_xContext ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ if( ! rOther.m_aDataSequences.empty())
+ {
+ if( lcl_isInternalData( rOther.m_aDataSequences.front()))
+ CloneHelper::CloneRefVector< tDataSequenceContainer::value_type >(
+ rOther.m_aDataSequences, m_aDataSequences );
+ else
+ m_aDataSequences = rOther.m_aDataSequences;
+ ModifyListenerHelper::addListenerToAllElements( m_aDataSequences, m_xModifyEventForwarder );
+ }
+}
+
+ErrorBar::~ErrorBar()
+{}
+
+uno::Reference< util::XCloneable > SAL_CALL ErrorBar::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new ErrorBar( *this ));
+}
+
+// ================================================================================
+
+// ____ OPropertySet ____
+uno::Any ErrorBar::GetDefaultValue( sal_Int32 nHandle ) const
+ throw(beans::UnknownPropertyException)
+{
+ static tPropertyValueMap aStaticDefaults;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aStaticDefaults.size() )
+ {
+ // initialize defaults
+ lcl_AddDefaultsToMap( aStaticDefaults );
+ LineProperties::AddDefaultsToMap( aStaticDefaults );
+ }
+
+ tPropertyValueMap::const_iterator aFound(
+ aStaticDefaults.find( nHandle ));
+
+ if( aFound == aStaticDefaults.end())
+ return uno::Any();
+
+ return (*aFound).second;
+ // \--
+}
+
+::cppu::IPropertyArrayHelper & SAL_CALL ErrorBar::getInfoHelper()
+{
+ return lcl_getInfoHelper();
+}
+
+
+// ____ XPropertySet ____
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ ErrorBar::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is())
+ {
+ xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
+ getInfoHelper());
+ }
+
+ return xInfo;
+ // \--
+}
+
+// ____ XModifyBroadcaster ____
+void SAL_CALL ErrorBar::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL ErrorBar::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// ____ XModifyListener ____
+void SAL_CALL ErrorBar::modified( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ m_xModifyEventForwarder->modified( aEvent );
+}
+
+// ____ XEventListener (base of XModifyListener) ____
+void SAL_CALL ErrorBar::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ // nothing
+}
+
+// ____ XDataSink ____
+void SAL_CALL ErrorBar::setData( const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > >& aData )
+ throw (uno::RuntimeException)
+{
+ ModifyListenerHelper::removeListenerFromAllElements( m_aDataSequences, m_xModifyEventForwarder );
+ EventListenerHelper::removeListenerFromAllElements( m_aDataSequences, this );
+ m_aDataSequences = ContainerHelper::SequenceToVector( aData );
+ EventListenerHelper::addListenerToAllElements( m_aDataSequences, this );
+ ModifyListenerHelper::addListenerToAllElements( m_aDataSequences, m_xModifyEventForwarder );
+}
+
+// ____ XDataSource ____
+uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > SAL_CALL ErrorBar::getDataSequences()
+ throw (uno::RuntimeException)
+{
+ return ContainerHelper::ContainerToSequence( m_aDataSequences );
+}
+
+// ____ XChild ____
+uno::Reference< uno::XInterface > SAL_CALL ErrorBar::getParent()
+ throw (uno::RuntimeException)
+{
+ return m_xParent;
+}
+
+void SAL_CALL ErrorBar::setParent(
+ const uno::Reference< uno::XInterface >& Parent )
+ throw (lang::NoSupportException,
+ uno::RuntimeException)
+{
+ m_xParent.set( Parent );
+}
+
+// ____ OPropertySet ____
+void ErrorBar::firePropertyChangeEvent()
+{
+ fireModifyEvent();
+}
+
+void ErrorBar::fireModifyEvent()
+{
+ m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
+}
+
+// ================================================================================
+
+uno::Sequence< ::rtl::OUString > ErrorBar::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.ErrorBar" );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( ErrorBar, lcl_aServiceName );
+
+// needed by MSC compiler
+using impl::ErrorBar_Base;
+
+IMPLEMENT_FORWARD_XINTERFACE2( ErrorBar, ErrorBar_Base, OPropertySet )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( ErrorBar, ErrorBar_Base, OPropertySet )
+
+} // namespace chart
diff --git a/chart2/source/tools/ExplicitCategoriesProvider.cxx b/chart2/source/tools/ExplicitCategoriesProvider.cxx
new file mode 100644
index 000000000000..bd1c1bb79813
--- /dev/null
+++ b/chart2/source/tools/ExplicitCategoriesProvider.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ExplicitCategoriesProvider.hxx"
+#include "DiagramHelper.hxx"
+#include "CommonConverters.hxx"
+#include "DataSourceHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "macros.hxx"
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+using ::std::vector;
+
+
+ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2::XCoordinateSystem >& xCooSysModel
+ , const uno::Reference< frame::XModel >& xChartModel )
+ : m_bDirty(true)
+ , m_xCooSysModel( xCooSysModel )
+ , m_xOriginalCategories()
+{
+ try
+ {
+ if( xCooSysModel.is() )
+ {
+ uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
+ if( xAxis.is() )
+ m_xOriginalCategories = xAxis->getScaleData().Categories;
+ }
+
+ if( m_xOriginalCategories.is() )
+ {
+ Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
+ if( xChartDoc.is() )
+ {
+ uno::Reference< data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
+
+ if( xDataProvider.is() )
+ {
+ OUString aCatgoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
+ const bool bFirstCellAsLabel = false;
+ const bool bHasCategories = false;
+ const uno::Sequence< sal_Int32 > aSequenceMapping;
+
+ uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
+ DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, true /*bUseColumns*/
+ , bFirstCellAsLabel, bHasCategories ) ) );
+
+ uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
+ DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, false /*bUseColumns*/
+ , bFirstCellAsLabel, bHasCategories ) ) );
+
+ if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() )
+ {
+ Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
+ Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
+
+ sal_Int32 nColumnCount = aColumns.getLength();
+ sal_Int32 nRowCount = aRows.getLength();
+ if( nColumnCount>1 && nRowCount>1 )
+ {
+ //we have complex categories
+ //->split them in the direction of the first series
+ //detect whether the first series is a row or a column
+ bool bSeriesUsesColumns = true;
+ ::std::vector< Reference< XDataSeries > > aSeries( ChartModelHelper::getDataSeries( xChartModel ) );
+ if( !aSeries.empty() )
+ {
+ uno::Reference< data::XDataSource > xSeriesSource( aSeries.front(), uno::UNO_QUERY );
+ ::rtl::OUString aStringDummy;
+ bool bDummy;
+ uno::Sequence< sal_Int32 > aSeqDummy;
+ DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource),
+ aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy );
+ }
+ if( bSeriesUsesColumns )
+ m_aSplitCategoriesList=aColumns;
+ else
+ m_aSplitCategoriesList=aRows;
+ }
+ }
+ }
+ }
+ if( !m_aSplitCategoriesList.getLength() )
+ {
+ m_aSplitCategoriesList.realloc(1);
+ m_aSplitCategoriesList[0]=m_xOriginalCategories;
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
+{
+}
+
+const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList()
+{
+ return m_aSplitCategoriesList;
+}
+
+bool ExplicitCategoriesProvider::hasComplexCategories() const
+{
+ return m_aSplitCategoriesList.getLength() > 1;
+}
+
+sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const
+{
+ sal_Int32 nCount = m_aSplitCategoriesList.getLength();
+ if(!nCount)
+ nCount = 1;
+ return nCount;
+}
+
+std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories )
+{
+ std::vector<sal_Int32> aLimitingBorders;
+ std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
+ std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
+ sal_Int32 nBorderIndex = 0; /*border below the index*/
+ for( ; aIt != aEnd; ++aIt )
+ {
+ ComplexCategory aComplexCategory(*aIt);
+ nBorderIndex += aComplexCategory.Count;
+ aLimitingBorders.push_back(nBorderIndex);
+ }
+ return aLimitingBorders;
+}
+
+uno::Sequence< rtl::OUString > lcl_DataToStringSequence( const uno::Reference< data::XDataSequence >& xDataSequence )
+{
+ uno::Sequence< rtl::OUString > aStrings;
+
+ OSL_ASSERT( xDataSequence.is());
+ if( !xDataSequence.is() )
+ return aStrings;
+
+
+ uno::Reference< data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY );
+ if( xTextualDataSequence.is() )
+ {
+ aStrings = xTextualDataSequence->getTextualData();
+ }
+ else
+ {
+ uno::Sequence< uno::Any > aValues = xDataSequence->getData();
+ aStrings.realloc(aValues.getLength());
+
+ for(sal_Int32 nN=aValues.getLength();nN--;)
+ aValues[nN] >>= aStrings[nN];
+ }
+
+ return aStrings;
+}
+
+SplitCategoriesProvider::~SplitCategoriesProvider()
+{
+}
+
+class SplitCategoriesProvider_ForLabeledDataSequences : public SplitCategoriesProvider
+{
+public:
+
+ explicit SplitCategoriesProvider_ForLabeledDataSequences( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::data::XLabeledDataSequence> >& rSplitCategoriesList )
+ : m_rSplitCategoriesList( rSplitCategoriesList )
+ {}
+ virtual ~SplitCategoriesProvider_ForLabeledDataSequences()
+ {}
+
+ virtual sal_Int32 getLevelCount() const;
+ virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
+
+private:
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::data::XLabeledDataSequence> >& m_rSplitCategoriesList;
+};
+
+sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount() const
+{
+ return m_rSplitCategoriesList.getLength();
+}
+uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel ) const
+{
+ uno::Sequence< rtl::OUString > aRet;
+ Reference< data::XLabeledDataSequence > xLabeledDataSequence( m_rSplitCategoriesList[nLevel] );
+ if( xLabeledDataSequence.is() )
+ aRet = lcl_DataToStringSequence( xLabeledDataSequence->getValues() );
+ return aRet;
+}
+
+std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
+ const uno::Sequence< rtl::OUString >& rStrings
+ , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
+{
+ std::vector< ComplexCategory > aResult;
+
+ sal_Int32 nMaxCount = rStrings.getLength();
+ OUString aPrevious;
+ sal_Int32 nCurrentCount=0;
+ for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
+ {
+ OUString aCurrent = rStrings[nN];
+ if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
+ {
+ aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
+ nCurrentCount=1;
+ aPrevious = aCurrent;
+ }
+ else
+ {
+ if( aCurrent.getLength() && aPrevious != aCurrent )
+ {
+ aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
+ nCurrentCount=1;
+ aPrevious = aCurrent;
+ }
+ else
+ nCurrentCount++;
+ }
+ }
+ if( nCurrentCount )
+ aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
+
+ return aResult;
+}
+
+sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories )
+{
+ sal_Int32 nCount = 0;
+ std::vector< ComplexCategory >::iterator aIt( rComplexCategories.begin() );
+ std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
+ for( ; aIt != aEnd; ++aIt )
+ nCount+=aIt->Count;
+ return nCount;
+}
+
+Sequence< OUString > lcl_getExplicitSimpleCategories(
+ const SplitCategoriesProvider& rSplitCategoriesProvider,
+ ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats )
+{
+ Sequence< OUString > aRet;
+
+ rComplexCats.clear();
+ sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount();
+ for( sal_Int32 nL = 0; nL < nLCount; nL++ )
+ {
+ std::vector<sal_Int32> aLimitingBorders;
+ if(nL>0)
+ aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() );
+ rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector(
+ rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
+ }
+
+ std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() );
+ std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() );
+
+ //ensure that the category count is the same on each level
+ sal_Int32 nMaxCategoryCount = 0;
+ {
+ for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
+ {
+ sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
+ nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
+ }
+ for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
+ {
+ sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
+ if( nCurrentCount< nMaxCategoryCount )
+ {
+ ComplexCategory& rComplexCategory = aOuterIt->back();
+ rComplexCategory.Count += (nMaxCategoryCount-nCurrentCount);
+ }
+ }
+ }
+
+ //create a list with an element for every index
+ std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
+ for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
+ {
+ std::vector< ComplexCategory > aSingleLevel;
+ std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
+ std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() );
+ for( ; aIt != aEnd; ++aIt )
+ {
+ ComplexCategory aComplexCategory( *aIt );
+ sal_Int32 nCount = aComplexCategory.Count;
+ while( nCount-- )
+ aSingleLevel.push_back(aComplexCategory);
+ }
+ aComplexCatsPerIndex.push_back( aSingleLevel );
+ }
+
+ if(nMaxCategoryCount)
+ {
+ aRet.realloc(nMaxCategoryCount);
+ aOuterEnd = aComplexCatsPerIndex.end();
+ OUString aSpace(C2U(" "));
+ for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
+ {
+ OUString aText;
+ for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
+ {
+ OUString aAddText = (*aOuterIt)[nN].Text;
+ if( aAddText.getLength() )
+ {
+ if(aText.getLength())
+ aText += aSpace;
+ aText += aAddText;
+ }
+ }
+ aRet[nN]=aText;
+ }
+ }
+ return aRet;
+}
+
+//static
+Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories(
+ const SplitCategoriesProvider& rSplitCategoriesProvider )
+{
+ vector< vector< ComplexCategory > > aComplexCats;
+ return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats );
+}
+
+void ExplicitCategoriesProvider::init()
+{
+ if( m_bDirty )
+ {
+ m_aExplicitCategories.realloc(0);
+ m_aComplexCats.clear();//not one per index
+
+ if( m_xOriginalCategories.is() )
+ {
+ if( !hasComplexCategories() )
+ m_aExplicitCategories = DataSequenceToStringSequence(m_xOriginalCategories->getValues());
+ else
+ m_aExplicitCategories = lcl_getExplicitSimpleCategories(
+ SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList ), m_aComplexCats );
+ }
+ if(!m_aExplicitCategories.getLength())
+ m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
+ m_bDirty = false;
+ }
+}
+
+
+Sequence< ::rtl::OUString > ExplicitCategoriesProvider::getSimpleCategories()
+{
+ init();
+ return m_aExplicitCategories;
+}
+
+std::vector< ComplexCategory > ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
+{
+ std::vector< ComplexCategory > aRet;
+ init();
+ sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
+ if( nLevel >= 0 && nLevel <= nMaxIndex )
+ aRet = m_aComplexCats[nMaxIndex-nLevel];
+ return aRet;
+}
+
+// static
+OUString ExplicitCategoriesProvider::getCategoryByIndex(
+ const Reference< XCoordinateSystem >& xCooSysModel
+ , const uno::Reference< frame::XModel >& xChartModel
+ , sal_Int32 nIndex )
+{
+ if( xCooSysModel.is())
+ {
+ ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, xChartModel );
+ Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories());
+ if( nIndex < aCategories.getLength())
+ return aCategories[ nIndex ];
+ }
+ return OUString();
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..d7bb86174323
--- /dev/null
+++ b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "ExponentialRegressionCurveCalculator.hxx"
+#include "macros.hxx"
+#include "RegressionCalculationHelper.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+ExponentialRegressionCurveCalculator::ExponentialRegressionCurveCalculator() :
+ m_fSlope( 0.0 ),
+ m_fIntercept( 0.0 )
+{
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+}
+
+ExponentialRegressionCurveCalculator::~ExponentialRegressionCurveCalculator()
+{}
+
+// ____ XRegressionCurveCalculator ____
+void SAL_CALL ExponentialRegressionCurveCalculator::recalculateRegression(
+ const uno::Sequence< double >& aXValues,
+ const uno::Sequence< double >& aYValues )
+ throw (uno::RuntimeException)
+{
+ RegressionCalculationHelper::tDoubleVectorPair aValues(
+ RegressionCalculationHelper::cleanup(
+ aXValues, aYValues,
+ RegressionCalculationHelper::isValidAndYPositive()));
+
+ const size_t nMax = aValues.first.size();
+ if( nMax == 0 )
+ {
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+ ::rtl::math::setNan( & m_fCorrelationCoeffitient );
+ return;
+ }
+
+ double fAverageX = 0.0, fAverageY = 0.0;
+ size_t i = 0;
+ for( i = 0; i < nMax; ++i )
+ {
+ fAverageX += aValues.first[i];
+ fAverageY += log( aValues.second[i] );
+ }
+
+ const double fN = static_cast< double >( nMax );
+ fAverageX /= fN;
+ fAverageY /= fN;
+
+ double fQx = 0.0, fQy = 0.0, fQxy = 0.0;
+ for( i = 0; i < nMax; ++i )
+ {
+ double fDeltaX = aValues.first[i] - fAverageX;
+ double fDeltaY = log( aValues.second[i] ) - fAverageY;
+
+ fQx += fDeltaX * fDeltaX;
+ fQy += fDeltaY * fDeltaY;
+ fQxy += fDeltaX * fDeltaY;
+ }
+
+ m_fSlope = fQxy / fQx;
+ m_fIntercept = fAverageY - m_fSlope * fAverageX;
+ m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy );
+
+ m_fSlope = exp( m_fSlope );
+ m_fIntercept = exp( m_fIntercept );
+}
+
+double SAL_CALL ExponentialRegressionCurveCalculator::getCurveValue( double x )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ double fResult;
+ ::rtl::math::setNan( & fResult );
+
+ if( ! ( ::rtl::math::isNan( m_fSlope ) ||
+ ::rtl::math::isNan( m_fIntercept )))
+ {
+ fResult = m_fIntercept * pow( m_fSlope, x );
+ }
+
+ return fResult;
+}
+
+uno::Sequence< geometry::RealPoint2D > SAL_CALL ExponentialRegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const uno::Reference< chart2::XScaling >& xScalingX,
+ const uno::Reference< chart2::XScaling >& xScalingY,
+ ::sal_Bool bMaySkipPointsInCalculation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( bMaySkipPointsInCalculation &&
+ isLinearScaling( xScalingX ) &&
+ isLogarithmicScaling( xScalingY ))
+ {
+ // optimize result
+ uno::Sequence< geometry::RealPoint2D > aResult( 2 );
+ aResult[0].X = min;
+ aResult[0].Y = this->getCurveValue( min );
+ aResult[1].X = max;
+ aResult[1].Y = this->getCurveValue( max );
+
+ return aResult;
+ }
+
+ return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
+}
+
+
+OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation(
+ const uno::Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey ) const
+{
+ OUStringBuffer aBuf( C2U( "f(x) = " ));
+
+ if( m_fIntercept == 0.0 ||
+ m_fSlope == 0.0 )
+ {
+ aBuf.append( sal_Unicode( '0' ));
+ }
+ else if( rtl::math::approxEqual( m_fSlope, 1.0 ) )
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+ else
+ {
+ if( ! rtl::math::approxEqual( m_fIntercept, 1.0 ) )
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ aBuf.append( sal_Unicode( 0x00b7 ));
+ }
+
+ if( m_fSlope < 0.0 )
+ aBuf.append( sal_Unicode( '(' ));
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fSlope ));
+ if( m_fSlope < 0.0 )
+ aBuf.append( sal_Unicode( ')' ));
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "^x" ));
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/FillProperties.cxx b/chart2/source/tools/FillProperties.cxx
new file mode 100644
index 000000000000..ee23727c321b
--- /dev/null
+++ b/chart2/source/tools/FillProperties.cxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "FillProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+
+namespace chart
+{
+
+namespace
+{
+
+void lcl_AddPropertiesToVector_without_BitmapProperties( ::std::vector< ::com::sun::star::beans::Property > & rOutProperties )
+{
+ rOutProperties.push_back(
+ Property( C2U( "FillStyle" ),
+ FillProperties::PROP_FILL_STYLE,
+ ::getCppuType( reinterpret_cast< const drawing::FillStyle * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillColor" ),
+ FillProperties::PROP_FILL_COLOR,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID // "maybe auto"
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillTransparence" ),
+ FillProperties::PROP_FILL_TRANSPARENCE,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillTransparenceGradientName" ),
+ FillProperties::PROP_FILL_TRANSPARENCE_GRADIENT_NAME,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ //optional
+// rOutProperties.push_back(
+// Property( C2U( "FillTransparenceGradient" ),
+// FillProperties::PROP_FILL_TRANSPARENCE_GRADIENT,
+// ::getCppuType( reinterpret_cast< const awt::Gradient * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT
+// | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillGradientName" ),
+ FillProperties::PROP_FILL_GRADIENT_NAME,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ beans::Property( C2U( "FillGradientStepCount" ),
+ FillProperties::PROP_FILL_GRADIENT_STEPCOUNT,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ //optional
+// rOutProperties.push_back(
+// Property( C2U( "FillGradient" ),
+// FillProperties::PROP_FILL_GRADIENT,
+// ::getCppuType( reinterpret_cast< const awt::Gradient * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT
+// | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillHatchName" ),
+ FillProperties::PROP_FILL_HATCH_NAME,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ //optional
+// rOutProperties.push_back(
+// Property( C2U( "FillHatch" ),
+// FillProperties::PROP_FILL_HATCH,
+// ::getCppuType( reinterpret_cast< const drawing::Hatch * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT
+// | beans::PropertyAttribute::MAYBEVOID ));
+
+ //bitmap properties see lcl_AddPropertiesToVector_only_BitmapProperties()
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBackground" ),
+ FillProperties::PROP_FILL_BACKGROUND,
+ ::getCppuType( reinterpret_cast< const sal_Bool * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+//static
+void lcl_AddPropertiesToVector_only_BitmapProperties( ::std::vector< ::com::sun::star::beans::Property > & rOutProperties )
+{
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapName" ),
+ FillProperties::PROP_FILL_BITMAP_NAME,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ //optional
+// rOutProperties.push_back(
+// Property( C2U( "FillBitmap" ),
+// FillProperties::PROP_FILL_BITMAP,
+// ::getCppuType( reinterpret_cast< const uno::Reference< awt::XBitmap > * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ //optional
+// rOutProperties.push_back(
+// Property( C2U( "FillBitmapURL" ),
+// FillProperties::PROP_FILL_BITMAP_URL,
+// ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapOffsetX" ),
+ FillProperties::PROP_FILL_BITMAP_OFFSETX,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapOffsetY" ),
+ FillProperties::PROP_FILL_BITMAP_OFFSETY,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapPositionOffsetX" ),
+ FillProperties::PROP_FILL_BITMAP_POSITION_OFFSETX,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapPositionOffsetY" ),
+ FillProperties::PROP_FILL_BITMAP_POSITION_OFFSETY,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapRectanglePoint" ),
+ FillProperties::PROP_FILL_BITMAP_RECTANGLEPOINT,
+ ::getCppuType( reinterpret_cast< const drawing::RectanglePoint * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapLogicalSize" ),
+ FillProperties::PROP_FILL_BITMAP_LOGICALSIZE,
+ ::getCppuType( reinterpret_cast< const sal_Bool * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapSizeX" ),
+ FillProperties::PROP_FILL_BITMAP_SIZEX,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapSizeY" ),
+ FillProperties::PROP_FILL_BITMAP_SIZEY,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapMode" ),
+ FillProperties::PROP_FILL_BITMAP_MODE,
+ ::getCppuType( reinterpret_cast< const drawing::BitmapMode * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+
+void lcl_AddDefaultsToMap_without_BitmapProperties(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, FillProperties::PROP_FILL_STYLE, drawing::FillStyle_SOLID );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, FillProperties::PROP_FILL_COLOR, 0xd9d9d9 ); // gray85
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_TRANSPARENCE, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, FillProperties::PROP_FILL_BACKGROUND, false );
+}
+
+void lcl_AddDefaultsToMap_only_BitmapProperties(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ uno::Any aSalInt16Zero = uno::makeAny( sal_Int16( 0 ));
+ uno::Any aSalInt32SizeDefault = uno::makeAny( sal_Int32( 0 ));
+
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_OFFSETX, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_OFFSETY, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_POSITION_OFFSETX, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_POSITION_OFFSETY, 0 );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, FillProperties::PROP_FILL_BITMAP_RECTANGLEPOINT, drawing::RectanglePoint_MIDDLE_MIDDLE );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, FillProperties::PROP_FILL_BITMAP_LOGICALSIZE, true );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, FillProperties::PROP_FILL_BITMAP_SIZEX, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, FillProperties::PROP_FILL_BITMAP_SIZEY, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, FillProperties::PROP_FILL_BITMAP_MODE, drawing::BitmapMode_REPEAT );
+}
+
+}//end anonymous namespace
+
+void FillProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ // Fill Properties see service drawing::FillProperties
+ // ---------------
+ lcl_AddPropertiesToVector_without_BitmapProperties( rOutProperties );
+ lcl_AddPropertiesToVector_only_BitmapProperties( rOutProperties );
+}
+
+void FillProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ lcl_AddDefaultsToMap_without_BitmapProperties( rOutMap );
+ lcl_AddDefaultsToMap_only_BitmapProperties( rOutMap );
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/FormattedStringHelper.cxx b/chart2/source/tools/FormattedStringHelper.cxx
new file mode 100644
index 000000000000..c13c87d45931
--- /dev/null
+++ b/chart2/source/tools/FormattedStringHelper.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "FormattedStringHelper.hxx"
+#include "macros.hxx"
+#include "PropertyHelper.hxx"
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using rtl::OUString;
+
+Sequence< Reference< chart2::XFormattedString > >
+ FormattedStringHelper::createFormattedStringSequence(
+ const Reference< uno::XComponentContext > & xContext
+ , const OUString & rString
+ , const Reference< beans::XPropertySet > & xTextProperties ) throw()
+{
+ Reference< XFormattedString > xFormStr;
+ try
+ {
+ if( xContext.is() )
+ {
+ xFormStr.set(
+ xContext->getServiceManager()->createInstanceWithContext(
+ C2U("com.sun.star.chart2.FormattedString"), xContext ),
+ uno::UNO_QUERY_THROW );
+
+ xFormStr->setString( rString );
+
+ // set character properties
+ comphelper::copyProperties(
+ xTextProperties, Reference< beans::XPropertySet >( xFormStr, uno::UNO_QUERY ) );
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return Sequence< Reference< XFormattedString > >( & xFormStr, 1 );
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
+
diff --git a/chart2/source/tools/ImplOPropertySet.cxx b/chart2/source/tools/ImplOPropertySet.cxx
new file mode 100644
index 000000000000..faf1defd20ac
--- /dev/null
+++ b/chart2/source/tools/ImplOPropertySet.cxx
@@ -0,0 +1,207 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "ImplOPropertySet.hxx"
+#include "CloneHelper.hxx"
+
+#include <algorithm>
+#include <functional>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+
+namespace
+{
+
+struct lcl_getPropertyStateByHandle :
+ public ::std::unary_function< sal_Int32, beans::PropertyState >
+{
+ lcl_getPropertyStateByHandle(
+ const ::property::impl::ImplOPropertySet::tPropertyMap & rMap )
+ : m_rMap( rMap )
+ {}
+
+ inline beans::PropertyState operator() ( sal_Int32 nHandle )
+ {
+ if( m_rMap.end() == m_rMap.find( nHandle ))
+ return beans::PropertyState_DEFAULT_VALUE;
+ return beans::PropertyState_DIRECT_VALUE;
+ }
+
+private:
+ const ::property::impl::ImplOPropertySet::tPropertyMap & m_rMap;
+};
+
+template< typename K, typename V >
+struct lcl_eraseMapEntry :
+ public ::std::unary_function< K, void >
+{
+ lcl_eraseMapEntry( ::std::map< K, V > & rMap )
+ : m_rMap( rMap )
+ {}
+
+ inline void operator() ( const K & aKey )
+ {
+ m_rMap.erase( aKey );
+ }
+
+private:
+ ::std::map< K, V > m_rMap;
+};
+
+struct lcl_replaceInterfacePropertiesByClones :
+ public ::std::unary_function< ::property::impl::ImplOPropertySet::tPropertyMap::value_type, void >
+{
+ inline void operator() ( ::property::impl::ImplOPropertySet::tPropertyMap::value_type & rProp )
+ {
+ if( rProp.second.hasValue() &&
+ rProp.second.getValueType().getTypeClass() == uno::TypeClass_INTERFACE )
+ {
+ Reference< util::XCloneable > xCloneable;
+ if( rProp.second >>= xCloneable )
+ rProp.second <<= xCloneable->createClone();
+ }
+ }
+};
+
+} // anonymous namespace
+
+namespace property
+{
+namespace impl
+{
+
+ImplOPropertySet::ImplOPropertySet()
+{}
+
+ImplOPropertySet::ImplOPropertySet( const ImplOPropertySet & rOther )
+{
+ ::std::copy( rOther.m_aProperties.begin(), rOther.m_aProperties.end(),
+ ::std::inserter( m_aProperties, m_aProperties.begin() ));
+ cloneInterfaceProperties();
+ m_xStyle.set( ::chart::CloneHelper::CreateRefClone< Reference< style::XStyle > >()( rOther.m_xStyle ));
+}
+
+beans::PropertyState ImplOPropertySet::GetPropertyStateByHandle( sal_Int32 nHandle ) const
+{
+ return lcl_getPropertyStateByHandle( m_aProperties ) ( nHandle );
+}
+
+Sequence< beans::PropertyState > ImplOPropertySet::GetPropertyStatesByHandle(
+ const ::std::vector< sal_Int32 > & aHandles ) const
+{
+ Sequence< beans::PropertyState > aResult( aHandles.size());
+
+ ::std::transform( aHandles.begin(), aHandles.end(),
+ aResult.getArray(),
+ lcl_getPropertyStateByHandle( m_aProperties ));
+
+ return aResult;
+}
+
+void ImplOPropertySet::SetPropertyToDefault( sal_Int32 nHandle )
+{
+ tPropertyMap::iterator aFoundIter( m_aProperties.find( nHandle ) );
+
+ if( m_aProperties.end() != aFoundIter )
+ {
+ m_aProperties.erase( aFoundIter );
+ }
+}
+
+void ImplOPropertySet::SetPropertiesToDefault(
+ const ::std::vector< sal_Int32 > & aHandles )
+{
+ ::std::for_each( aHandles.begin(), aHandles.end(),
+ lcl_eraseMapEntry< sal_Int32, Any >( m_aProperties ) );
+}
+
+void ImplOPropertySet::SetAllPropertiesToDefault()
+{
+ m_aProperties.clear();
+}
+
+bool ImplOPropertySet::GetPropertyValueByHandle(
+ Any & rValue,
+ sal_Int32 nHandle ) const
+{
+ bool bResult = false;
+
+ tPropertyMap::const_iterator aFoundIter( m_aProperties.find( nHandle ) );
+
+ if( m_aProperties.end() != aFoundIter )
+ {
+ rValue = (*aFoundIter).second;
+ bResult = true;
+ }
+
+ return bResult;
+}
+
+void ImplOPropertySet::SetPropertyValueByHandle(
+ sal_Int32 nHandle, const Any & rValue, Any * pOldValue )
+{
+ if( pOldValue != NULL )
+ {
+ tPropertyMap::const_iterator aFoundIter( m_aProperties.find( nHandle ) );
+ if( m_aProperties.end() != aFoundIter )
+ (*pOldValue) = (*aFoundIter).second;
+ }
+
+ m_aProperties[ nHandle ] = rValue;
+}
+
+bool ImplOPropertySet::SetStyle( const Reference< style::XStyle > & xStyle )
+{
+ if( ! xStyle.is())
+ return false;
+
+ m_xStyle = xStyle;
+ return true;
+}
+
+Reference< style::XStyle > ImplOPropertySet::GetStyle() const
+{
+ return m_xStyle;
+}
+
+void ImplOPropertySet::cloneInterfaceProperties()
+{
+ ::std::for_each( m_aProperties.begin(), m_aProperties.end(),
+ lcl_replaceInterfacePropertiesByClones());
+}
+
+
+} // namespace impl
+} // namespace chart
diff --git a/chart2/source/tools/ImplOPropertySet.hxx b/chart2/source/tools/ImplOPropertySet.hxx
new file mode 100644
index 000000000000..505ab598d7da
--- /dev/null
+++ b/chart2/source/tools/ImplOPropertySet.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART_IMPLOPROPERTYSET_HXX
+#define CHART_IMPLOPROPERTYSET_HXX
+
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/style/XStyle.hpp>
+
+#include <map>
+#include <vector>
+
+namespace property
+{
+namespace impl
+{
+
+class ImplOPropertySet
+{
+public:
+ ImplOPropertySet();
+ explicit ImplOPropertySet( const ImplOPropertySet & rOther );
+
+ /** supports states DIRECT_VALUE and DEFAULT_VALUE
+ */
+ ::com::sun::star::beans::PropertyState
+ GetPropertyStateByHandle( sal_Int32 nHandle ) const;
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState >
+ GetPropertyStatesByHandle( const ::std::vector< sal_Int32 > & aHandles ) const;
+
+ void SetPropertyToDefault( sal_Int32 nHandle );
+ void SetPropertiesToDefault( const ::std::vector< sal_Int32 > & aHandles );
+ void SetAllPropertiesToDefault();
+
+ /** @param rValue is set to the value for the property given in nHandle. If
+ the property is not set, the style chain is searched for any
+ instance set there. If there was no value found either in the
+ property set itself or any of its styles, rValue remains
+ unchanged and false is returned.
+
+ @return false if the property is default, true otherwise.
+ */
+ bool GetPropertyValueByHandle(
+ ::com::sun::star::uno::Any & rValue,
+ sal_Int32 nHandle ) const;
+
+ void SetPropertyValueByHandle( sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any & rValue,
+ ::com::sun::star::uno::Any * pOldValue = NULL );
+
+ bool SetStyle( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > & xStyle );
+ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >
+ GetStyle() const;
+
+ typedef
+ ::std::map< sal_Int32, ::com::sun::star::uno::Any >
+ tPropertyMap;
+
+private:
+ void cloneInterfaceProperties();
+
+ tPropertyMap m_aProperties;
+ ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >
+ m_xStyle;
+};
+
+} // namespace impl
+} // namespace chart
+
+// CHART_IMPLOPROPERTYSET_HXX
+#endif
diff --git a/chart2/source/tools/InternalData.cxx b/chart2/source/tools/InternalData.cxx
new file mode 100755
index 000000000000..65fc97a04b38
--- /dev/null
+++ b/chart2/source/tools/InternalData.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "InternalData.hxx"
+#include "ResId.hxx"
+#include "Strings.hrc"
+#include "macros.hxx"
+
+#include <rtl/math.hxx>
+
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+using namespace ::std;
+
+namespace chart
+{
+
+// ----------------------------------------
+namespace
+{
+struct lcl_NumberedStringGenerator
+{
+ lcl_NumberedStringGenerator( const OUString & rStub, const OUString & rWildcard ) :
+ m_aStub( rStub ),
+ m_nCounter( 0 ),
+ m_nStubStartIndex( rStub.indexOf( rWildcard )),
+ m_nWildcardLength( rWildcard.getLength())
+ {
+ }
+ vector< OUString > operator()()
+ {
+ vector< OUString > aRet(1);
+ aRet[0] = m_aStub.replaceAt( m_nStubStartIndex, m_nWildcardLength, OUString::valueOf( ++m_nCounter ));
+ return aRet;
+ }
+private:
+ OUString m_aStub;
+ sal_Int32 m_nCounter;
+ const sal_Int32 m_nStubStartIndex;
+ const sal_Int32 m_nWildcardLength;
+};
+
+template< typename T >
+ Sequence< T > lcl_ValarrayToSequence( const ::std::valarray< T > & rValarray )
+{
+ // is there a more elegant way of conversion?
+ Sequence< T > aResult( rValarray.size());
+ for( size_t i = 0; i < rValarray.size(); ++i )
+ aResult[i] = rValarray[i];
+ return aResult;
+}
+
+} // anonymous namespace
+// ----------------------------------------
+
+InternalData::InternalData()
+ : m_nColumnCount( 0 )
+ , m_nRowCount( 0 )
+ , m_aRowLabels( 0 )
+ , m_aColumnLabels( 0 )
+{}
+
+void InternalData::createDefaultData()
+{
+ const sal_Int32 nRowCount = 4;
+ const sal_Int32 nColumnCount = 3;
+
+ m_nRowCount = nRowCount;
+ m_nColumnCount = nColumnCount;
+ const sal_Int32 nSize = nColumnCount * nRowCount;
+ // @todo: localize this!
+ const OUString aRowName( ::chart::SchResId::getResString( STR_ROW_LABEL ));
+ const OUString aColName( ::chart::SchResId::getResString( STR_COLUMN_LABEL ));
+
+ const double fDefaultData[ nSize ] =
+ { 9.10, 3.20, 4.54,
+ 2.40, 8.80, 9.65,
+ 3.10, 1.50, 3.70,
+ 4.30, 9.02, 6.20 };
+
+ m_aData.resize( nSize );
+ for( sal_Int32 i=0; i<nSize; ++i )
+ m_aData[i] = fDefaultData[i];
+
+ m_aRowLabels.clear();
+ m_aRowLabels.reserve( m_nRowCount );
+ generate_n( back_inserter( m_aRowLabels ), m_nRowCount,
+ lcl_NumberedStringGenerator( aRowName, C2U("%ROWNUMBER") ));
+
+ m_aColumnLabels.clear();
+ m_aColumnLabels.reserve( m_nColumnCount );
+ generate_n( back_inserter( m_aColumnLabels ), m_nColumnCount,
+ lcl_NumberedStringGenerator( aColName, C2U("%COLUMNNUMBER") ));
+}
+
+void InternalData::setData( const Sequence< Sequence< double > >& rDataInRows )
+{
+ m_nRowCount = rDataInRows.getLength();
+ m_nColumnCount = (m_nRowCount ? rDataInRows[0].getLength() : 0);
+
+ if( m_aRowLabels.size() != static_cast< sal_uInt32 >( m_nRowCount ))
+ m_aRowLabels.resize( m_nRowCount );
+ if( m_aColumnLabels.size() != static_cast< sal_uInt32 >( m_nColumnCount ))
+ m_aColumnLabels.resize( m_nColumnCount );
+
+ m_aData.resize( m_nRowCount * m_nColumnCount );
+ double fNan;
+ ::rtl::math::setNan( & fNan );
+ // set all values to Nan
+ m_aData = fNan;
+
+ for( sal_Int32 nRow=0; nRow<m_nRowCount; ++nRow )
+ {
+ int nDataIdx = nRow*m_nColumnCount;
+ const sal_Int32 nMax = ::std::min( rDataInRows[nRow].getLength(), m_nColumnCount );
+ for( sal_Int32 nCol=0; nCol < nMax; ++nCol )
+ {
+ m_aData[nDataIdx] = rDataInRows[nRow][nCol];
+ nDataIdx += 1;
+ }
+ }
+}
+
+Sequence< Sequence< double > > InternalData::getData() const
+{
+ Sequence< Sequence< double > > aResult( m_nRowCount );
+
+ for( sal_Int32 i=0; i<m_nRowCount; ++i )
+ aResult[i] = lcl_ValarrayToSequence< tDataType::value_type >(
+ m_aData[ ::std::slice( i*m_nColumnCount, m_nColumnCount, 1 ) ] );
+
+ return aResult;
+}
+
+Sequence< double > InternalData::getColumnValues( sal_Int32 nColumnIndex ) const
+{
+ if( nColumnIndex >= 0 && nColumnIndex < m_nColumnCount )
+ return lcl_ValarrayToSequence< tDataType::value_type >(
+ m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] );
+ return Sequence< double >();
+}
+Sequence< double > InternalData::getRowValues( sal_Int32 nRowIndex ) const
+{
+ if( nRowIndex >= 0 && nRowIndex < m_nRowCount )
+ return lcl_ValarrayToSequence< tDataType::value_type >(
+ m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ] );
+ return Sequence< double >();
+}
+
+void InternalData::setColumnValues( sal_Int32 nColumnIndex, const vector< double > & rNewData )
+{
+ if( nColumnIndex < 0 )
+ return;
+ enlargeData( nColumnIndex + 1, rNewData.size() );
+
+ tDataType aSlice = m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ];
+ for( vector< double >::size_type i = 0; i < rNewData.size(); ++i )
+ aSlice[i] = rNewData[i];
+ m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] = aSlice;
+}
+
+void InternalData::setRowValues( sal_Int32 nRowIndex, const vector< double > & rNewData )
+{
+ if( nRowIndex < 0 )
+ return;
+ enlargeData( rNewData.size(), nRowIndex+1 );
+
+ tDataType aSlice = m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ];
+ for( vector< double >::size_type i = 0; i < rNewData.size(); ++i )
+ aSlice[i] = rNewData[i];
+ m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]= aSlice;
+}
+
+void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< OUString >& rComplexLabel )
+{
+ if( nColumnIndex < 0 )
+ return;
+ if( nColumnIndex >= static_cast< sal_Int32 >( m_aColumnLabels.size() ) )
+ {
+ m_aColumnLabels.resize(nColumnIndex+1);
+ enlargeData( nColumnIndex+1, 0 );
+ }
+
+ m_aColumnLabels[nColumnIndex]=rComplexLabel;
+}
+void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< OUString >& rComplexLabel )
+{
+ if( nRowIndex < 0 )
+ return;
+ if( nRowIndex >= static_cast< sal_Int32 >( m_aRowLabels.size() ) )
+ {
+ m_aRowLabels.resize(nRowIndex+1);
+ enlargeData( 0, nRowIndex+1 );
+ }
+
+ m_aRowLabels[nRowIndex] = rComplexLabel;
+}
+
+vector< OUString > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const
+{
+ if( nColumnIndex < static_cast< sal_Int32 >( m_aColumnLabels.size() ) )
+ return m_aColumnLabels[nColumnIndex];
+ else
+ return vector< OUString >();
+}
+vector< OUString > InternalData::getComplexRowLabel( sal_Int32 nRowIndex ) const
+{
+ if( nRowIndex < static_cast< sal_Int32 >( m_aRowLabels.size() ) )
+ return m_aRowLabels[nRowIndex];
+ else
+ return vector< OUString >();
+}
+
+void InternalData::swapRowWithNext( sal_Int32 nRowIndex )
+{
+ if( nRowIndex < m_nRowCount - 1 )
+ {
+ const sal_Int32 nMax = m_nColumnCount;
+ for( sal_Int32 nColIdx=0; nColIdx<nMax; ++nColIdx )
+ {
+ size_t nIndex1 = nColIdx + nRowIndex*m_nColumnCount;
+ size_t nIndex2 = nIndex1 + m_nColumnCount;
+ double fTemp = m_aData[nIndex1];
+ m_aData[nIndex1] = m_aData[nIndex2];
+ m_aData[nIndex2] = fTemp;
+ }
+
+ vector< OUString > aTemp( m_aRowLabels[nRowIndex] );
+ m_aRowLabels[nRowIndex] = m_aRowLabels[nRowIndex + 1];
+ m_aRowLabels[nRowIndex + 1] = aTemp;
+ }
+}
+
+void InternalData::swapColumnWithNext( sal_Int32 nColumnIndex )
+{
+ if( nColumnIndex < m_nColumnCount - 1 )
+ {
+ const sal_Int32 nMax = m_nRowCount;
+ for( sal_Int32 nRowIdx=0; nRowIdx<nMax; ++nRowIdx )
+ {
+ size_t nIndex1 = nColumnIndex + nRowIdx*m_nColumnCount;
+ size_t nIndex2 = nIndex1 + 1;
+ double fTemp = m_aData[nIndex1];
+ m_aData[nIndex1] = m_aData[nIndex2];
+ m_aData[nIndex2] = fTemp;
+ }
+
+ vector< OUString > aTemp( m_aColumnLabels[nColumnIndex] );
+ m_aColumnLabels[nColumnIndex] = m_aColumnLabels[nColumnIndex + 1];
+ m_aColumnLabels[nColumnIndex + 1] = aTemp;
+ }
+}
+
+bool InternalData::enlargeData( sal_Int32 nColumnCount, sal_Int32 nRowCount )
+{
+ sal_Int32 nNewColumnCount( ::std::max<sal_Int32>( m_nColumnCount, nColumnCount ) );
+ sal_Int32 nNewRowCount( ::std::max<sal_Int32>( m_nRowCount, nRowCount ) );
+ sal_Int32 nNewSize( nNewColumnCount*nNewRowCount );
+
+ bool bGrow = (nNewSize > m_nColumnCount*m_nRowCount);
+
+ if( bGrow )
+ {
+ double fNan;
+ ::rtl::math::setNan( &fNan );
+ tDataType aNewData( fNan, nNewSize );
+ // copy old data
+ for( int nCol=0; nCol<m_nColumnCount; ++nCol )
+ static_cast< tDataType >(
+ aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] ) =
+ m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ];
+
+ m_aData.resize( nNewSize );
+ m_aData = aNewData;
+ }
+ m_nColumnCount = nNewColumnCount;
+ m_nRowCount = nNewRowCount;
+ return bGrow;
+}
+
+void InternalData::insertColumn( sal_Int32 nAfterIndex )
+{
+ // note: -1 is allowed, as we insert after the given index
+ OSL_ASSERT( nAfterIndex < m_nColumnCount && nAfterIndex >= -1 );
+ if( nAfterIndex >= m_nColumnCount || nAfterIndex < -1 )
+ return;
+ sal_Int32 nNewColumnCount = m_nColumnCount + 1;
+ sal_Int32 nNewSize( nNewColumnCount * m_nRowCount );
+
+ double fNan;
+ ::rtl::math::setNan( &fNan );
+ tDataType aNewData( fNan, nNewSize );
+
+ // copy old data
+ int nCol=0;
+ for( ; nCol<=nAfterIndex; ++nCol )
+ aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] );
+ for( ++nCol; nCol<nNewColumnCount; ++nCol )
+ aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( nCol - 1, m_nRowCount, m_nColumnCount ) ] );
+
+ m_nColumnCount = nNewColumnCount;
+ m_aData.resize( nNewSize );
+ m_aData = aNewData;
+
+ // labels
+ if( nAfterIndex < static_cast< sal_Int32 >( m_aColumnLabels.size()))
+ m_aColumnLabels.insert( m_aColumnLabels.begin() + (nAfterIndex + 1), vector< OUString >(1) );
+
+#if OSL_DEBUG_LEVEL > 2
+ traceData();
+#endif
+}
+
+sal_Int32 InternalData::appendColumn()
+{
+ insertColumn( getColumnCount() - 1 );
+ return getColumnCount() - 1;
+}
+
+sal_Int32 InternalData::appendRow()
+{
+ insertRow( getRowCount() - 1 );
+ return getRowCount() - 1;
+}
+
+void InternalData::insertRow( sal_Int32 nAfterIndex )
+{
+ // note: -1 is allowed, as we insert after the given index
+ OSL_ASSERT( nAfterIndex < m_nRowCount && nAfterIndex >= -1 );
+ if( nAfterIndex >= m_nRowCount || nAfterIndex < -1 )
+ return;
+ sal_Int32 nNewRowCount = m_nRowCount + 1;
+ sal_Int32 nNewSize( m_nColumnCount * nNewRowCount );
+
+ double fNan;
+ ::rtl::math::setNan( &fNan );
+ tDataType aNewData( fNan, nNewSize );
+
+ // copy old data
+ sal_Int32 nIndex = nAfterIndex + 1;
+ aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] );
+
+ if( nIndex < m_nRowCount )
+ {
+ sal_Int32 nRemainingCount = m_nColumnCount * (m_nRowCount - nIndex);
+ aNewData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] );
+ }
+
+ m_nRowCount = nNewRowCount;
+ m_aData.resize( nNewSize );
+ m_aData = aNewData;
+
+ // labels
+ if( nAfterIndex < static_cast< sal_Int32 >( m_aRowLabels.size()))
+ m_aRowLabels.insert( m_aRowLabels.begin() + nIndex, vector< OUString> (1));
+
+#if OSL_DEBUG_LEVEL > 2
+ traceData();
+#endif
+}
+
+void InternalData::deleteColumn( sal_Int32 nAtIndex )
+{
+ OSL_ASSERT( nAtIndex < m_nColumnCount && nAtIndex >= 0 );
+ if( nAtIndex >= m_nColumnCount || m_nColumnCount < 1 || nAtIndex < 0 )
+ return;
+ sal_Int32 nNewColumnCount = m_nColumnCount - 1;
+ sal_Int32 nNewSize( nNewColumnCount * m_nRowCount );
+
+ double fNan;
+ ::rtl::math::setNan( &fNan );
+ tDataType aNewData( fNan, nNewSize );
+
+ // copy old data
+ int nCol=0;
+ for( ; nCol<nAtIndex; ++nCol )
+ aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] );
+ for( ; nCol<nNewColumnCount; ++nCol )
+ aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( nCol + 1, m_nRowCount, m_nColumnCount ) ] );
+
+ m_nColumnCount = nNewColumnCount;
+ m_aData.resize( nNewSize );
+ m_aData = aNewData;
+
+ // labels
+ if( nAtIndex < static_cast< sal_Int32 >( m_aColumnLabels.size()))
+ m_aColumnLabels.erase( m_aColumnLabels.begin() + nAtIndex );
+
+#if OSL_DEBUG_LEVEL > 2
+ traceData();
+#endif
+}
+
+void InternalData::deleteRow( sal_Int32 nAtIndex )
+{
+ OSL_ASSERT( nAtIndex < m_nRowCount && nAtIndex >= 0 );
+ if( nAtIndex >= m_nRowCount || m_nRowCount < 1 || nAtIndex < 0 )
+ return;
+ sal_Int32 nNewRowCount = m_nRowCount - 1;
+ sal_Int32 nNewSize( m_nColumnCount * nNewRowCount );
+
+ double fNan;
+ ::rtl::math::setNan( &fNan );
+ tDataType aNewData( fNan, nNewSize );
+
+ // copy old data
+ sal_Int32 nIndex = nAtIndex;
+ if( nIndex )
+ aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] );
+
+ if( nIndex < nNewRowCount )
+ {
+ sal_Int32 nRemainingCount = m_nColumnCount * (nNewRowCount - nIndex);
+ aNewData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] =
+ static_cast< tDataType >(
+ m_aData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] );
+ }
+
+ m_nRowCount = nNewRowCount;
+ m_aData.resize( nNewSize );
+ m_aData = aNewData;
+
+ // labels
+ if( nAtIndex < static_cast< sal_Int32 >( m_aRowLabels.size()))
+ m_aRowLabels.erase( m_aRowLabels.begin() + nAtIndex );
+
+#if OSL_DEBUG_LEVEL > 2
+ traceData();
+#endif
+}
+
+sal_Int32 InternalData::getRowCount() const
+{
+ return m_nRowCount;
+}
+
+sal_Int32 InternalData::getColumnCount() const
+{
+ return m_nColumnCount;
+}
+
+void InternalData::setComplexRowLabels( const vector< vector< OUString > >& rNewRowLabels )
+{
+ m_aRowLabels = rNewRowLabels;
+ sal_Int32 nNewRowCount = static_cast< sal_Int32 >( m_aRowLabels.size() );
+ if( nNewRowCount < m_nRowCount )
+ m_aRowLabels.resize( m_nRowCount );
+ else
+ enlargeData( 0, nNewRowCount );
+}
+
+vector< vector< OUString > > InternalData::getComplexRowLabels() const
+{
+ return m_aRowLabels;
+}
+
+void InternalData::setComplexColumnLabels( const vector< vector< OUString > >& rNewColumnLabels )
+{
+ m_aColumnLabels = rNewColumnLabels;
+ sal_Int32 nNewColumnCount = static_cast< sal_Int32 >( m_aColumnLabels.size() );
+ if( nNewColumnCount < m_nColumnCount )
+ m_aColumnLabels.resize( m_nColumnCount );
+ else
+ enlargeData( nNewColumnCount, 0 );
+}
+
+vector< vector< OUString > > InternalData::getComplexColumnLabels() const
+{
+ return m_aColumnLabels;
+}
+
+#if OSL_DEBUG_LEVEL > 2
+void InternalData::traceData() const
+{
+ OSL_TRACE( "InternalData: Data in rows\n" );
+
+ for( sal_Int32 i=0; i<m_nRowCount; ++i )
+ {
+ tDataType aSlice( m_aData[ ::std::slice( i*m_nColumnCount, m_nColumnCount, 1 ) ] );
+ for( sal_Int32 j=0; j<m_nColumnCount; ++j )
+ OSL_TRACE( "%lf ", aSlice[j] );
+ OSL_TRACE( "\n" );
+ }
+ OSL_TRACE( "\n" );
+}
+#endif
+
+} // namespace chart
diff --git a/chart2/source/tools/InternalDataProvider.cxx b/chart2/source/tools/InternalDataProvider.cxx
new file mode 100644
index 000000000000..4abc51be31af
--- /dev/null
+++ b/chart2/source/tools/InternalDataProvider.cxx
@@ -0,0 +1,1314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include <rtl/math.hxx>
+
+#include <valarray>
+
+#include "InternalDataProvider.hxx"
+#include "LabeledDataSequence.hxx"
+#include "DataSource.hxx"
+#include "PropertyHelper.hxx"
+#include "macros.hxx"
+#include "XMLRangeHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "CommonConverters.hxx"
+#include "CommonFunctors.hxx"
+#include "UncachedDataSequence.hxx"
+#include "DataSourceHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "ExplicitCategoriesProvider.hxx"
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XDataSequence.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/charclass.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <vector>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::std;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+// ================================================================================
+
+namespace
+{
+
+// note: in xmloff this name is used to indicate usage of own data
+static const ::rtl::OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ));
+
+static const ::rtl::OUString lcl_aCategoriesRangeName(
+ RTL_CONSTASCII_USTRINGPARAM( "categories" ));
+static const ::rtl::OUString lcl_aCategoriesLevelRangeNamePrefix(
+ RTL_CONSTASCII_USTRINGPARAM( "categoriesL " )); //L <-> level
+static const ::rtl::OUString lcl_aCategoriesPointRangeNamePrefix(
+ RTL_CONSTASCII_USTRINGPARAM( "categoriesP " )); //P <-> point
+static const ::rtl::OUString lcl_aCategoriesRoleName(
+ RTL_CONSTASCII_USTRINGPARAM( "categories" ));
+static const ::rtl::OUString lcl_aLabelRangePrefix(
+ RTL_CONSTASCII_USTRINGPARAM( "label " ));
+static const ::rtl::OUString lcl_aCompleteRange(
+ RTL_CONSTASCII_USTRINGPARAM( "all" ));
+
+typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > >
+ lcl_tSequenceMap;
+
+struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void >
+{
+ void operator() ( const lcl_tSequenceMap::value_type & rMapEntry )
+ {
+ // convert weak reference to reference
+ Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second );
+ if( xSeq.is())
+ {
+ Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
+ if( xMod.is())
+ xMod->setModified( sal_True );
+ }
+ }
+};
+
+struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2::XDataSeries >, void >
+{
+ lcl_internalizeSeries( InternalData & rInternalData,
+ InternalDataProvider & rProvider,
+ bool bConnectToModel, bool bDataInColumns ) :
+ m_rInternalData( rInternalData ),
+ m_rProvider( rProvider ),
+ m_bConnectToModel( bConnectToModel ),
+ m_bDataInColumns( bDataInColumns )
+ {}
+ void operator() ( const Reference< chart2::XDataSeries > & xSeries )
+ {
+ Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
+ Reference< chart2::data::XDataSink > xSink( xSeries, uno::UNO_QUERY );
+ if( xSource.is() && xSink.is() )
+ {
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences();
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() );
+ for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i )
+ {
+ sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() );
+ OUString aIdentifier( OUString::valueOf( nNewIndex ));
+ //@todo: deal also with genericXDataSequence
+ Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY );
+ Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY );
+ Reference< chart2::data::XDataSequence > xNewValues;
+
+ if( xValues.is() )
+ {
+ ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData()));
+ if( m_bDataInColumns )
+ m_rInternalData.setColumnValues( nNewIndex, aValues );
+ else
+ m_rInternalData.setRowValues( nNewIndex, aValues );
+ if( m_bConnectToModel )
+ {
+ xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier ));
+ comphelper::copyProperties(
+ Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ),
+ Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY ));
+ }
+ }
+
+ if( xLabel.is() )
+ {
+ if( m_bDataInColumns )
+ m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( xLabel->getTextualData() ) );
+ else
+ m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( xLabel->getTextualData() ) );
+ if( m_bConnectToModel )
+ {
+ Reference< chart2::data::XDataSequence > xNewLabel(
+ m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier ));
+ comphelper::copyProperties(
+ Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ),
+ Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY ));
+ aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
+ new LabeledDataSequence( xNewValues, xNewLabel ));
+ }
+ }
+ else
+ {
+ if( m_bConnectToModel )
+ aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
+ new LabeledDataSequence( xNewValues ));
+ }
+ }
+ if( m_bConnectToModel )
+ xSink->setData( aNewSeriesData );
+ }
+ }
+
+private:
+ InternalData & m_rInternalData;
+ InternalDataProvider & m_rProvider;
+ bool m_bConnectToModel;
+ bool m_bDataInColumns;
+};
+
+struct lcl_makeAnyFromLevelVector : public ::std::unary_function< vector< OUString >, uno::Any >
+{
+public:
+
+ explicit lcl_makeAnyFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
+ {}
+
+ uno::Any operator() ( const vector< OUString >& rVector )
+ {
+ OUString aString;
+ if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
+ aString = rVector[m_nLevel];
+ return uno::makeAny( aString );
+ }
+
+private:
+ sal_Int32 m_nLevel;
+};
+
+struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< OUString >, OUString >
+{
+public:
+
+ explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
+ {}
+
+ OUString operator() ( const vector< OUString >& rVector )
+ {
+ OUString aString;
+ if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
+ aString = rVector[m_nLevel];
+ return aString;
+ }
+
+private:
+ sal_Int32 m_nLevel;
+};
+
+
+struct lcl_setStringAtLevel : public ::std::binary_function< vector< OUString >, OUString, vector< OUString > >
+{
+public:
+
+ explicit lcl_setStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
+ {}
+
+ vector< OUString > operator() ( const vector< OUString >& rVector, const OUString& rNewText )
+ {
+ vector< OUString > aRet( rVector );
+ if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
+ aRet.resize( m_nLevel+1 );
+ aRet[ m_nLevel ]=rNewText;
+ return aRet;
+ }
+
+private:
+ sal_Int32 m_nLevel;
+};
+
+struct lcl_insertStringAtLevel : public ::std::unary_function< vector< OUString >, void >
+{
+public:
+
+ explicit lcl_insertStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
+ {}
+
+ void operator() ( vector< OUString >& rVector )
+ {
+ if( m_nLevel > static_cast< sal_Int32 >(rVector.size()) )
+ rVector.resize( m_nLevel );
+
+ vector< OUString >::iterator aIt( rVector.begin() );
+ for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
+ {
+ if( nN==m_nLevel )
+ break;
+ }
+ rVector.insert( aIt, OUString() );
+ }
+
+private:
+ sal_Int32 m_nLevel;
+};
+
+struct lcl_removeStringAtLevel : public ::std::unary_function< vector< OUString >, void >
+{
+public:
+
+ explicit lcl_removeStringAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
+ {}
+
+ void operator() ( vector< OUString >& rVector )
+ {
+ vector< OUString >::iterator aIt( rVector.begin() );
+ for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
+ {
+ if( nN==m_nLevel )
+ {
+ rVector.erase( aIt );
+ break;
+ }
+ }
+ }
+
+private:
+ sal_Int32 m_nLevel;
+};
+
+vector< OUString > lcl_AnyToStringVector( const Sequence< uno::Any >& aAnySeq )
+{
+ vector< OUString > aStringVec;
+ transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(),
+ back_inserter( aStringVec ), CommonFunctors::AnyToString() );
+ return aStringVec;
+}
+
+Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq )
+{
+ Sequence< OUString > aResult;
+ aResult.realloc( aAnySeq.getLength() );
+ transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(),
+ aResult.getArray(), CommonFunctors::AnyToString() );
+ return aResult;
+}
+
+} // anonymous namespace
+
+// ================================================================================
+
+InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/)
+ : m_bDataInColumns( true )
+{}
+
+InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel )
+ : m_bDataInColumns( true )
+{
+ try
+ {
+ Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
+ if( xDiagram.is())
+ {
+ Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
+
+ //data in columns?
+ {
+ ::rtl::OUString aRangeString;
+ bool bFirstCellAsLabel = true;
+ bool bHasCategories = true;
+ uno::Sequence< sal_Int32 > aSequenceMapping;
+ DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories );
+ }
+
+ // categories
+ {
+ vector< vector< OUString > > aNewCategories;//inner count is level
+ {
+ ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
+ const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
+ sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
+ for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
+ {
+ Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
+ if( !xLDS.is() )
+ continue;
+ Reference< chart2::data::XTextualDataSequence > xSeq( xLDS->getValues(), uno::UNO_QUERY );
+ Sequence< OUString > aStringSeq;
+ if( xSeq.is() )
+ aStringSeq = xSeq->getTextualData(); // @todo: be able to deal with XDataSequence, too
+ sal_Int32 nLength = aStringSeq.getLength();
+ if( static_cast< sal_Int32 >(aNewCategories.size()) < nLength )
+ aNewCategories.resize( nLength );
+
+ transform( aNewCategories.begin(), aNewCategories.end(), aStringSeq.getConstArray(),
+ aNewCategories.begin(), lcl_setStringAtLevel(nL) );
+ }
+ if( !nLevelCount )
+ {
+ Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
+ sal_Int32 nLength = aSimplecategories.getLength();
+ aNewCategories.reserve( nLength );
+ for( sal_Int32 nN=0; nN<nLength; nN++)
+ {
+ vector< OUString > aStringVector(1);
+ aStringVector[0] = aSimplecategories[nN];
+ aNewCategories.push_back( aStringVector );
+ }
+ }
+ }
+
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexRowLabels( aNewCategories );
+ else
+ m_aInternalData.setComplexColumnLabels( aNewCategories );
+ if( bConnectToModel )
+ DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
+ createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
+ }
+
+ // data series
+ ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
+ ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// copy-CTOR
+InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
+ impl::InternalDataProvider_Base(),
+ m_aSequenceMap( rOther.m_aSequenceMap ),
+ m_aInternalData( rOther.m_aInternalData ),
+ m_bDataInColumns( rOther.m_bDataInColumns )
+{}
+
+InternalDataProvider::~InternalDataProvider()
+{}
+
+void InternalDataProvider::lcl_addDataSequenceToMap(
+ const OUString & rRangeRepresentation,
+ const Reference< chart2::data::XDataSequence > & xSequence )
+{
+ m_aSequenceMap.insert(
+ tSequenceMap::value_type(
+ rRangeRepresentation,
+ uno::WeakReference< chart2::data::XDataSequence >( xSequence )));
+}
+
+void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation )
+{
+ // set sequence to deleted by setting its range to an empty string
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
+ for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
+ {
+ Reference< chart2::data::XDataSequence > xSeq( aIt->second );
+ if( xSeq.is())
+ {
+ Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
+ if( xNamed.is())
+ xNamed->setName( OUString());
+ }
+ }
+ // remove from map
+ m_aSequenceMap.erase( aRange.first, aRange.second );
+}
+
+void InternalDataProvider::lcl_adaptMapReferences(
+ const OUString & rOldRangeRepresentation,
+ const OUString & rNewRangeRepresentation )
+{
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
+ tSequenceMap aNewElements;
+ for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
+ {
+ Reference< chart2::data::XDataSequence > xSeq( aIt->second );
+ if( xSeq.is())
+ {
+ Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
+ if( xNamed.is())
+ xNamed->setName( rNewRangeRepresentation );
+ }
+ aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second ));
+ }
+ // erase map values for old index
+ m_aSequenceMap.erase( aRange.first, aRange.second );
+ // add new entries for values with new index
+ ::std::copy( aNewElements.begin(), aNewElements.end(),
+ ::std::inserter( m_aSequenceMap,
+ m_aSequenceMap.upper_bound( rNewRangeRepresentation )));
+}
+
+void InternalDataProvider::lcl_increaseMapReferences(
+ sal_Int32 nBegin, sal_Int32 nEnd )
+{
+ for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
+ {
+ lcl_adaptMapReferences( OUString::valueOf( nIndex ),
+ OUString::valueOf( nIndex + 1 ));
+ lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
+ lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 ));
+ }
+}
+
+void InternalDataProvider::lcl_decreaseMapReferences(
+ sal_Int32 nBegin, sal_Int32 nEnd )
+{
+ for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
+ {
+ lcl_adaptMapReferences( OUString::valueOf( nIndex ),
+ OUString::valueOf( nIndex - 1 ));
+ lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
+ lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 ));
+ }
+}
+
+Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
+ const OUString & rRangeRepresentation )
+{
+ Reference< chart2::data::XDataSequence > xSeq(
+ new UncachedDataSequence( this, rRangeRepresentation ));
+ lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
+ return xSeq;
+}
+
+Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
+ const OUString & rRangeRepresentation,
+ const OUString & rRole )
+{
+ Reference< chart2::data::XDataSequence > xSeq(
+ new UncachedDataSequence( this, rRangeRepresentation, rRole ));
+ lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
+ return xSeq;
+}
+
+void InternalDataProvider::createDefaultData()
+{
+ m_aInternalData.createDefaultData();
+}
+
+// ____ XDataProvider ____
+::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
+ throw (uno::RuntimeException)
+{
+ return true;
+}
+
+namespace
+{
+
+sal_Int32 lcl_getInnerLevelCount( const vector< vector< OUString > >& rLabels )
+{
+ sal_Int32 nCount = 1;//minimum is 1!
+ vector< vector< OUString > >::const_iterator aLevelIt( rLabels.begin() );
+ vector< vector< OUString > >::const_iterator aLevelEnd( rLabels.end() );
+ for( ;aLevelIt!=aLevelEnd; ++aLevelIt )
+ {
+ const vector< ::rtl::OUString >& rCurrentLevelLabels = *aLevelIt;
+ nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount );
+ }
+ return nCount;
+}
+
+}//end anonymous namespace
+
+Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
+ const Sequence< beans::PropertyValue >& aArguments )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ OUString aRangeRepresentation;
+ bool bUseColumns = true;
+ bool bFirstCellAsLabel = true;
+ bool bHasCategories = true;
+ uno::Sequence< sal_Int32 > aSequenceMapping;
+ DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
+
+ if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) )
+ {
+ //return split complex categories if we have any:
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
+ vector< vector< OUString > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
+ if( bUseColumns==m_bDataInColumns )
+ {
+ sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
+ for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
+ aComplexCategories.push_back( new LabeledDataSequence(
+ new UncachedDataSequence( this
+ , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL )
+ , lcl_aCategoriesRoleName ) ) );
+ }
+ else
+ {
+ sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
+ for( sal_Int32 nP=0; nP<nPointCount; nP++ )
+ aComplexCategories.push_back( new LabeledDataSequence(
+ new UncachedDataSequence( this
+ , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP )
+ , lcl_aCategoriesRoleName ) ) );
+ }
+ //don't add the created sequences to the map as they are used temporarily only ...
+ return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) );
+ }
+
+ OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange ));
+
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
+
+ // categories
+ if( bHasCategories )
+ aResultLSeqVec.push_back(
+ new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
+
+ // data with labels
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
+ const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
+ for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
+ {
+ aDataVec.push_back(
+ new LabeledDataSequence(
+ lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )),
+ lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx ))));
+ }
+
+ // attention: this data provider has the limitation that it stores
+ // internally if data comes from columns or rows. It is intended for
+ // creating only one used data source.
+ // @todo: add this information in the range representation strings
+ m_bDataInColumns = bUseColumns;
+
+ //reorder labeled sequences according to aSequenceMapping; ignore categories
+ for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
+ {
+ std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
+ if( nOldIndex < aDataVec.size() )
+ {
+ if( aDataVec[nOldIndex].is() )
+ {
+ aResultLSeqVec.push_back( aDataVec[nOldIndex] );
+ aDataVec[nOldIndex] = 0;
+ }
+ }
+ }
+
+ //add left over data sequences to result
+ ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin());
+ const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end());
+ for( ;aIt!=aEndIt; ++aIt)
+ {
+ if( aIt->is() )
+ aResultLSeqVec.push_back( *aIt );
+ }
+
+ return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) );
+}
+
+Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
+ const Reference< chart2::data::XDataSource >& /* xDataSource */ )
+ throw (uno::RuntimeException)
+{
+ Sequence< beans::PropertyValue > aArguments( 4 );
+ aArguments[0] = beans::PropertyValue(
+ C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ),
+ beans::PropertyState_DIRECT_VALUE );
+ aArguments[1] = beans::PropertyValue(
+ C2U("DataRowSource"), -1, uno::makeAny(
+ m_bDataInColumns
+ ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
+ : ::com::sun::star::chart::ChartDataRowSource_ROWS ),
+ beans::PropertyState_DIRECT_VALUE );
+ // internal data always contains labels and categories
+ aArguments[2] = beans::PropertyValue(
+ C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
+ aArguments[3] = beans::PropertyValue(
+ C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
+
+ // #i85913# Sequence Mapping is not needed for internal data, as it is
+ // applied to the data when the data source is created.
+
+ return aArguments;
+}
+
+::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
+ throw (uno::RuntimeException)
+{
+ return true;
+}
+
+Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
+ const OUString& aRangeRepresentation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
+ {
+ OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
+
+ // categories
+ return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
+ }
+ else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
+ {
+ // label
+ sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
+ return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ));
+ }
+ else if( aRangeRepresentation.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" )))
+ {
+ sal_Int32 nIndex = (m_bDataInColumns
+ ? m_aInternalData.getColumnCount()
+ : m_aInternalData.getRowCount()) - 1;
+ return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
+ }
+ else if( aRangeRepresentation.getLength())
+ {
+ // data
+ sal_Int32 nIndex = aRangeRepresentation.toInt32();
+ return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
+ }
+
+ return Reference< chart2::data::XDataSequence >();
+}
+
+Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
+ throw (uno::RuntimeException)
+{
+ // there is no range selection component
+ return Reference< sheet::XRangeSelection >();
+}
+
+// ____ XInternalDataProvider ____
+::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bResult = false;
+
+ if( aRange.match( lcl_aCategoriesRangeName ))
+ {
+ OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
+ bResult = true;
+ }
+ else if( aRange.match( lcl_aLabelRangePrefix ))
+ {
+ sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
+ bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
+ }
+ else
+ {
+ sal_Int32 nIndex = aRange.toInt32();
+ bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
+ }
+
+ return bResult;
+}
+
+Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
+ throw (uno::RuntimeException)
+{
+ Sequence< uno::Any > aResult;
+
+ if( aRange.match( lcl_aLabelRangePrefix ) )
+ {
+ sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
+ vector< OUString > aComplexLabel = m_bDataInColumns
+ ? m_aInternalData.getComplexColumnLabel( nIndex )
+ : m_aInternalData.getComplexRowLabel( nIndex );
+ if( !aComplexLabel.empty() )
+ {
+ aResult.realloc( aComplexLabel.size() );
+ transform( aComplexLabel.begin(), aComplexLabel.end(),
+ aResult.getArray(), CommonFunctors::makeAny< OUString >());
+ }
+ }
+ else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
+ {
+ sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32();
+ vector< OUString > aComplexCategory = m_bDataInColumns
+ ? m_aInternalData.getComplexRowLabel( nPointIndex )
+ : m_aInternalData.getComplexColumnLabel( nPointIndex );
+ if( !aComplexCategory.empty() )
+ {
+ aResult.realloc( aComplexCategory.size() );
+ transform( aComplexCategory.begin(), aComplexCategory.end(),
+ aResult.getArray(), CommonFunctors::makeAny< OUString >());
+ }
+ }
+ else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
+ {
+ sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32();
+ vector< vector< OUString > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
+ if( nLevel < lcl_getInnerLevelCount( aCategories ) )
+ {
+ aResult.realloc( aCategories.size() );
+ transform( aCategories.begin(), aCategories.end(),
+ aResult.getArray(), lcl_makeAnyFromLevelVector(nLevel) );
+ }
+ }
+ else if( aRange.equals( lcl_aCategoriesRangeName ) )
+ {
+ Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions();
+ aResult.realloc( aLabels.getLength() );
+ transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(),
+ aResult.getArray(), CommonFunctors::makeAny< OUString >() );
+ }
+ else
+ {
+ sal_Int32 nIndex = aRange.toInt32();
+ if( nIndex >= 0 )
+ {
+ Sequence< double > aData;
+ if( m_bDataInColumns )
+ aData = m_aInternalData.getColumnValues(nIndex);
+ else
+ aData = m_aInternalData.getRowValues(nIndex);
+ if( aData.getLength() )
+ {
+ aResult.realloc( aData.getLength());
+ transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(),
+ aResult.getArray(), CommonFunctors::makeAny< double >());
+ }
+ }
+ }
+
+ return aResult;
+}
+
+void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
+ const OUString& aRange, const Sequence< uno::Any >& aNewData )
+ throw (uno::RuntimeException)
+{
+ if( aRange.match( lcl_aLabelRangePrefix ) )
+ {
+ vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) );
+ sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexColumnLabel( nIndex, aNewStrings );
+ else
+ m_aInternalData.setComplexRowLabel( nIndex, aNewStrings );
+ }
+ else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
+ {
+ vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) );
+ sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexRowLabel( nPointIndex, aNewStrings );
+ else
+ m_aInternalData.setComplexColumnLabel( nPointIndex, aNewStrings );
+ }
+ else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
+ {
+ vector< OUString > aNewStrings( lcl_AnyToStringVector( aNewData ) );
+ sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
+ vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
+
+ //ensure equal length
+ if( aNewStrings.size() > aComplexCategories.size() )
+ aComplexCategories.resize( aNewStrings.size() );
+ else if( aNewStrings.size() < aComplexCategories.size() )
+ aNewStrings.resize( aComplexCategories.size() );
+
+ transform( aComplexCategories.begin(), aComplexCategories.end(), aNewStrings.begin(),
+ aComplexCategories.begin(), lcl_setStringAtLevel(nLevel) );
+
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexRowLabels( aComplexCategories );
+ else
+ m_aInternalData.setComplexColumnLabels( aComplexCategories );
+ }
+ else if( aRange.equals( lcl_aCategoriesRangeName ) )
+ {
+ if( m_bDataInColumns )
+ this->setRowDescriptions( lcl_AnyToStringSequence(aNewData) );
+ else
+ this->setColumnDescriptions( lcl_AnyToStringSequence(aNewData) );
+ }
+ else
+ {
+ sal_Int32 nIndex = aRange.toInt32();
+ if( nIndex>=0 )
+ {
+ vector< double > aNewDataVec;
+ transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(),
+ back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
+ if( m_bDataInColumns )
+ m_aInternalData.setColumnValues( nIndex, aNewDataVec );
+ else
+ m_aInternalData.setRowValues( nIndex, aNewDataVec );
+ }
+ }
+}
+
+void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
+ throw (uno::RuntimeException)
+{
+ if( m_bDataInColumns )
+ {
+ lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
+ m_aInternalData.insertColumn( nAfterIndex );
+ }
+ else
+ {
+ lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
+ m_aInternalData.insertRow( nAfterIndex );
+ }
+}
+
+void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
+ throw (uno::RuntimeException)
+{
+ lcl_deleteMapReferences( OUString::valueOf( nAtIndex ));
+ lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex ));
+ if( m_bDataInColumns )
+ {
+ lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
+ m_aInternalData.deleteColumn( nAtIndex );
+ }
+ else
+ {
+ lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
+ m_aInternalData.deleteRow( nAtIndex );
+ }
+}
+
+void SAL_CALL InternalDataProvider::appendSequence()
+ throw (uno::RuntimeException)
+{
+ if( m_bDataInColumns )
+ m_aInternalData.appendColumn();
+ else
+ m_aInternalData.appendRow();
+}
+
+void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
+ if( nLevel>0 )
+ {
+ vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
+ ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertStringAtLevel(nLevel) );
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexRowLabels( aComplexCategories );
+ else
+ m_aInternalData.setComplexColumnLabels( aComplexCategories );
+
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
+ ::std::for_each( aRange.first, aRange.second, lcl_setModified());
+ }
+}
+void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
+ if( nLevel>0 )
+ {
+ vector< vector< OUString > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
+ ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeStringAtLevel(nLevel) );
+ if( m_bDataInColumns )
+ m_aInternalData.setComplexRowLabels( aComplexCategories );
+ else
+ m_aInternalData.setComplexColumnLabels( aComplexCategories );
+
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
+ ::std::for_each( aRange.first, aRange.second, lcl_setModified());
+ }
+}
+
+void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
+ throw (uno::RuntimeException)
+{
+ sal_Int32 nMaxRep = 0;
+ if( m_bDataInColumns )
+ {
+ m_aInternalData.insertRow( nAfterIndex );
+ nMaxRep = m_aInternalData.getColumnCount();
+ }
+ else
+ {
+ m_aInternalData.insertColumn( nAfterIndex );
+ nMaxRep = m_aInternalData.getRowCount();
+ }
+
+ // notify change to all affected ranges
+ tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
+ tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
+ ::std::for_each( aBegin, aEnd, lcl_setModified());
+
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
+ ::std::for_each( aRange.first, aRange.second, lcl_setModified());
+}
+
+void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
+ throw (uno::RuntimeException)
+{
+ sal_Int32 nMaxRep = 0;
+ if( m_bDataInColumns )
+ {
+ m_aInternalData.deleteRow( nAtIndex );
+ nMaxRep = m_aInternalData.getColumnCount();
+ }
+ else
+ {
+ m_aInternalData.deleteColumn( nAtIndex );
+ nMaxRep = m_aInternalData.getRowCount();
+ }
+
+ // notify change to all affected ranges
+ tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
+ tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
+ ::std::for_each( aBegin, aEnd, lcl_setModified());
+
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
+ ::std::for_each( aRange.first, aRange.second, lcl_setModified());
+}
+
+void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
+ throw (uno::RuntimeException)
+{
+ if( m_bDataInColumns )
+ m_aInternalData.swapRowWithNext( nAtIndex );
+ else
+ m_aInternalData.swapColumnWithNext( nAtIndex );
+ sal_Int32 nMaxRep = (m_bDataInColumns
+ ? m_aInternalData.getColumnCount()
+ : m_aInternalData.getRowCount());
+
+ // notify change to all affected ranges
+ tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
+ tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
+ ::std::for_each( aBegin, aEnd, lcl_setModified());
+
+ tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
+ ::std::for_each( aRange.first, aRange.second, lcl_setModified());
+}
+
+void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
+ throw (uno::RuntimeException)
+{
+ if( xSeq.is())
+ lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
+}
+
+
+// ____ XRangeXMLConversion ____
+OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ XMLRangeHelper::CellRange aRange;
+ aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table"));
+
+ // attention: this data provider has the limitation that it stores
+ // internally if data comes from columns or rows. It is intended for
+ // creating only one used data source.
+ // @todo: add this information in the range representation strings
+ if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
+ {
+ OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
+ aRange.aUpperLeft.bIsEmpty = false;
+ if( m_bDataInColumns )
+ {
+ aRange.aUpperLeft.nColumn = 0;
+ aRange.aUpperLeft.nRow = 1;
+ aRange.aLowerRight = aRange.aUpperLeft;
+ aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
+ }
+ else
+ {
+ aRange.aUpperLeft.nColumn = 1;
+ aRange.aUpperLeft.nRow = 0;
+ aRange.aLowerRight = aRange.aUpperLeft;
+ aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
+ }
+ }
+ else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
+ {
+ sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
+ aRange.aUpperLeft.bIsEmpty = false;
+ aRange.aLowerRight.bIsEmpty = true;
+ if( m_bDataInColumns )
+ {
+ aRange.aUpperLeft.nColumn = nIndex + 1;
+ aRange.aUpperLeft.nRow = 0;
+ }
+ else
+ {
+ aRange.aUpperLeft.nColumn = 0;
+ aRange.aUpperLeft.nRow = nIndex + 1;
+ }
+ }
+ else if( aRangeRepresentation.equals( lcl_aCompleteRange ))
+ {
+ aRange.aUpperLeft.bIsEmpty = false;
+ aRange.aLowerRight.bIsEmpty = false;
+ aRange.aUpperLeft.nColumn = 0;
+ aRange.aUpperLeft.nRow = 0;
+ aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
+ aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
+ }
+ else
+ {
+ sal_Int32 nIndex = aRangeRepresentation.toInt32();
+ aRange.aUpperLeft.bIsEmpty = false;
+ if( m_bDataInColumns )
+ {
+ aRange.aUpperLeft.nColumn = nIndex + 1;
+ aRange.aUpperLeft.nRow = 1;
+ aRange.aLowerRight = aRange.aUpperLeft;
+ aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
+ }
+ else
+ {
+ aRange.aUpperLeft.nColumn = 1;
+ aRange.aUpperLeft.nRow = nIndex + 1;
+ aRange.aLowerRight = aRange.aUpperLeft;
+ aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
+ }
+ }
+
+ return XMLRangeHelper::getXMLStringFromCellRange( aRange );
+}
+
+OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
+ if( aRange.aUpperLeft.bIsEmpty )
+ {
+ OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
+ return OUString();
+ }
+
+ // "all"
+ if( !aRange.aLowerRight.bIsEmpty &&
+ ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
+ ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
+ return lcl_aCompleteRange;
+
+ // attention: this data provider has the limitation that it stores
+ // internally if data comes from columns or rows. It is intended for
+ // creating only one used data source.
+ // @todo: add this information in the range representation strings
+
+ // data in columns
+ if( m_bDataInColumns )
+ {
+ if( aRange.aUpperLeft.nColumn == 0 )
+ return lcl_aCategoriesRangeName;
+ if( aRange.aUpperLeft.nRow == 0 )
+ return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
+
+ return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
+ }
+
+ // data in rows
+ if( aRange.aUpperLeft.nRow == 0 )
+ return lcl_aCategoriesRangeName;
+ if( aRange.aUpperLeft.nColumn == 0 )
+ return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
+
+ return OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
+}
+
+namespace
+{
+Sequence< Sequence< OUString > > lcl_convertComplexVectorToSequence( const vector< vector< OUString > >& rIn )
+{
+ Sequence< Sequence< OUString > > aRet;
+ sal_Int32 nOuterCount = rIn.size();
+ if( nOuterCount )
+ {
+ aRet.realloc(nOuterCount);
+ for( sal_Int32 nN=0; nN<nOuterCount; nN++)
+ aRet[nN]=ContainerHelper::ContainerToSequence( rIn[nN] );
+ }
+ return aRet;
+}
+
+vector< vector< OUString > > lcl_convertComplexSequenceToVector( const Sequence< Sequence< OUString > >& rIn )
+{
+ vector< vector< OUString > > aRet;
+ sal_Int32 nOuterCount = rIn.getLength();
+ for( sal_Int32 nN=0; nN<nOuterCount; nN++)
+ aRet.push_back( ContainerHelper::SequenceToVector( rIn[nN] ) );
+ return aRet;
+}
+
+class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
+{
+public:
+
+ explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< ::rtl::OUString > >& rComplexDescriptions )
+ : m_rComplexDescriptions( rComplexDescriptions )
+ {}
+ virtual ~SplitCategoriesProvider_ForComplexDescriptions()
+ {}
+
+ virtual sal_Int32 getLevelCount() const;
+ virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
+
+private:
+ const ::std::vector< ::std::vector< ::rtl::OUString > >& m_rComplexDescriptions;
+};
+
+sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
+{
+ return lcl_getInnerLevelCount( m_rComplexDescriptions );
+}
+uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
+{
+ uno::Sequence< rtl::OUString > aResult;
+ if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
+ {
+ aResult.realloc( m_rComplexDescriptions.size() );
+ transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
+ aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
+ }
+ return aResult;
+}
+
+}//anonymous namespace
+
+// ____ XComplexDescriptionAccess ____
+Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException)
+{
+ return lcl_convertComplexVectorToSequence( m_aInternalData.getComplexRowLabels() );
+}
+void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException)
+{
+ m_aInternalData.setComplexRowLabels( lcl_convertComplexSequenceToVector(aRowDescriptions) );
+}
+Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException)
+{
+ return lcl_convertComplexVectorToSequence( m_aInternalData.getComplexColumnLabels() );
+}
+void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException)
+{
+ m_aInternalData.setComplexColumnLabels( lcl_convertComplexSequenceToVector(aColumnDescriptions) );
+}
+
+// ____ XChartDataArray ____
+Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
+ throw (uno::RuntimeException)
+{
+ return m_aInternalData.getData();
+}
+
+void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
+ throw (uno::RuntimeException)
+{
+ return m_aInternalData.setData( rDataInRows );
+}
+
+void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
+ throw (uno::RuntimeException)
+{
+ vector< vector< OUString > > aComplexDescriptions( aRowDescriptions.getLength() );
+ transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
+ aComplexDescriptions.begin(), lcl_setStringAtLevel(0) );
+ m_aInternalData.setComplexRowLabels( aComplexDescriptions );
+}
+
+void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
+ throw (uno::RuntimeException)
+{
+ vector< vector< OUString > > aComplexDescriptions( aColumnDescriptions.getLength() );
+ transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
+ aComplexDescriptions.begin(), lcl_setStringAtLevel(0) );
+ m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
+}
+
+Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
+ throw (uno::RuntimeException)
+{
+ vector< vector< OUString > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
+ SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
+ return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
+}
+
+Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
+ throw (uno::RuntimeException)
+{
+ vector< vector< OUString > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
+ SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
+ return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
+}
+
+// ____ XChartData (base of XChartDataArray) ____
+void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
+ const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
+ throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
+ const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
+ throw (uno::RuntimeException)
+{
+}
+
+double SAL_CALL InternalDataProvider::getNotANumber()
+ throw (uno::RuntimeException)
+{
+ double fNan;
+ ::rtl::math::setNan( & fNan );
+ return fNan;
+}
+
+::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
+ throw (uno::RuntimeException)
+{
+ return ::rtl::math::isNan( nNumber )
+ || ::rtl::math::isInf( nNumber );
+}
+// lang::XInitialization:
+void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
+{
+ comphelper::SequenceAsHashMap aArgs(_aArguments);
+ if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) )
+ createDefaultData();
+}
+// ____ XCloneable ____
+Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
+ throw (uno::RuntimeException)
+{
+ return Reference< util::XCloneable >( new InternalDataProvider( *this ));
+}
+
+
+// ================================================================================
+
+Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 1 );
+ aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" ));
+ return aServices;
+}
+
+// ================================================================================
+
+APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
+
+} // namespace chart
diff --git a/chart2/source/tools/LabeledDataSequence.cxx b/chart2/source/tools/LabeledDataSequence.cxx
new file mode 100644
index 000000000000..21ade3aefadc
--- /dev/null
+++ b/chart2/source/tools/LabeledDataSequence.cxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "LabeledDataSequence.hxx"
+#include "ModifyListenerHelper.hxx"
+#include "macros.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+LabeledDataSequence::LabeledDataSequence( const Reference< uno::XComponentContext > & xContext ) :
+ m_xContext( xContext ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{}
+
+LabeledDataSequence::LabeledDataSequence(
+ const uno::Reference< chart2::data::XDataSequence > & rValues ) :
+ m_xData( rValues ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ ModifyListenerHelper::addListener( m_xData, m_xModifyEventForwarder );
+}
+
+LabeledDataSequence::LabeledDataSequence(
+ const uno::Reference< chart2::data::XDataSequence > & rValues,
+ const uno::Reference< chart2::data::XDataSequence > & rLabel ) :
+ m_xData( rValues ),
+ m_xLabel( rLabel ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ ModifyListenerHelper::addListener( m_xData, m_xModifyEventForwarder );
+ ModifyListenerHelper::addListener( m_xLabel, m_xModifyEventForwarder );
+}
+
+LabeledDataSequence::~LabeledDataSequence()
+{
+ if( m_xModifyEventForwarder.is())
+ {
+ if( m_xData.is())
+ ModifyListenerHelper::removeListener( m_xData, m_xModifyEventForwarder );
+ if( m_xLabel.is())
+ ModifyListenerHelper::removeListener( m_xLabel, m_xModifyEventForwarder );
+ }
+}
+
+// ____ XLabeledDataSequence ____
+uno::Reference< chart2::data::XDataSequence > SAL_CALL LabeledDataSequence::getValues()
+ throw (uno::RuntimeException)
+{
+ return m_xData;
+}
+
+void SAL_CALL LabeledDataSequence::setValues(
+ const uno::Reference< chart2::data::XDataSequence >& xSequence )
+ throw (uno::RuntimeException)
+{
+ if( m_xData != xSequence )
+ {
+ ModifyListenerHelper::removeListener( m_xData, m_xModifyEventForwarder );
+ m_xData = xSequence;
+ ModifyListenerHelper::addListener( m_xData, m_xModifyEventForwarder );
+ }
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL LabeledDataSequence::getLabel()
+ throw (uno::RuntimeException)
+{
+ return m_xLabel;
+}
+
+void SAL_CALL LabeledDataSequence::setLabel(
+ const uno::Reference< chart2::data::XDataSequence >& xSequence )
+ throw (uno::RuntimeException)
+{
+ if( m_xLabel != xSequence )
+ {
+ ModifyListenerHelper::removeListener( m_xLabel, m_xModifyEventForwarder );
+ m_xLabel = xSequence;
+ ModifyListenerHelper::addListener( m_xLabel, m_xModifyEventForwarder );
+ }
+}
+
+// ____ XCloneable ____
+uno::Reference< util::XCloneable > SAL_CALL LabeledDataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ uno::Reference< chart2::data::XDataSequence > xNewValues( m_xData );
+ uno::Reference< chart2::data::XDataSequence > xNewLabel( m_xLabel );
+
+ uno::Reference< util::XCloneable > xLabelCloneable( m_xLabel, uno::UNO_QUERY );
+ if( xLabelCloneable.is())
+ xNewLabel.set( xLabelCloneable->createClone(), uno::UNO_QUERY );
+
+ uno::Reference< util::XCloneable > xValuesCloneable( m_xData, uno::UNO_QUERY );
+ if( xValuesCloneable.is())
+ xNewValues.set( xValuesCloneable->createClone(), uno::UNO_QUERY );
+
+ return uno::Reference< util::XCloneable >(
+ new LabeledDataSequence( xNewValues, xNewLabel ) );
+}
+
+// ____ XModifyBroadcaster ____
+void SAL_CALL LabeledDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL LabeledDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// ================================================================================
+
+Sequence< OUString > LabeledDataSequence::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 1 );
+ aServices[ 0 ] = C2U( "com.sun.star.chart2.data.LabeledDataSequence" );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( LabeledDataSequence,
+ C2U( "com.sun.star.comp.chart2.LabeledDataSequence" ))
+
+// ================================================================================
+
+} // namespace chart
diff --git a/chart2/source/tools/LegendHelper.cxx b/chart2/source/tools/LegendHelper.cxx
new file mode 100644
index 000000000000..4e778db1a68c
--- /dev/null
+++ b/chart2/source/tools/LegendHelper.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "LegendHelper.hxx"
+#include "macros.hxx"
+#include <com/sun/star/chart2/LegendExpansion.hpp>
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XLegend.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+
+//static
+Reference< chart2::XLegend > LegendHelper::showLegend( const Reference< frame::XModel >& xModel
+ , const uno::Reference< uno::XComponentContext >& xContext )
+{
+ uno::Reference< chart2::XLegend > xLegend = LegendHelper::getLegend( xModel, xContext, true );
+ uno::Reference< beans::XPropertySet > xProp( xLegend, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ xProp->setPropertyValue( C2U("Show"), uno::makeAny(sal_True) );
+
+ chart2::RelativePosition aRelativePosition;
+ if( !(xProp->getPropertyValue( C2U( "RelativePosition" )) >>= aRelativePosition) )
+ {
+ chart2::LegendPosition ePos = chart2::LegendPosition_LINE_END;
+ if( !(xProp->getPropertyValue( C2U( "AnchorPosition" )) >>= ePos ) )
+ xProp->setPropertyValue( C2U( "AnchorPosition" ), uno::makeAny( ePos ));
+
+ chart2::LegendExpansion eExpansion =
+ ( ePos == chart2::LegendPosition_LINE_END ||
+ ePos == chart2::LegendPosition_LINE_START )
+ ? chart2::LegendExpansion_HIGH
+ : chart2::LegendExpansion_WIDE;
+ if( !(xProp->getPropertyValue( C2U( "Expansion" )) >>= eExpansion ) )
+ xProp->setPropertyValue( C2U( "Expansion" ), uno::makeAny( eExpansion ));
+
+ xProp->setPropertyValue( C2U( "RelativePosition" ), uno::Any());
+ }
+
+ }
+ return xLegend;
+}
+
+//static
+void LegendHelper::hideLegend( const Reference< frame::XModel >& xModel )
+{
+ uno::Reference< chart2::XLegend > xLegend = LegendHelper::getLegend( xModel, 0, false );
+ uno::Reference< beans::XPropertySet > xProp( xLegend, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ xProp->setPropertyValue( C2U("Show"), uno::makeAny(sal_False) );
+ }
+}
+
+// static
+uno::Reference< chart2::XLegend > LegendHelper::getLegend(
+ const uno::Reference< frame::XModel >& xModel
+ , const uno::Reference< uno::XComponentContext >& xContext
+ , bool bCreate )
+{
+ uno::Reference< chart2::XLegend > xResult;
+
+ uno::Reference< chart2::XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
+ if( xChartDoc.is())
+ {
+ try
+ {
+ uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram());
+ if( xDia.is() )
+ {
+ xResult.set( xDia->getLegend() );
+ if( bCreate && !xResult.is() && xContext.is() )
+ {
+ xResult.set( xContext->getServiceManager()->createInstanceWithContext(
+ C2U( "com.sun.star.chart2.Legend" ), xContext ), uno::UNO_QUERY );
+ xDia->setLegend( xResult );
+ }
+ }
+ else if(bCreate)
+ {
+ DBG_ERROR("need diagram for creation of legend");
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return xResult;
+}
+
+// static
+bool LegendHelper::hasLegend( const uno::Reference< chart2::XDiagram > & xDiagram )
+{
+ bool bReturn = false;
+ if( xDiagram.is())
+ {
+ uno::Reference< beans::XPropertySet > xLegendProp( xDiagram->getLegend(), uno::UNO_QUERY );
+ if( xLegendProp.is())
+ xLegendProp->getPropertyValue( C2U("Show")) >>= bReturn;
+ }
+
+ return bReturn;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
+
diff --git a/chart2/source/tools/LifeTime.cxx b/chart2/source/tools/LifeTime.cxx
new file mode 100644
index 000000000000..444e894a101d
--- /dev/null
+++ b/chart2/source/tools/LifeTime.cxx
@@ -0,0 +1,546 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "LifeTime.hxx"
+#include "macros.hxx"
+#include <osl/diagnose.h>
+
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <com/sun/star/util/XCloseListener.hpp>
+
+using namespace ::com::sun::star;
+
+namespace apphelper
+{
+//--------------------------
+
+LifeTimeManager::LifeTimeManager( lang::XComponent* pComponent, sal_Bool bLongLastingCallsCancelable )
+ : m_aListenerContainer( m_aAccessMutex )
+ , m_pComponent(pComponent)
+ , m_bLongLastingCallsCancelable(bLongLastingCallsCancelable)
+{
+ impl_init();
+}
+
+void LifeTimeManager::impl_init()
+{
+ m_bDisposed = sal_False;
+ m_bInDispose = sal_False;
+ m_nAccessCount = 0;
+ m_nLongLastingCallCount = 0;
+ m_aNoAccessCountCondition.set();
+ m_aNoLongLastingCallCountCondition.set();
+}
+
+LifeTimeManager::~LifeTimeManager()
+{
+}
+
+bool LifeTimeManager::impl_isDisposed( bool bAssert )
+{
+ if( m_bDisposed || m_bInDispose )
+ {
+ if( bAssert )
+ {
+ OSL_ENSURE( sal_False, "This component is already disposed " );
+ (void)(bAssert);
+ }
+ return sal_True;
+ }
+ return sal_False;
+}
+ sal_Bool LifeTimeManager
+::impl_canStartApiCall()
+{
+ if( impl_isDisposed() )
+ return sal_False; //behave passive if already disposed
+
+ //mutex is acquired
+ return sal_True;
+}
+
+ void LifeTimeManager
+::impl_registerApiCall(sal_Bool bLongLastingCall)
+{
+ //only allowed if not disposed
+ //do not acquire the mutex here because it will be acquired already
+ m_nAccessCount++;
+ if(m_nAccessCount==1)
+ //@todo? is it ok to wake some threads here while we have acquired the mutex?
+ m_aNoAccessCountCondition.reset();
+
+ if(bLongLastingCall)
+ m_nLongLastingCallCount++;
+ if(m_nLongLastingCallCount==1)
+ m_aNoLongLastingCallCountCondition.reset();
+}
+ void LifeTimeManager
+::impl_unregisterApiCall(sal_Bool bLongLastingCall)
+{
+ //Mutex needs to be acquired exactly ones
+ //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
+
+ OSL_ENSURE( m_nAccessCount>0, "access count mismatch" );
+ m_nAccessCount--;
+ if(bLongLastingCall)
+ m_nLongLastingCallCount--;
+ if( m_nLongLastingCallCount==0 )
+ {
+ m_aNoLongLastingCallCountCondition.set();
+ }
+ if( m_nAccessCount== 0)
+ {
+ m_aNoAccessCountCondition.set();
+ impl_apiCallCountReachedNull();
+
+ }
+}
+
+ sal_Bool LifeTimeManager
+::dispose() throw(uno::RuntimeException)
+{
+ //hold no mutex
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aAccessMutex );
+
+ if( m_bDisposed || m_bInDispose )
+ {
+ OSL_TRACE( "This component is already disposed " );
+ return sal_False; //behave passive if already disposed
+ }
+
+ m_bInDispose = true;
+ //adding any listener is not allowed anymore
+ //new calls will not be accepted
+ //still running calls have the freedom to finish their work without crash
+ }
+ //no mutex is acquired
+
+ //--do the disposing of listeners after calling this method
+ {
+ uno::Reference< lang::XComponent > xComponent =
+ uno::Reference< lang::XComponent >(m_pComponent);;
+ if(xComponent.is())
+ {
+ // notify XCLoseListeners
+ lang::EventObject aEvent( xComponent );
+ m_aListenerContainer.disposeAndClear( aEvent );
+ }
+ }
+
+ //no mutex is acquired
+ {
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aAccessMutex );
+ OSL_ENSURE( !m_bDisposed, "dispose was called already" );
+ m_bDisposed = sal_True;
+ aGuard.clear();
+ }
+ //no mutex is acquired
+
+ //wait until all still running calls have finished
+ //the accessCount cannot grow anymore, because all calls will return after checking m_bDisposed
+ m_aNoAccessCountCondition.wait();
+
+ //we are the only ones working on our data now
+
+ return sal_True;
+ //--release all resources and references after calling this method successful
+}
+
+//-----------------------------------------------------------------
+
+CloseableLifeTimeManager::CloseableLifeTimeManager( ::com::sun::star::util::XCloseable* pCloseable
+ , ::com::sun::star::lang::XComponent* pComponent
+ , sal_Bool bLongLastingCallsCancelable )
+ : LifeTimeManager( pComponent, bLongLastingCallsCancelable )
+ , m_pCloseable(pCloseable)
+{
+ impl_init();
+}
+
+CloseableLifeTimeManager::~CloseableLifeTimeManager()
+{
+}
+
+bool CloseableLifeTimeManager::impl_isDisposedOrClosed( bool bAssert )
+{
+ if( impl_isDisposed( bAssert ) )
+ return sal_True;
+
+ if( m_bClosed )
+ {
+ if( bAssert )
+ {
+ OSL_ENSURE( sal_False, "This object is already closed" );
+ (void)(bAssert);//avoid warnings
+ }
+ return sal_True;
+ }
+ return sal_False;
+}
+
+ sal_Bool CloseableLifeTimeManager
+::g_close_startTryClose(sal_Bool bDeliverOwnership)
+ throw ( uno::Exception )
+{
+ //no mutex is allowed to be acquired
+ {
+ osl::ResettableGuard< osl::Mutex > aGuard( m_aAccessMutex );
+ if( impl_isDisposedOrClosed(false) )
+ return sal_False;
+
+ //Mutex needs to be acquired exactly ones; will be released inbetween
+ if( !impl_canStartApiCall() )
+ return sal_False;
+ //mutex is acquired
+
+ //not closed already -> we try to close again
+ m_bInTryClose = sal_True;
+ m_aEndTryClosingCondition.reset();
+
+ impl_registerApiCall(sal_False);
+ }
+
+ //------------------------------------------------
+ //no mutex is acquired
+
+ //only remove listener calls will be worked on until end of tryclose
+ //all other new calls will wait till end of try close // @todo? is that really ok
+
+ //?? still running calls have the freedom to finish their work without crash
+
+ try
+ {
+ uno::Reference< util::XCloseable > xCloseable =
+ uno::Reference< util::XCloseable >(m_pCloseable);;
+ if(xCloseable.is())
+ {
+ //--call queryClosing on all registered close listeners
+ ::cppu::OInterfaceContainerHelper* pIC = m_aListenerContainer.getContainer(
+ ::getCppuType((const uno::Reference< util::XCloseListener >*)0) );;
+ if( pIC )
+ {
+ //lang::EventObject aEvent( static_cast< util::XCloseable*>(xCloseable) );
+ lang::EventObject aEvent( xCloseable );
+ ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ while( aIt.hasMoreElements() )
+ {
+ uno::Reference< util::XCloseListener > xCloseListener( aIt.next(), uno::UNO_QUERY );
+ if(xCloseListener.is())
+ xCloseListener->queryClosing( aEvent, bDeliverOwnership );
+ }
+ }
+ }
+ }
+ catch( uno::Exception& ex )
+ {
+ //no mutex is acquired
+ g_close_endTryClose(bDeliverOwnership, sal_False);
+ (void)(ex);
+ throw;
+ }
+ return sal_True;
+}
+
+ void CloseableLifeTimeManager
+::g_close_endTryClose(sal_Bool bDeliverOwnership, sal_Bool /* bMyVeto */ )
+{
+ //this method is called, if the try to close was not successfull
+ osl::Guard< osl::Mutex > aGuard( m_aAccessMutex );
+ impl_setOwnership( bDeliverOwnership, sal_False );
+
+ m_bInTryClose = sal_False;
+ m_aEndTryClosingCondition.set();
+
+ //Mutex needs to be acquired exactly ones
+ //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
+ impl_unregisterApiCall(sal_False);
+}
+
+ sal_Bool CloseableLifeTimeManager
+::g_close_isNeedToCancelLongLastingCalls( sal_Bool bDeliverOwnership, util::CloseVetoException& ex )
+ throw ( util::CloseVetoException )
+{
+ //this method is called when no closelistener has had a veto during queryclosing
+ //the method returns false, if nothing stands against closing anymore
+ //it returns true, if some longlasting calls are running, which might be cancelled
+ //it throws the given exception, if long calls are running but not cancelable
+
+ osl::Guard< osl::Mutex > aGuard( m_aAccessMutex );
+ //this count cannot grow after try of close has started, because we wait in all those methods for end of try closing
+ if( !m_nLongLastingCallCount )
+ return sal_False;
+
+ if(m_bLongLastingCallsCancelable)
+ return sal_True;
+
+ impl_setOwnership( bDeliverOwnership, sal_True );
+
+ m_bInTryClose = sal_False;
+ m_aEndTryClosingCondition.set();
+
+ //Mutex needs to be acquired exactly ones
+ //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
+ impl_unregisterApiCall(sal_False);
+
+ throw ex;
+}
+
+ void CloseableLifeTimeManager
+::g_close_endTryClose_doClose()
+{
+ //this method is called, if the try to close was successfull
+ osl::ResettableGuard< osl::Mutex > aGuard( m_aAccessMutex );
+
+ m_bInTryClose = sal_False;
+ m_aEndTryClosingCondition.set();
+
+ //Mutex needs to be acquired exactly ones
+ //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
+ impl_unregisterApiCall(sal_False);
+ impl_doClose();
+}
+
+ void CloseableLifeTimeManager
+::impl_setOwnership( sal_Bool bDeliverOwnership, sal_Bool bMyVeto )
+{
+ m_bOwnership = bDeliverOwnership && bMyVeto;
+ m_bOwnershipIsWellKnown = sal_True;
+}
+ sal_Bool CloseableLifeTimeManager
+::impl_shouldCloseAtNextChance()
+{
+ return m_bOwnership;
+}
+
+ void CloseableLifeTimeManager
+::impl_apiCallCountReachedNull()
+{
+ //Mutex needs to be acquired exactly ones
+ //mutex will be released inbetween in impl_doClose()
+ if( m_pCloseable && impl_shouldCloseAtNextChance() )
+ impl_doClose();
+}
+
+ void CloseableLifeTimeManager
+::impl_doClose()
+{
+ //Mutex needs to be acquired exactly ones before calling impl_doClose()
+
+ if(m_bClosed)
+ return; //behave as passive as possible, if disposed or closed already
+ if( m_bDisposed || m_bInDispose )
+ return; //behave as passive as possible, if disposed or closed already
+
+ //--------
+ m_bClosed = sal_True;
+
+ NegativeGuard< osl::Mutex > aNegativeGuard( m_aAccessMutex );
+ //mutex is not acquired, mutex will be reacquired at the end of this method automatically
+
+ uno::Reference< util::XCloseable > xCloseable=NULL;
+ try
+ {
+ xCloseable = uno::Reference< util::XCloseable >(m_pCloseable);;
+ if(xCloseable.is())
+ {
+ //--call notifyClosing on all registered close listeners
+ ::cppu::OInterfaceContainerHelper* pIC = m_aListenerContainer.getContainer(
+ ::getCppuType((const uno::Reference< util::XCloseListener >*)0) );;
+ if( pIC )
+ {
+ //lang::EventObject aEvent( static_cast< util::XCloseable*>(xCloseable) );
+ lang::EventObject aEvent( xCloseable );
+ ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ while( aIt.hasMoreElements() )
+ {
+ uno::Reference< util::XCloseListener > xListener( aIt.next(), uno::UNO_QUERY );
+ if( xListener.is() )
+ xListener->notifyClosing( aEvent );
+ }
+ }
+ }
+ }
+ catch( uno::Exception& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ if(xCloseable.is())
+ {
+ uno::Reference< lang::XComponent > xComponent =
+ uno::Reference< lang::XComponent >( xCloseable, uno::UNO_QUERY );
+ if(xComponent.is())
+ {
+ OSL_ENSURE( m_bClosed, "a not closed component will be disposed " );
+ xComponent->dispose();
+ }
+ }
+ //mutex will be reacquired in destructor of aNegativeGuard
+}
+
+ sal_Bool CloseableLifeTimeManager
+::g_addCloseListener( const uno::Reference< util::XCloseListener > & xListener )
+ throw(uno::RuntimeException)
+{
+ osl::Guard< osl::Mutex > aGuard( m_aAccessMutex );
+ //Mutex needs to be acquired exactly ones; will be released inbetween
+ if( !impl_canStartApiCall() )
+ return sal_False;
+ //mutex is acquired
+
+ m_aListenerContainer.addInterface( ::getCppuType((const uno::Reference< util::XCloseListener >*)0),xListener );
+ m_bOwnership = sal_False;
+ return sal_True;
+}
+
+ sal_Bool CloseableLifeTimeManager
+::impl_canStartApiCall()
+{
+ //Mutex needs to be acquired exactly ones before calling this method
+ //the mutex will be released inbetween and reacquired
+
+ if( impl_isDisposed() )
+ return sal_False; //behave passive if already disposed
+ if( m_bClosed )
+ return sal_False; //behave passive if closing is already done
+
+ //during try-close most calls need to wait for the decision
+ while( m_bInTryClose )
+ {
+ //if someone tries to close this object at the moment
+ //we need to wait for his end because the result of the preceding call
+ //is relevant for our behaviour here
+
+ m_aAccessMutex.release();
+ m_aEndTryClosingCondition.wait(); //@todo??? this may block??? try closing
+ m_aAccessMutex.acquire();
+ if( m_bDisposed || m_bInDispose || m_bClosed )
+ return sal_False; //return if closed already
+ }
+ //mutex is acquired
+ return sal_True;
+}
+
+//--------------------------
+
+ sal_Bool LifeTimeGuard
+::startApiCall(sal_Bool bLongLastingCall)
+{
+ //Mutex needs to be acquired exactly ones; will be released inbetween
+ //mutex is requiered due to constructor of LifeTimeGuard
+
+ OSL_ENSURE( !m_bCallRegistered, "this method is only allowed ones" );
+ if(m_bCallRegistered)
+ return sal_False;
+
+ //Mutex needs to be acquired exactly ones; will be released inbetween
+ if( !m_rManager.impl_canStartApiCall() )
+ return sal_False;
+ //mutex is acquired
+
+ m_bCallRegistered = sal_True;
+ m_bLongLastingCallRegistered = bLongLastingCall;
+ m_rManager.impl_registerApiCall(bLongLastingCall);
+ return sal_True;
+}
+
+LifeTimeGuard::~LifeTimeGuard()
+{
+ try
+ {
+ //do acquire the mutex if it was cleared before
+ osl::MutexGuard g(m_rManager.m_aAccessMutex);
+ if(m_bCallRegistered)
+ {
+ //Mutex needs to be acquired exactly ones
+ //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
+ m_rManager.impl_unregisterApiCall(m_bLongLastingCallRegistered);
+ }
+ }
+ catch( uno::Exception& ex )
+ {
+ //@todo ? allow a uno::RuntimeException from dispose to travel through??
+ ex.Context.is(); //to avoid compilation warnings
+ }
+}
+
+/*
+the XCloseable::close method has to be implemented in the following way:
+::close
+{
+ //hold no mutex
+
+ if( !m_aLifeTimeManager.g_close_startTryClose( bDeliverOwnership ) )
+ return;
+ //no mutex is acquired
+
+ // At the end of this method may we must dispose ourself ...
+ // and may nobody from outside hold a reference to us ...
+ // then it's a good idea to do that by ourself.
+ uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
+
+ //the listeners have had no veto
+ //check wether we self can close
+ {
+ util::CloseVetoException aVetoException = util::CloseVetoException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "the model itself could not be closed" ) )
+ , static_cast< ::cppu::OWeakObject* >(this));
+
+ if( m_aLifeTimeManager.g_close_isNeedToCancelLongLastingCalls( bDeliverOwnership, aVetoException ) )
+ {
+ ////you can empty this block, if you never start longlasting calls or
+ ////if your longlasting calls are per default not cancelable (check how you have constructed your LifeTimeManager)
+
+ sal_Bool bLongLastingCallsAreCanceled = sal_False;
+ try
+ {
+ //try to cancel running longlasting calls
+ //// @todo
+ }
+ catch( uno::Exception& ex )
+ {
+ //// @todo
+ //do not throw anything here!! (without endTryClose)
+ }
+ //if not successful canceled
+ if(!bLongLastingCallsAreCanceled)
+ {
+ m_aLifeTimeManager.g_close_endTryClose( bDeliverOwnership, sal_True );
+ throw aVetoException;
+ }
+ }
+
+ }
+ m_aLifeTimeManager.g_close_endTryClose_doClose();
+}
+*/
+
+}//end namespace apphelper
diff --git a/chart2/source/tools/LineProperties.cxx b/chart2/source/tools/LineProperties.cxx
new file mode 100644
index 000000000000..95cf95e21a86
--- /dev/null
+++ b/chart2/source/tools/LineProperties.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "LineProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+
+namespace chart
+{
+
+void LineProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ // Line Properties see service drawing::LineProperties
+ // ---------------
+ rOutProperties.push_back(
+ Property( C2U( "LineStyle" ),
+ PROP_LINE_STYLE,
+ ::getCppuType( reinterpret_cast< const drawing::LineStyle * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineDash" ),
+ PROP_LINE_DASH,
+ ::getCppuType( reinterpret_cast< const drawing::LineDash * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+//not in service description
+ rOutProperties.push_back(
+ Property( C2U( "LineDashName" ),
+ PROP_LINE_DASH_NAME,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineColor" ),
+ PROP_LINE_COLOR,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineTransparence" ),
+ PROP_LINE_TRANSPARENCE,
+ ::getCppuType( reinterpret_cast< const sal_Int16 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineWidth" ),
+ PROP_LINE_WIDTH,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineJoint" ),
+ PROP_LINE_JOINT,
+ ::getCppuType( reinterpret_cast< const drawing::LineJoint * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+void LineProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_STYLE, drawing::LineStyle_SOLID );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_WIDTH, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_COLOR, 0x000000 ); // black
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_LINE_TRANSPARENCE, 0 );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_JOINT, drawing::LineJoint_ROUND );
+}
+
+//static
+bool LineProperties::IsLineVisible( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xLineProperties )
+{
+ bool bRet = false;
+ try
+ {
+ if( xLineProperties.is() )
+ {
+ drawing::LineStyle aLineStyle(drawing::LineStyle_SOLID);
+ xLineProperties->getPropertyValue( C2U( "LineStyle" ) ) >>= aLineStyle;
+ if( aLineStyle != drawing::LineStyle_NONE )
+ {
+ sal_Int16 nLineTransparence=0;
+ xLineProperties->getPropertyValue( C2U( "LineTransparence" ) ) >>= nLineTransparence;
+ if(100!=nLineTransparence)
+ {
+ bRet = true;
+ }
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return bRet;
+}
+
+//static
+void LineProperties::SetLineVisible( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xLineProperties )
+{
+ try
+ {
+ if( xLineProperties.is() )
+ {
+ drawing::LineStyle aLineStyle(drawing::LineStyle_SOLID);
+ xLineProperties->getPropertyValue( C2U( "LineStyle" ) ) >>= aLineStyle;
+ if( aLineStyle == drawing::LineStyle_NONE )
+ xLineProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) );
+
+ sal_Int16 nLineTransparence=0;
+ xLineProperties->getPropertyValue( C2U( "LineTransparence" ) ) >>= nLineTransparence;
+ if(100==nLineTransparence)
+ xLineProperties->setPropertyValue( C2U( "LineTransparence" ), uno::makeAny( sal_Int16(0) ) );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+//static
+void LineProperties::SetLineInvisible( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet >& xLineProperties )
+{
+ try
+ {
+ if( xLineProperties.is() )
+ {
+ drawing::LineStyle aLineStyle(drawing::LineStyle_SOLID);
+ xLineProperties->getPropertyValue( C2U( "LineStyle" ) ) >>= aLineStyle;
+ if( aLineStyle != drawing::LineStyle_NONE )
+ xLineProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/LinearRegressionCurveCalculator.cxx b/chart2/source/tools/LinearRegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..7a372cff4f51
--- /dev/null
+++ b/chart2/source/tools/LinearRegressionCurveCalculator.cxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "LinearRegressionCurveCalculator.hxx"
+#include "macros.hxx"
+#include "RegressionCalculationHelper.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+LinearRegressionCurveCalculator::LinearRegressionCurveCalculator() :
+ m_fSlope( 0.0 ),
+ m_fIntercept( 0.0 )
+{
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+}
+
+LinearRegressionCurveCalculator::~LinearRegressionCurveCalculator()
+{}
+
+// ____ XRegressionCurveCalculator ____
+void SAL_CALL LinearRegressionCurveCalculator::recalculateRegression(
+ const uno::Sequence< double >& aXValues,
+ const uno::Sequence< double >& aYValues )
+ throw (uno::RuntimeException)
+{
+ RegressionCalculationHelper::tDoubleVectorPair aValues(
+ RegressionCalculationHelper::cleanup(
+ aXValues, aYValues,
+ RegressionCalculationHelper::isValid()));
+
+ const size_t nMax = aValues.first.size();
+ if( nMax == 0 )
+ {
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+ ::rtl::math::setNan( & m_fCorrelationCoeffitient );
+ return;
+ }
+
+ const double fN = static_cast< double >( nMax );
+ double fSumX = 0.0, fSumY = 0.0, fSumXSq = 0.0, fSumYSq = 0.0, fSumXY = 0.0;
+ for( size_t i = 0; i < nMax; ++i )
+ {
+ fSumX += aValues.first[i];
+ fSumY += aValues.second[i];
+ fSumXSq += aValues.first[i] * aValues.first[i];
+ fSumYSq += aValues.second[i] * aValues.second[i];
+ fSumXY += aValues.first[i] * aValues.second[i];
+ }
+
+ m_fSlope = (fN * fSumXY - fSumX * fSumY) / ( fN * fSumXSq - fSumX * fSumX );
+ m_fIntercept = (fSumY - m_fSlope * fSumX) / fN;
+
+ m_fCorrelationCoeffitient = ( fN * fSumXY - fSumX * fSumY ) /
+ sqrt( ( fN * fSumXSq - fSumX * fSumX ) *
+ ( fN * fSumYSq - fSumY * fSumY ) );
+}
+
+double SAL_CALL LinearRegressionCurveCalculator::getCurveValue( double x )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ double fResult;
+ ::rtl::math::setNan( & fResult );
+
+ if( ! ( ::rtl::math::isNan( m_fSlope ) ||
+ ::rtl::math::isNan( m_fIntercept )))
+ {
+ fResult = m_fSlope * x + m_fIntercept;
+ }
+
+ return fResult;
+}
+
+uno::Sequence< geometry::RealPoint2D > SAL_CALL LinearRegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const uno::Reference< chart2::XScaling >& xScalingX,
+ const uno::Reference< chart2::XScaling >& xScalingY,
+ ::sal_Bool bMaySkipPointsInCalculation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( bMaySkipPointsInCalculation &&
+ isLinearScaling( xScalingX ) &&
+ isLinearScaling( xScalingY ))
+ {
+ // optimize result
+ uno::Sequence< geometry::RealPoint2D > aResult( 2 );
+ aResult[0].X = min;
+ aResult[0].Y = this->getCurveValue( min );
+ aResult[1].X = max;
+ aResult[1].Y = this->getCurveValue( max );
+
+ return aResult;
+ }
+ return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
+}
+
+OUString LinearRegressionCurveCalculator::ImplGetRepresentation(
+ const uno::Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey ) const
+{
+ OUStringBuffer aBuf( C2U( "f(x) = " ));
+
+ bool bHaveSlope = false;
+
+ if( m_fSlope != 0.0 )
+ {
+ if( ::rtl::math::approxEqual( fabs( m_fSlope ), 1.0 ))
+ {
+ if( m_fSlope < 0 )
+ aBuf.append( UC_MINUS_SIGN );
+ }
+ else
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fSlope ));
+ aBuf.append( sal_Unicode( 'x' ));
+ bHaveSlope = true;
+ }
+
+ if( bHaveSlope )
+ {
+ if( m_fIntercept < 0.0 )
+ {
+ aBuf.append( UC_SPACE );
+ aBuf.append( UC_MINUS_SIGN );
+ aBuf.append( UC_SPACE );
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fabs( m_fIntercept )));
+ }
+ else if( m_fIntercept > 0.0 )
+ {
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " + " ));
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+ }
+ else
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx b/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..c7c2db60431c
--- /dev/null
+++ b/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "LogarithmicRegressionCurveCalculator.hxx"
+#include "macros.hxx"
+#include "RegressionCalculationHelper.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+LogarithmicRegressionCurveCalculator::LogarithmicRegressionCurveCalculator() :
+ m_fSlope( 0.0 ),
+ m_fIntercept( 0.0 )
+{
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+}
+
+LogarithmicRegressionCurveCalculator::~LogarithmicRegressionCurveCalculator()
+{}
+
+// ____ XRegressionCurve ____
+void SAL_CALL LogarithmicRegressionCurveCalculator::recalculateRegression(
+ const uno::Sequence< double >& aXValues,
+ const uno::Sequence< double >& aYValues )
+ throw (uno::RuntimeException)
+{
+ RegressionCalculationHelper::tDoubleVectorPair aValues(
+ RegressionCalculationHelper::cleanup(
+ aXValues, aYValues,
+ RegressionCalculationHelper::isValidAndXPositive()));
+
+ const size_t nMax = aValues.first.size();
+ if( nMax == 0 )
+ {
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+ ::rtl::math::setNan( & m_fCorrelationCoeffitient );
+ return;
+ }
+
+ double fAverageX = 0.0, fAverageY = 0.0;
+ size_t i = 0;
+ for( i = 0; i < nMax; ++i )
+ {
+ fAverageX += log( aValues.first[i] );
+ fAverageY += aValues.second[i];
+ }
+
+ const double fN = static_cast< double >( nMax );
+ fAverageX /= fN;
+ fAverageY /= fN;
+
+ double fQx = 0.0, fQy = 0.0, fQxy = 0.0;
+ for( i = 0; i < nMax; ++i )
+ {
+ double fDeltaX = log( aValues.first[i] ) - fAverageX;
+ double fDeltaY = aValues.second[i] - fAverageY;
+
+ fQx += fDeltaX * fDeltaX;
+ fQy += fDeltaY * fDeltaY;
+ fQxy += fDeltaX * fDeltaY;
+ }
+
+ m_fSlope = fQxy / fQx;
+ m_fIntercept = fAverageY - m_fSlope * fAverageX;
+ m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy );
+}
+
+double SAL_CALL LogarithmicRegressionCurveCalculator::getCurveValue( double x )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ double fResult;
+ ::rtl::math::setNan( & fResult );
+
+ if( ! ( ::rtl::math::isNan( m_fSlope ) ||
+ ::rtl::math::isNan( m_fIntercept )))
+ {
+ fResult = m_fSlope * log( x ) + m_fIntercept;
+ }
+
+ return fResult;
+}
+
+uno::Sequence< geometry::RealPoint2D > SAL_CALL LogarithmicRegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const uno::Reference< chart2::XScaling >& xScalingX,
+ const uno::Reference< chart2::XScaling >& xScalingY,
+ ::sal_Bool bMaySkipPointsInCalculation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( bMaySkipPointsInCalculation &&
+ isLogarithmicScaling( xScalingX ) &&
+ isLinearScaling( xScalingY ))
+ {
+ // optimize result
+ uno::Sequence< geometry::RealPoint2D > aResult( 2 );
+ aResult[0].X = min;
+ aResult[0].Y = this->getCurveValue( min );
+ aResult[1].X = max;
+ aResult[1].Y = this->getCurveValue( max );
+
+ return aResult;
+ }
+ return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
+}
+
+OUString LogarithmicRegressionCurveCalculator::ImplGetRepresentation(
+ const uno::Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey ) const
+{
+ OUStringBuffer aBuf( C2U( "f(x) = " ));
+
+ bool bHaveSlope = false;
+
+ if( m_fSlope != 0.0 )
+ {
+ if( ::rtl::math::approxEqual( fabs( m_fSlope ), 1.0 ))
+ {
+ if( m_fSlope < 0 )
+ aBuf.append( UC_MINUS_SIGN );
+ }
+ else
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fSlope ));
+ aBuf.append( UC_SPACE );
+ }
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "ln(x)" ));
+ bHaveSlope = true;
+ }
+
+ if( bHaveSlope )
+ {
+ if( m_fIntercept < 0.0 )
+ {
+ aBuf.append( UC_SPACE );
+ aBuf.append( UC_MINUS_SIGN );
+ aBuf.append( UC_SPACE );
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, fabs( m_fIntercept )));
+ }
+ else if( m_fIntercept > 0.0 )
+ {
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " + " ));
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+ }
+ else
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx b/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..8277a5830b0a
--- /dev/null
+++ b/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "MeanValueRegressionCurveCalculator.hxx"
+#include "macros.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+MeanValueRegressionCurveCalculator::MeanValueRegressionCurveCalculator() :
+ m_fMeanValue( 0.0 )
+{
+ ::rtl::math::setNan( & m_fMeanValue );
+}
+
+MeanValueRegressionCurveCalculator::~MeanValueRegressionCurveCalculator()
+{}
+
+// ____ XRegressionCurveCalculator ____
+void SAL_CALL MeanValueRegressionCurveCalculator::recalculateRegression(
+ const uno::Sequence< double >& /*aXValues*/,
+ const uno::Sequence< double >& aYValues )
+ throw (uno::RuntimeException)
+{
+ const sal_Int32 nDataLength = aYValues.getLength();
+ sal_Int32 nMax = nDataLength;
+ double fSumY = 0.0;
+ const double * pY = aYValues.getConstArray();
+
+ for( sal_Int32 i = 0; i < nDataLength; ++i )
+ {
+ if( ::rtl::math::isNan( pY[i] ) ||
+ ::rtl::math::isInf( pY[i] ))
+ --nMax;
+ else
+ fSumY += pY[i];
+ }
+
+ m_fCorrelationCoeffitient = 0.0;
+
+ if( nMax == 0 )
+ {
+ ::rtl::math::setNan( & m_fMeanValue );
+ }
+ else
+ {
+ m_fMeanValue = fSumY / static_cast< double >( nMax );
+
+ // correlation coefficient: standard deviation
+ if( nMax > 1 )
+ {
+ double fErrorSum = 0.0;
+ for( sal_Int32 i = 0; i < nDataLength; ++i )
+ {
+ if( !::rtl::math::isNan( pY[i] ) &&
+ !::rtl::math::isInf( pY[i] ))
+ {
+ double v = m_fMeanValue - pY[i];
+ fErrorSum += (v*v);
+ }
+ }
+ OSL_ASSERT( fErrorSum >= 0.0 );
+ m_fCorrelationCoeffitient = sqrt( fErrorSum / (nMax - 1 ));
+ }
+ }
+}
+
+double SAL_CALL MeanValueRegressionCurveCalculator::getCurveValue( double /*x*/ )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return m_fMeanValue;
+}
+
+
+uno::Sequence< geometry::RealPoint2D > SAL_CALL MeanValueRegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const uno::Reference< chart2::XScaling >& xScalingX,
+ const uno::Reference< chart2::XScaling >& xScalingY,
+ ::sal_Bool bMaySkipPointsInCalculation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( bMaySkipPointsInCalculation )
+ {
+ // optimize result
+ uno::Sequence< geometry::RealPoint2D > aResult( 2 );
+ aResult[0].X = min;
+ aResult[0].Y = m_fMeanValue;
+ aResult[1].X = max;
+ aResult[1].Y = m_fMeanValue;
+
+ return aResult;
+ }
+ return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
+}
+
+OUString MeanValueRegressionCurveCalculator::ImplGetRepresentation(
+ const uno::Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey ) const
+{
+ OUStringBuffer aBuf( C2U( "f(x) = " ));
+
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fMeanValue ));
+
+ return aBuf.makeStringAndClear();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/MediaDescriptorHelper.cxx b/chart2/source/tools/MediaDescriptorHelper.cxx
new file mode 100644
index 000000000000..687bc203a84f
--- /dev/null
+++ b/chart2/source/tools/MediaDescriptorHelper.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "MediaDescriptorHelper.hxx"
+
+using namespace ::com::sun::star;
+
+namespace apphelper
+{
+
+
+const short FLAG_DEPRECATED =1;
+const short FLAG_MODEL =2;
+
+#define WRITE_PROPERTY( MediaName, nFlags ) \
+if(rProp.Name.equals(::rtl::OUString::createFromAscii(#MediaName))) \
+{ \
+ if( rProp.Value >>= MediaName ) \
+ ISSET_##MediaName = sal_True; \
+ if(nFlags & FLAG_DEPRECATED) \
+ { \
+ m_aDeprecatedProperties[nDeprecatedCount]=rProp;\
+ nDeprecatedCount++; \
+ } \
+ else \
+ { \
+ m_aRegularProperties[nRegularCount]=rProp; \
+ nRegularCount++; \
+ if( nFlags & FLAG_MODEL) \
+ { \
+ m_aModelProperties[nModelCount]=rProp; \
+ nModelCount++; \
+ } \
+ } \
+}
+
+MediaDescriptorHelper::MediaDescriptorHelper( const uno::Sequence<
+ beans::PropertyValue > & rMediaDescriptor )
+{
+ impl_init();
+
+ m_aRegularProperties.realloc(0);
+ m_aRegularProperties.realloc(rMediaDescriptor.getLength());
+ sal_Int32 nRegularCount = 0;
+
+ m_aDeprecatedProperties.realloc(0);
+ m_aDeprecatedProperties.realloc(rMediaDescriptor.getLength());
+ sal_Int32 nDeprecatedCount = 0;
+
+ m_aAdditionalProperties.realloc(0);
+ m_aAdditionalProperties.realloc(rMediaDescriptor.getLength());
+ sal_Int32 nAdditionalCount = 0;
+
+ m_aModelProperties.realloc(0);
+ m_aModelProperties.realloc(rMediaDescriptor.getLength());
+ sal_Int32 nModelCount = 0;
+
+
+ //read given rMediaDescriptor and store in internal structures:
+ for( sal_Int32 i= rMediaDescriptor.getLength();i--;)
+ {
+ const beans::PropertyValue& rProp = rMediaDescriptor[i];
+ WRITE_PROPERTY( AsTemplate, FLAG_MODEL )
+ else WRITE_PROPERTY( Author, FLAG_MODEL )
+ else WRITE_PROPERTY( CharacterSet, FLAG_MODEL )
+ else WRITE_PROPERTY( Comment, FLAG_MODEL )
+ else WRITE_PROPERTY( ComponentData, FLAG_MODEL )
+ else WRITE_PROPERTY( FileName, FLAG_DEPRECATED )
+ else WRITE_PROPERTY( FilterData, FLAG_MODEL )
+ else WRITE_PROPERTY( FilterName, FLAG_MODEL )
+ else WRITE_PROPERTY( FilterFlags, FLAG_DEPRECATED)
+ else WRITE_PROPERTY( FilterOptions, FLAG_MODEL )
+ else WRITE_PROPERTY( FrameName, FLAG_MODEL )
+ else WRITE_PROPERTY( Hidden, FLAG_MODEL )
+ else WRITE_PROPERTY( HierarchicalDocumentName, FLAG_MODEL )
+ else WRITE_PROPERTY( OutputStream, 0 )
+ else WRITE_PROPERTY( InputStream, 0 )
+ else WRITE_PROPERTY( InteractionHandler, 0 )
+ else WRITE_PROPERTY( JumpMark, 0 )
+ else WRITE_PROPERTY( MediaType, FLAG_MODEL )
+ else WRITE_PROPERTY( OpenFlags, FLAG_DEPRECATED )
+ else WRITE_PROPERTY( OpenNewView, 0 )
+ else WRITE_PROPERTY( Overwrite, FLAG_MODEL )
+ else WRITE_PROPERTY( Password, FLAG_MODEL )
+ else WRITE_PROPERTY( PosSize, 0 )
+ else WRITE_PROPERTY( PostData, 0 )
+ else WRITE_PROPERTY( PostString, FLAG_DEPRECATED )
+ else WRITE_PROPERTY( Preview, FLAG_MODEL )
+ else WRITE_PROPERTY( ReadOnly, 0 )
+ else WRITE_PROPERTY( Referer, FLAG_MODEL )
+ else WRITE_PROPERTY( SetEmbedded, 0 )
+ else WRITE_PROPERTY( Silent, 0 )
+ else WRITE_PROPERTY( StatusIndicator, 0 )
+ else WRITE_PROPERTY( Storage, FLAG_MODEL )
+ else WRITE_PROPERTY( Stream, FLAG_MODEL )
+ else WRITE_PROPERTY( TemplateName, FLAG_DEPRECATED )
+ else WRITE_PROPERTY( TemplateRegionName, FLAG_DEPRECATED )
+ else WRITE_PROPERTY( Unpacked, FLAG_MODEL )
+ else WRITE_PROPERTY( URL, FLAG_MODEL )
+ else WRITE_PROPERTY( Version, FLAG_MODEL )
+ else WRITE_PROPERTY( ViewData, FLAG_MODEL )
+ else WRITE_PROPERTY( ViewId, FLAG_MODEL )
+ else WRITE_PROPERTY( WinExtent, FLAG_DEPRECATED )
+ else
+ {
+ m_aAdditionalProperties[nAdditionalCount]=rProp;
+ nAdditionalCount++;
+ }
+ }
+
+ m_aRegularProperties.realloc(nRegularCount);
+ m_aDeprecatedProperties.realloc(nDeprecatedCount);
+ m_aAdditionalProperties.realloc(nAdditionalCount);
+ m_aModelProperties.realloc(nModelCount);
+}
+
+void MediaDescriptorHelper::impl_init()
+{
+ AsTemplate = sal_False;
+ ISSET_AsTemplate = sal_False;
+
+ ISSET_Author = sal_False;
+ ISSET_CharacterSet = sal_False;
+ ISSET_Comment = sal_False;
+
+// ::com::sun::star::uno::Any ComponentData;
+ ISSET_ComponentData = sal_False;
+ ISSET_FileName = sal_False;
+
+// ::com::sun::star::uno::Any FilterData;
+ ISSET_FilterData = sal_False;
+ ISSET_FilterName = sal_False;
+ ISSET_FilterFlags = sal_False;
+ ISSET_FilterOptions = sal_False;
+ ISSET_FrameName = sal_False;
+
+ Hidden = sal_False;
+ ISSET_Hidden = sal_False;
+ ISSET_HierarchicalDocumentName = sal_False;
+ ISSET_OutputStream = sal_False;
+ ISSET_InputStream = sal_False;
+ ISSET_InteractionHandler = sal_False;
+ ISSET_JumpMark = sal_False;
+ ISSET_MediaType = sal_False;
+ ISSET_OpenFlags = sal_False;
+ OpenNewView = sal_False;
+ ISSET_OpenNewView = sal_False;
+ Overwrite = sal_False;
+ ISSET_Overwrite = sal_False;
+ ISSET_Password = sal_False;
+
+// ::com::sun::star::awt::Rectangle PosSize;
+ ISSET_PosSize = sal_False;
+
+// ::com::sun::star::uno::Sequence< sal_Int8 > PostData;
+ ISSET_PostData = sal_False;
+ ISSET_PostString = sal_False;
+ Preview = sal_False;
+ ISSET_Preview = sal_False;
+ ReadOnly = sal_False;
+ ISSET_ReadOnly = sal_False;
+ ISSET_Referer = sal_False;
+ ISSET_StatusIndicator = sal_False;
+ Silent = sal_False;
+ ISSET_Silent = sal_False;
+ ISSET_TemplateName = sal_False;
+ ISSET_TemplateRegionName = sal_False;
+ Unpacked = sal_False;
+ ISSET_Unpacked = sal_False;
+ ISSET_URL = sal_False;
+ Version = 0;
+ ISSET_Version = sal_False;
+
+// ::com::sun::star::uno::Any ViewData;
+ ISSET_ViewData = sal_False;
+ ViewId = 0;
+ ISSET_ViewId = sal_False;
+
+ ISSET_WinExtent = sal_False;
+
+ ISSET_Storage = sal_False;
+ ISSET_Stream = sal_False;
+}
+
+MediaDescriptorHelper::~MediaDescriptorHelper()
+{
+
+}
+
+ uno::Sequence< beans::PropertyValue > MediaDescriptorHelper
+::getReducedForModel()
+{
+ return m_aModelProperties;
+}
+}
diff --git a/chart2/source/tools/ModifyListenerCallBack.cxx b/chart2/source/tools/ModifyListenerCallBack.cxx
new file mode 100644
index 000000000000..ae13b65c39c2
--- /dev/null
+++ b/chart2/source/tools/ModifyListenerCallBack.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ModifyListenerCallBack.hxx"
+#include "MutexContainer.hxx"
+#include <cppuhelper/compbase1.hxx>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+namespace chart {
+
+typedef ::cppu::WeakComponentImplHelper1<
+ ::com::sun::star::util::XModifyListener >
+ ModifyListenerCallBack_Base;
+
+class ModifyListenerCallBack_impl
+ : public ::chart::MutexContainer
+ , public ModifyListenerCallBack_Base
+{
+public:
+ explicit ModifyListenerCallBack_impl( const Link& rCallBack );
+ virtual ~ModifyListenerCallBack_impl();
+
+ void startListening( const Reference< util::XModifyBroadcaster >& xBroadcaster );
+ void stopListening();
+
+ //XModifyListener
+ virtual void SAL_CALL modified( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
+
+ //XEventListener
+ virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
+
+ using ::cppu::WeakComponentImplHelperBase::disposing;
+
+private:
+ Link m_aLink;//will be callef on modify
+ Reference< util::XModifyBroadcaster > m_xBroadcaster;//broadcaster to listen at
+};
+
+
+ModifyListenerCallBack_impl::ModifyListenerCallBack_impl( const Link& rCallBack )
+ : ModifyListenerCallBack_Base( m_aMutex )
+ , m_aLink( rCallBack )
+ , m_xBroadcaster(0)
+{
+}
+
+ModifyListenerCallBack_impl::~ModifyListenerCallBack_impl()
+{
+}
+
+//XModifyListener
+void SAL_CALL ModifyListenerCallBack_impl::modified( const lang::EventObject& /*aEvent*/ ) throw (uno::RuntimeException)
+{
+ m_aLink.Call(0);
+}
+
+//XEventListener
+void SAL_CALL ModifyListenerCallBack_impl::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
+{
+ m_xBroadcaster.clear();
+}
+
+void ModifyListenerCallBack_impl::startListening( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >& xBroadcaster )
+{
+ if( m_xBroadcaster == xBroadcaster )
+ return;
+
+ stopListening();
+ m_xBroadcaster = xBroadcaster;
+ if( m_xBroadcaster.is() )
+ m_xBroadcaster->addModifyListener( this );
+}
+void ModifyListenerCallBack_impl::stopListening()
+{
+ if( m_xBroadcaster.is() )
+ {
+ m_xBroadcaster->removeModifyListener( this );
+ m_xBroadcaster.clear();
+ }
+}
+
+//-------------------------------------------
+
+ModifyListenerCallBack::ModifyListenerCallBack( const Link& rCallBack )
+ : pModifyListener_impl( new ModifyListenerCallBack_impl(rCallBack) )
+ , m_xModifyListener( pModifyListener_impl )
+{
+}
+
+ModifyListenerCallBack::~ModifyListenerCallBack()
+{
+ stopListening();
+}
+
+void ModifyListenerCallBack::startListening( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyBroadcaster >& xBroadcaster )
+{
+ pModifyListener_impl->startListening( xBroadcaster );
+}
+void ModifyListenerCallBack::stopListening()
+{
+ pModifyListener_impl->stopListening();
+}
+
+} // namespace chart
+
diff --git a/chart2/source/tools/ModifyListenerHelper.cxx b/chart2/source/tools/ModifyListenerHelper.cxx
new file mode 100644
index 000000000000..7ac5a2786cef
--- /dev/null
+++ b/chart2/source/tools/ModifyListenerHelper.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ModifyListenerHelper.hxx"
+#include "WeakListenerAdapter.hxx"
+#include "macros.hxx"
+
+#include <cppuhelper/interfacecontainer.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace
+{
+
+void lcl_fireModifyEvent(
+ ::cppu::OBroadcastHelper & rBroadcastHelper,
+ const Reference< uno::XWeak > & xEventSource,
+ const lang::EventObject * pEvent )
+{
+ ::cppu::OInterfaceContainerHelper * pCntHlp = rBroadcastHelper.getContainer(
+ ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0)));
+ if( pCntHlp )
+ {
+ lang::EventObject aEventToSend;
+ if( pEvent )
+ aEventToSend = *pEvent;
+ else
+ aEventToSend.Source.set( xEventSource );
+ OSL_ENSURE( aEventToSend.Source.is(), "Sending event without source" );
+
+ ::cppu::OInterfaceIteratorHelper aIt( *pCntHlp );
+
+ while( aIt.hasMoreElements())
+ {
+ Reference< util::XModifyListener > xModListener( aIt.next(), uno::UNO_QUERY );
+ if( xModListener.is())
+ xModListener->modified( aEventToSend );
+ }
+ }
+}
+
+struct lcl_weakReferenceToSame : public ::std::unary_function<
+ ::std::pair<
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XModifyListener >,
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > >,
+ bool >
+{
+ lcl_weakReferenceToSame( const Reference< util::XModifyListener > & xModListener ) :
+ m_xHardRef( xModListener )
+ {}
+
+ bool operator() ( const argument_type & xElem )
+ {
+ Reference< util::XModifyListener > xWeakAsHard( xElem.first );
+ if( xWeakAsHard.is())
+ return (xWeakAsHard == m_xHardRef);
+ return false;
+ }
+
+private:
+ Reference< util::XModifyListener > m_xHardRef;
+};
+
+} // anonymous namespace
+
+// ================================================================================
+
+namespace chart
+{
+namespace ModifyListenerHelper
+{
+
+uno::Reference< util::XModifyListener > createModifyEventForwarder()
+{
+ return new ModifyEventForwarder();
+}
+
+ModifyEventForwarder::ModifyEventForwarder() :
+ ::cppu::WeakComponentImplHelper2<
+ ::com::sun::star::util::XModifyBroadcaster,
+ ::com::sun::star::util::XModifyListener >( m_aMutex ),
+ m_aModifyListeners( m_aMutex )
+{
+}
+
+void ModifyEventForwarder::FireEvent( const lang::EventObject & rEvent )
+{
+ lcl_fireModifyEvent( m_aModifyListeners, Reference< uno::XWeak >(), & rEvent );
+}
+
+void ModifyEventForwarder::AddListener( const Reference< util::XModifyListener >& aListener )
+{
+ try
+ {
+ Reference< util::XModifyListener > xListenerToAdd( aListener );
+
+ Reference< uno::XWeak > xWeak( aListener, uno::UNO_QUERY );
+ if( xWeak.is())
+ {
+ // remember the helper class for later remove
+ uno::WeakReference< util::XModifyListener > xWeakRef( aListener );
+ xListenerToAdd.set( new WeakModifyListenerAdapter( xWeakRef ));
+ m_aListenerMap.push_back( tListenerMap::value_type( xWeakRef, xListenerToAdd ));
+ }
+
+ m_aModifyListeners.addListener( ::getCppuType( &xListenerToAdd ), xListenerToAdd );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ModifyEventForwarder::RemoveListener( const Reference< util::XModifyListener >& aListener )
+{
+ try
+ {
+ // look up fitting helper class that has been added
+ Reference< util::XModifyListener > xListenerToRemove( aListener );
+ tListenerMap::iterator aIt(
+ ::std::find_if( m_aListenerMap.begin(), m_aListenerMap.end(), lcl_weakReferenceToSame( aListener )));
+ if( aIt != m_aListenerMap.end())
+ {
+ xListenerToRemove.set( (*aIt).second );
+ // map entry is no longer needed
+ m_aListenerMap.erase( aIt );
+ }
+
+ m_aModifyListeners.removeListener( ::getCppuType( &aListener ), xListenerToRemove );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ModifyEventForwarder::DisposeAndClear( const Reference< uno::XWeak > & xSource )
+{
+ ::cppu::OInterfaceContainerHelper * pCntHlp = m_aModifyListeners.getContainer(
+ ::getCppuType( reinterpret_cast< Reference< util::XModifyListener > * >(0)));
+ if( pCntHlp )
+ pCntHlp->disposeAndClear( lang::EventObject( xSource ) );
+}
+
+// ____ XModifyBroadcaster ____
+void SAL_CALL ModifyEventForwarder::addModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ AddListener( aListener );
+}
+
+void SAL_CALL ModifyEventForwarder::removeModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ RemoveListener( aListener );
+}
+
+// ____ XModifyListener ____
+void SAL_CALL ModifyEventForwarder::modified( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ FireEvent( aEvent );
+}
+
+// ____ XEventListener (base of XModifyListener) ____
+void SAL_CALL ModifyEventForwarder::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ // nothing
+}
+
+// ____ WeakComponentImplHelperBase ____
+void SAL_CALL ModifyEventForwarder::disposing()
+{
+ // dispose was called at this
+ DisposeAndClear( this );
+}
+
+} // namespace ModifyListenerHelper
+} // namespace chart
diff --git a/chart2/source/tools/MutexContainer.cxx b/chart2/source/tools/MutexContainer.cxx
new file mode 100644
index 000000000000..4fbb14674cdb
--- /dev/null
+++ b/chart2/source/tools/MutexContainer.cxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "MutexContainer.hxx"
+
+namespace chart
+{
+
+MutexContainer::~MutexContainer()
+{}
+
+::osl::Mutex & MutexContainer::GetMutex() const
+{
+ return m_aMutex;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/NameContainer.cxx b/chart2/source/tools/NameContainer.cxx
new file mode 100644
index 000000000000..05169c4608f9
--- /dev/null
+++ b/chart2/source/tools/NameContainer.cxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "NameContainer.hxx"
+
+/*
+//SvXMLUnitConverter
+#include <xmloff/xmluconv.hxx>
+*/
+#include <com/sun/star/uno/Any.hxx>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+uno::Reference< container::XNameContainer > createNameContainer(
+ const ::com::sun::star::uno::Type& rType, const rtl::OUString& rServicename, const rtl::OUString& rImplementationName )
+{
+ return new NameContainer( rType, rServicename, rImplementationName );
+}
+
+NameContainer::NameContainer( const ::com::sun::star::uno::Type& rType, const OUString& rServicename, const OUString& rImplementationName )
+ : m_aType( rType )
+ , m_aServicename( rServicename )
+ , m_aImplementationName( rImplementationName )
+ , m_aMap()
+{
+}
+
+NameContainer::NameContainer(
+ const NameContainer & rOther )
+ : impl::NameContainer_Base()
+ , m_aType( rOther.m_aType )
+ , m_aServicename( rOther.m_aServicename )
+ , m_aImplementationName( rOther.m_aImplementationName )
+ , m_aMap( rOther.m_aMap )
+{
+}
+
+NameContainer::~NameContainer()
+{
+}
+
+//XServiceInfo
+OUString SAL_CALL NameContainer::getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return m_aImplementationName;
+}
+
+sal_Bool SAL_CALL NameContainer::supportsService( const OUString& ServiceName )
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString* pArray = aSNL.getArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ {
+ if( pArray[ i ] == ServiceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL NameContainer::getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ] = m_aServicename;
+ return aSNS;
+}
+
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+
+// XNameContainer
+void SAL_CALL NameContainer::insertByName( const OUString& rName, const Any& rElement )
+ throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ if( m_aMap.find( rName ) != m_aMap.end() )
+ throw container::ElementExistException();
+ m_aMap.insert( tContentMap::value_type( rName, rElement ));
+}
+
+
+
+void SAL_CALL NameContainer::removeByName( const OUString& Name )
+ throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ tContentMap::iterator aIt( m_aMap.find( Name ));
+ if( aIt == m_aMap.end())
+ throw container::NoSuchElementException();
+ m_aMap.erase( aIt );
+}
+
+// XNameReplace
+void SAL_CALL NameContainer::replaceByName( const OUString& rName, const Any& rElement )
+ throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ tContentMap::iterator aIt( m_aMap.find( rName ));
+ if( aIt == m_aMap.end() )
+ throw container::NoSuchElementException();
+ aIt->second = rElement;
+}
+
+// XNameAccess
+Any SAL_CALL NameContainer::getByName( const OUString& rName )
+ throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ tContentMap::iterator aIter( m_aMap.find( rName ) );
+ if( aIter == m_aMap.end() )
+ throw container::NoSuchElementException();
+ return aIter->second;
+}
+
+Sequence< OUString > SAL_CALL NameContainer::getElementNames()
+ throw( uno::RuntimeException )
+{
+ sal_Int32 nCount = m_aMap.size();
+ Sequence< OUString > aSeq(nCount);
+ sal_Int32 nN = 0;
+ for( tContentMap::iterator aIter = m_aMap.begin(); aIter != m_aMap.end(), nN < nCount; aIter++, nN++ )
+ aSeq[nN]=aIter->first;
+ return aSeq;
+}
+
+sal_Bool SAL_CALL NameContainer::hasByName( const OUString& rName )
+ throw( uno::RuntimeException )
+{
+ return ( m_aMap.find( rName ) != m_aMap.end() );
+}
+
+// XElementAccess
+sal_Bool SAL_CALL NameContainer::hasElements()
+ throw( uno::RuntimeException )
+{
+ return ! m_aMap.empty();
+}
+
+uno::Type SAL_CALL NameContainer::getElementType()
+ throw( uno::RuntimeException )
+{
+ return m_aType;
+}
+
+// XCloneable
+uno::Reference< util::XCloneable > SAL_CALL NameContainer::createClone()
+ throw ( uno::RuntimeException )
+{
+ return uno::Reference< util::XCloneable >( new NameContainer( *this ));
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/NamedFillProperties.cxx b/chart2/source/tools/NamedFillProperties.cxx
new file mode 100644
index 000000000000..f904c34c1df1
--- /dev/null
+++ b/chart2/source/tools/NamedFillProperties.cxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "NamedFillProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <com/sun/star/chart2/FillBitmap.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+void NamedFillProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ const uno::Type tCppuTypeString = ::getCppuType( reinterpret_cast< const OUString * >(0));
+
+ // Fill Properties
+ // ---------------
+
+ //optional property:
+ rOutProperties.push_back(
+ Property( C2U( "FillTransparenceGradient" ),
+ PROP_FILL_TRANSPARENCE_GRADIENT,
+ ::getCppuType( reinterpret_cast< const awt::Gradient * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ //optional property:
+ rOutProperties.push_back(
+ Property( C2U( "FillGradient" ),
+ PROP_FILL_GRADIENT,
+ ::getCppuType( reinterpret_cast< const awt::Gradient * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ //optional property:
+ rOutProperties.push_back(
+ Property( C2U( "FillHatch" ),
+ PROP_FILL_HATCH,
+ ::getCppuType( reinterpret_cast< const drawing::Hatch * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ //optional property:
+ rOutProperties.push_back(
+ Property( C2U( "FillBitmapURL" ),
+ PROP_FILL_BITMAP,
+ ::getCppuType( reinterpret_cast< const ::rtl::OUString * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+}
+
+void NamedFillProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+}
+
+// static
+OUString NamedFillProperties::GetPropertyNameForHandle( sal_Int32 nHandle )
+{
+ //will return e.g. "FillGradientName" for PROP_FILL_GRADIENT_NAME
+ switch( nHandle )
+ {
+ case PROP_FILL_GRADIENT_NAME:
+ return C2U( "FillGradientName" );
+ case PROP_FILL_HATCH_NAME:
+ return C2U( "FillHatchName" );
+ case PROP_FILL_BITMAP_NAME:
+ return C2U( "FillBitmapName" );
+ case PROP_FILL_TRANSPARENCY_GRADIENT_NAME:
+ return C2U( "FillTransparenceGradientName" );
+ }
+ return OUString();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/NamedLineProperties.cxx b/chart2/source/tools/NamedLineProperties.cxx
new file mode 100644
index 000000000000..02680abf690e
--- /dev/null
+++ b/chart2/source/tools/NamedLineProperties.cxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "NamedLineProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+// @deprecated !!
+void NamedLineProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ const uno::Type tCppuTypeString = ::getCppuType( reinterpret_cast< const OUString * >(0));
+
+ // Line Properties
+ // ---------------
+ rOutProperties.push_back(
+ Property( C2U( "LineDash" ),
+ PROP_LINE_DASH,
+ ::getCppuType( reinterpret_cast< const drawing::LineDash * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ if( bIncludeLineEnds )
+ {
+ rOutProperties.push_back(
+ Property( C2U( "LineStartName" ),
+ PROP_LINE_START_NAME,
+ tCppuTypeString,
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "LineEndName" ),
+ PROP_LINE_END_NAME,
+ tCppuTypeString,
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT
+ | beans::PropertyAttribute::MAYBEVOID ));
+ }
+}
+
+void NamedLineProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap,
+ bool bIncludeLineEnds /* = false */ )
+{
+}
+
+// static
+OUString NamedLineProperties::GetPropertyNameForHandle( sal_Int32 nHandle )
+{
+ //will return e.g. "LineDashName" for PROP_LINE_DASH_NAME
+ switch( nHandle )
+ {
+ case PROP_LINE_DASH_NAME:
+ return C2U( "LineDashName" );
+ case PROP_LINE_START_NAME:
+ case PROP_LINE_END_NAME:
+ break;
+ }
+ return OUString();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/NamedProperties.cxx b/chart2/source/tools/NamedProperties.cxx
new file mode 100644
index 000000000000..4fcb536b3279
--- /dev/null
+++ b/chart2/source/tools/NamedProperties.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "NamedProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+void NamedProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ NamedFillProperties::AddPropertiesToVector( rOutProperties );
+ NamedLineProperties::AddPropertiesToVector( rOutProperties );
+}
+
+// static
+OUString NamedProperties::GetPropertyNameForHandle( sal_Int32 nHandle )
+{
+ OUString aName = NamedFillProperties::GetPropertyNameForHandle( nHandle );
+ if( !aName.getLength() )
+ aName = NamedLineProperties::GetPropertyNameForHandle( nHandle );
+ return aName;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/OPropertySet.cxx b/chart2/source/tools/OPropertySet.cxx
new file mode 100644
index 000000000000..a1caac803dd7
--- /dev/null
+++ b/chart2/source/tools/OPropertySet.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "OPropertySet.hxx"
+#include "ImplOPropertySet.hxx"
+#include "ContainerHelper.hxx"
+#include <rtl/uuid.h>
+#include <cppuhelper/queryinterface.hxx>
+
+#include <vector>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::style::XStyleSupplier;
+// using ::com::sun::star::beans::XFastPropertyState;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::osl::MutexGuard;
+
+// needed for MS compiler
+using ::cppu::OBroadcastHelper;
+using ::cppu::OPropertySetHelper;
+using ::cppu::OWeakObject;
+
+namespace property
+{
+
+OPropertySet::OPropertySet( ::osl::Mutex & par_rMutex ) :
+ OBroadcastHelper( par_rMutex ),
+ // the following causes a warning; there seems to be no way to avoid it
+ OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
+ m_rMutex( par_rMutex ),
+ m_pImplProperties( new impl::ImplOPropertySet() ),
+ m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
+{
+}
+
+OPropertySet::OPropertySet( const OPropertySet & rOther, ::osl::Mutex & par_rMutex ) :
+ OBroadcastHelper( par_rMutex ),
+ // the following causes a warning; there seems to be no way to avoid it
+ OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
+ m_rMutex( par_rMutex ),
+ m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
+{
+ // /--
+ MutexGuard aGuard( m_rMutex );
+ if( rOther.m_pImplProperties.get())
+ m_pImplProperties.reset( new impl::ImplOPropertySet( * rOther.m_pImplProperties.get()));
+ // \--
+}
+
+void OPropertySet::SetNewValuesExplicitlyEvenIfTheyEqualDefault()
+{
+ m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault = true;
+}
+
+OPropertySet::~OPropertySet()
+{}
+
+void OPropertySet::disposePropertySet()
+{
+ m_pImplProperties.reset( 0 );
+}
+
+Any SAL_CALL OPropertySet::queryInterface( const uno::Type& aType )
+ throw (uno::RuntimeException)
+{
+ return ::cppu::queryInterface(
+ aType,
+// static_cast< uno::XInterface * >(
+// static_cast< uno::XWeak * >( this )),
+// static_cast< uno::XWeak * >( this ),
+// static_cast< lang::XServiceInfo * >( this ),
+ static_cast< lang::XTypeProvider * >( this ),
+ static_cast< beans::XPropertySet * >( this ),
+ static_cast< beans::XMultiPropertySet * >( this ),
+ static_cast< beans::XFastPropertySet * >( this ),
+ static_cast< beans::XPropertyState * >( this ),
+ static_cast< beans::XMultiPropertyStates * >( this ),
+ static_cast< XStyleSupplier * >( this ) );
+// static_cast< XFastPropertyState * >( this ) );
+}
+
+// void SAL_CALL OPropertySet::acquire() throw ()
+// {
+// OWeakObject::acquire();
+// }
+
+// void SAL_CALL OPropertySet::release() throw ()
+// {
+// OWeakObject::release();
+// }
+
+
+// ____ XServiceInfo ____
+// OUString SAL_CALL
+// OPropertySet::getImplementationName()
+// throw (uno::RuntimeException)
+// {
+// return OUString( RTL_CONSTASCII_USTRINGPARAM( "property::OPropertySet" ));
+// }
+
+// sal_Bool SAL_CALL
+// OPropertySet::supportsService( const OUString& ServiceName )
+// throw (uno::RuntimeException)
+// {
+// return ( 0 == ServiceName.reverseCompareToAsciiL(
+// RTL_CONSTASCII_STRINGPARAM( "com.sun.star.beans.PropertySet" )));
+// }
+
+// Sequence< OUString > SAL_CALL
+// OPropertySet::getSupportedServiceNames()
+// throw (uno::RuntimeException)
+// {
+// Sequence< OUString > aServiceNames( 1 );
+// aServiceNames[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.PropertySet" ));
+// return aServiceNames;
+// }
+
+#define LCL_PROP_CPPUTYPE(t) (::getCppuType( reinterpret_cast< const Reference<t> *>(0)))
+
+// // ____ XTypeProvider ____
+Sequence< uno::Type > SAL_CALL
+ OPropertySet::getTypes()
+ throw (uno::RuntimeException)
+{
+ static Sequence< uno::Type > aTypeList;
+
+ // /--
+ MutexGuard aGuard( m_rMutex );
+
+ if( aTypeList.getLength() == 0 )
+ {
+ ::std::vector< uno::Type > aTypes;
+
+// aTypes.push_back( LCL_PROP_CPPUTYPE( uno::XWeak ));
+// aTypes.push_back( LCL_PROP_CPPUTYPE( lang::XServiceInfo ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( lang::XTypeProvider ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertySet ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertySet ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XFastPropertySet ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertyState ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertyStates ));
+ aTypes.push_back( LCL_PROP_CPPUTYPE( XStyleSupplier ));
+// aTypes.push_back( LCL_PROP_CPPUTYPE( XFastPropertyState ));
+
+ aTypeList = ::chart::ContainerHelper::ContainerToSequence( aTypes );
+ }
+
+ return aTypeList;
+ // \--
+}
+
+Sequence< sal_Int8 > SAL_CALL
+ OPropertySet::getImplementationId()
+ throw (uno::RuntimeException)
+{
+ static uno::Sequence< sal_Int8 > aId;
+ if( aId.getLength() == 0 )
+ {
+ aId.realloc( 16 );
+ rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
+ }
+ return aId;
+}
+
+
+// ____ XPropertyState ____
+beans::PropertyState SAL_CALL
+ OPropertySet::getPropertyState( const OUString& PropertyName )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+
+ return m_pImplProperties->GetPropertyStateByHandle(
+ rPH.getHandleByName( PropertyName ));
+}
+
+Sequence< beans::PropertyState > SAL_CALL
+ OPropertySet::getPropertyStates( const Sequence< OUString >& aPropertyName )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+
+ sal_Int32 * pHandles = new sal_Int32[ aPropertyName.getLength() ];
+ rPH.fillHandles( pHandles, aPropertyName );
+
+ ::std::vector< sal_Int32 > aHandles( pHandles, pHandles + aPropertyName.getLength());
+ delete[] pHandles;
+
+ return m_pImplProperties->GetPropertyStatesByHandle( aHandles );
+}
+
+void SAL_CALL
+ OPropertySet::setPropertyToDefault( const OUString& PropertyName )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+
+ m_pImplProperties->SetPropertyToDefault( rPH.getHandleByName( PropertyName ));
+ firePropertyChangeEvent();
+}
+
+Any SAL_CALL
+ OPropertySet::getPropertyDefault( const OUString& aPropertyName )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+
+ return GetDefaultValue( rPH.getHandleByName( aPropertyName ) );
+}
+
+
+// ____ XMultiPropertyStates ____
+
+// Note: getPropertyStates() is already implemented in XPropertyState with the
+// same signature
+
+void SAL_CALL
+ OPropertySet::setAllPropertiesToDefault()
+ throw (uno::RuntimeException)
+{
+ m_pImplProperties->SetAllPropertiesToDefault();
+ firePropertyChangeEvent();
+}
+
+void SAL_CALL
+ OPropertySet::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+
+ sal_Int32 * pHandles = new sal_Int32[ aPropertyNames.getLength() ];
+ rPH.fillHandles( pHandles, aPropertyNames );
+
+ ::std::vector< sal_Int32 > aHandles( pHandles, pHandles + aPropertyNames.getLength());
+ delete[] pHandles;
+
+ m_pImplProperties->SetPropertiesToDefault( aHandles );
+}
+
+Sequence< Any > SAL_CALL
+ OPropertySet::getPropertyDefaults( const Sequence< OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ::cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+ const sal_Int32 nElements = aPropertyNames.getLength();
+
+ Sequence< Any > aResult( nElements );
+ Any * pResultArray = aResult.getArray();
+ sal_Int32 nI = 0;
+
+ for( ; nI < nElements; ++nI )
+ {
+ pResultArray[ nI ] = GetDefaultValue(
+ rPH.getHandleByName( aPropertyNames[ nI ] ));
+ }
+
+ return aResult;
+}
+
+sal_Bool SAL_CALL OPropertySet::convertFastPropertyValue
+ ( Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue )
+ throw (lang::IllegalArgumentException)
+{
+ getFastPropertyValue( rOldValue, nHandle );
+ //accept longs also for short values
+ {
+ sal_Int16 nValue;
+ if( (rOldValue>>=nValue) && !(rValue>>=nValue) )
+ {
+ sal_Int32 n32Value = 0;
+ if( rValue>>=n32Value )
+ {
+ rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n32Value) );
+ return sal_True;
+ }
+
+ sal_Int64 n64Value = 0;
+ if( rValue>>=n64Value )
+ {
+ rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n64Value) );
+ return sal_True;
+ }
+ }
+ }
+ rConvertedValue = rValue;
+ if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && rOldValue == rConvertedValue )
+ return sal_False;//no change necessary
+ return sal_True;
+}
+
+void SAL_CALL OPropertySet::setFastPropertyValue_NoBroadcast
+ ( sal_Int32 nHandle,
+ const Any& rValue )
+ throw (uno::Exception)
+{
+#if OSL_DEBUG_LEVEL > 0
+ if( rValue.hasValue())
+ {
+ cppu::IPropertyArrayHelper & rPH = getInfoHelper();
+ OUString aName;
+ rPH.fillPropertyMembersByHandle( &aName, 0, nHandle );
+ OSL_ENSURE( rValue.isExtractableTo( rPH.getPropertyByName( aName ).Type ),
+ "Property type is wrong" );
+ }
+#endif
+
+ Any aDefault;
+ try
+ {
+ aDefault = GetDefaultValue( nHandle );
+ }
+ catch( beans::UnknownPropertyException ex )
+ {
+ aDefault.clear();
+ }
+ m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
+ if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && aDefault.hasValue() && aDefault == rValue ) //#i98893# don't export defaults to file
+ m_pImplProperties->SetPropertyToDefault( nHandle );
+ else
+ m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
+}
+
+void SAL_CALL OPropertySet::getFastPropertyValue
+ ( Any& rValue,
+ sal_Int32 nHandle ) const
+{
+ if( ! m_pImplProperties->GetPropertyValueByHandle( rValue, nHandle ))
+ {
+// OSL_TRACE( "OPropertySet: asking style for property" );
+ // property was not set -> try style
+ uno::Reference< beans::XFastPropertySet > xStylePropSet( m_pImplProperties->GetStyle(), uno::UNO_QUERY );
+ if( xStylePropSet.is() )
+ {
+#ifdef DBG_UTIL
+ {
+ // check if the handle of the style points to the same property
+ // name as the handle in this property set
+ uno::Reference< beans::XPropertySet > xPropSet( xStylePropSet, uno::UNO_QUERY );
+ if( xPropSet.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo(),
+ uno::UNO_QUERY );
+ if( xInfo.is() )
+ {
+ // for some reason the virtual method getInfoHelper() is
+ // not const
+ ::cppu::IPropertyArrayHelper & rPH =
+ const_cast< OPropertySet * >( this )->getInfoHelper();
+
+ // find the Property with Handle nHandle in Style
+ Sequence< beans::Property > aProps( xInfo->getProperties() );
+ sal_Int32 nI = aProps.getLength() - 1;
+ while( ( nI >= 0 ) && nHandle != aProps[ nI ].Handle )
+ --nI;
+
+ if( nI >= 0 ) // => nHandle == aProps[nI].Handle
+ {
+ // check whether the handle in this property set is
+ // the same as the one in the style
+ beans::Property aProp( rPH.getPropertyByName( aProps[ nI ].Name ) );
+ OSL_ENSURE( nHandle == aProp.Handle,
+ "HandleCheck: Handles for same property differ!" );
+
+ if( nHandle == aProp.Handle )
+ {
+ OSL_ENSURE( aProp.Type == aProps[nI].Type,
+ "HandleCheck: Types differ!" );
+ OSL_ENSURE( aProp.Attributes == aProps[nI].Attributes,
+ "HandleCheck: Attributes differ!" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE( false, "HandleCheck: Handle not found in Style" );
+ }
+ }
+ else
+ OSL_ENSURE( false, "HandleCheck: Invalid XPropertySetInfo returned" );
+ }
+ else
+ OSL_ENSURE( false, "HandleCheck: XPropertySet not supported" );
+ }
+#endif
+ rValue = xStylePropSet->getFastPropertyValue( nHandle );
+ }
+ else
+ {
+// OSL_TRACE( "OPropertySet: no style => getting default for property" );
+ // there is no style (or the style does not support XFastPropertySet)
+ // => take the default value
+ try
+ {
+ rValue = GetDefaultValue( nHandle );
+ }
+ catch( beans::UnknownPropertyException ex )
+ {
+ rValue.clear();
+ }
+ }
+ }
+}
+
+void OPropertySet::firePropertyChangeEvent()
+{
+ // nothing in base class
+}
+
+// ____ XStyleSupplier ____
+Reference< style::XStyle > SAL_CALL OPropertySet::getStyle()
+ throw (uno::RuntimeException)
+{
+ return m_pImplProperties->GetStyle();
+}
+
+void SAL_CALL OPropertySet::setStyle( const Reference< style::XStyle >& xStyle )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( ! m_pImplProperties->SetStyle( xStyle ))
+ throw lang::IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty Style" )),
+ static_cast< beans::XPropertySet * >( this ),
+ 0 );
+}
+
+// ____ XFastPropertyState ____
+// beans::PropertyState OPropertySet::SAL_CALL getFastPropertyState( sal_Int32 nHandle )
+// throw (beans::UnknownPropertyException,
+// uno::RuntimeException)
+// {
+// return m_pImplProperties->GetPropertyStateByHandle( nHandle );
+// }
+
+// uno::Sequence< beans::PropertyState > OPropertySet::SAL_CALL getFastPropertyStates(
+// const uno::Sequence< sal_Int32 >& aHandles )
+// throw (beans::UnknownPropertyException,
+// uno::RuntimeException)
+// {
+// ::std::vector< sal_Int32 > aHandleVec(
+// aHandles.getConstArray(),
+// aHandles.getConstArray() + aHandles.getLength() );
+
+// return m_pImplProperties->GetPropertyStatesByHandle( aHandleVec );
+// }
+
+// void OPropertySet::SAL_CALL setFastPropertyToDefault( sal_Int32 nHandle )
+// throw (beans::UnknownPropertyException,
+// uno::RuntimeException)
+// {
+// m_pImplProperties->SetPropertyToDefault( nHandle );
+// }
+
+// uno::Any OPropertySet::SAL_CALL getFastPropertyDefault( sal_Int32 nHandle )
+// throw (beans::UnknownPropertyException,
+// lang::WrappedTargetException,
+// uno::RuntimeException)
+// {
+// return GetDefaultValue( nHandle );
+// }
+
+// ____ XMultiPropertySet ____
+void SAL_CALL OPropertySet::setPropertyValues(
+ const Sequence< OUString >& PropertyNames, const Sequence< Any >& Values )
+ throw(beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ::cppu::OPropertySetHelper::setPropertyValues( PropertyNames, Values );
+
+ firePropertyChangeEvent();
+}
+
+// ____ XFastPropertySet ____
+void SAL_CALL OPropertySet::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
+ throw(beans::UnknownPropertyException,
+ beans::PropertyVetoException,
+ lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ ::cppu::OPropertySetHelper::setFastPropertyValue( nHandle, rValue );
+
+ firePropertyChangeEvent();
+}
+
+
+} // namespace property
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx
new file mode 100644
index 000000000000..0599f9317aed
--- /dev/null
+++ b/chart2/source/tools/ObjectIdentifier.cxx
@@ -0,0 +1,1491 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ObjectIdentifier.hxx"
+#include "macros.hxx"
+#include "TitleHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "AxisHelper.hxx"
+#include "servicenames_charttypes.hxx"
+#include "DiagramHelper.hxx"
+#include "AxisIndexDefines.hxx"
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XAxis.hpp>
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+
+// header for define DBG_ASSERT
+#include <tools/debug.hxx>
+#include <comphelper/InlineContainer.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+
+static OUString m_aMultiClick( C2U("MultiClick") );
+static OUString m_aDragMethodEquals( C2U("DragMethod=") );
+static OUString m_aDragParameterEquals( C2U("DragParameter=") );
+static OUString m_aProtocol( C2U("CID/") );
+static OUString m_aEmptyString;
+static OUString m_aPieSegmentDragMethodServiceName( C2U("PieSegmentDraging") );
+
+namespace
+{
+
+OUString lcl_createClassificationStringForType( ObjectType eObjectType
+ , const OUString& rDragMethodServiceName
+ , const OUString& rDragParameterString
+ )
+{
+ OUStringBuffer aRet;
+ switch( eObjectType )
+ {
+ //these object types are all selected only after their parents was selected before
+ case OBJECTTYPE_LEGEND_ENTRY: //parent is intended to be OBJECTTYPE_LEGEND
+ case OBJECTTYPE_DATA_POINT: //parent is intended to be OBJECTTYPE_DATA_SERIES
+ case OBJECTTYPE_DATA_LABEL: //parent is intended to be OBJECTTYPE_DATA_LABELS
+ case OBJECTTYPE_DATA_ERRORS_X: //parent is intended to be OBJECTTYPE_DATA_ERRORS
+ case OBJECTTYPE_DATA_ERRORS_Y: //parent is intended to be OBJECTTYPE_DATA_ERRORS
+ case OBJECTTYPE_DATA_ERRORS_Z: //parent is intended to be OBJECTTYPE_DATA_ERRORS
+ aRet=m_aMultiClick;
+ default:
+ ;//empty string
+ }
+ if( rDragMethodServiceName.getLength() )
+ {
+ if( aRet.getLength() )
+ aRet.appendAscii(":");
+ aRet.append( m_aDragMethodEquals );
+ aRet.append( rDragMethodServiceName );
+
+ if( rDragParameterString.getLength() )
+ {
+ if( aRet.getLength() )
+ aRet.appendAscii(":");
+ aRet.append( m_aDragParameterEquals );
+ aRet.append( rDragParameterString );
+ }
+ }
+ return aRet.makeStringAndClear();
+}
+
+typedef ::comphelper::MakeMap< TitleHelper::eTitleType, OUString > tTitleMap;
+const tTitleMap& lcl_getTitleMap()
+{
+ //maps the title type to the ParentParticle for that title
+ static tTitleMap m_aTitleMap = tTitleMap
+ ( TitleHelper::MAIN_TITLE, C2U("") )
+ ( TitleHelper::SUB_TITLE, C2U("D=0") )
+ ( TitleHelper::X_AXIS_TITLE, C2U("D=0:CS=0:Axis=0,0") )
+ ( TitleHelper::Y_AXIS_TITLE, C2U("D=0:CS=0:Axis=1,0") )
+ ( TitleHelper::Z_AXIS_TITLE, C2U("D=0:CS=0:Axis=2,0") )
+ ( TitleHelper::SECONDARY_X_AXIS_TITLE, C2U("D=0:CS=0:Axis=0,1") )
+ ( TitleHelper::SECONDARY_Y_AXIS_TITLE, C2U("D=0:CS=0:Axis=1,1") )
+ ;
+ return m_aTitleMap;
+}
+
+OUString lcl_getTitleParentParticle( TitleHelper::eTitleType aTitleType )
+{
+ OUString aRet;
+
+ const tTitleMap& rMap = lcl_getTitleMap();
+ tTitleMap::const_iterator aIt( rMap.find( aTitleType ) );
+ if( aIt != rMap.end())
+ aRet = (*aIt).second;
+
+ return aRet;
+}
+
+Reference<XChartType> lcl_getFirstStockChartType( const Reference< frame::XModel >& xChartModel )
+{
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ if(!xDiagram.is())
+ return 0;
+
+ //iterate through all coordinate systems
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( !xCooSysContainer.is())
+ return 0;
+
+ uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
+ {
+ //iterate through all chart types in the current coordinate system
+ Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
+ if( !xChartTypeContainer.is() )
+ continue;
+
+ uno::Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
+ for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
+ {
+ Reference< XChartType > xChartType( aChartTypeList[nT] );
+ if(!xChartType.is())
+ continue;
+ OUString aChartType = xChartType->getChartType();
+ if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ return xChartType;
+ }
+ }
+ return 0;
+}
+
+OUString lcl_getIndexStringAfterString( const OUString& rString, const OUString& rSearchString )
+{
+ OUStringBuffer aRet;
+
+ sal_Int32 nIndexStart = rString.lastIndexOf( rSearchString );
+ if( nIndexStart != -1 )
+ {
+ nIndexStart += rSearchString.getLength();
+ sal_Int32 nIndexEnd = rString.getLength();
+ sal_Int32 nNextColon = rString.indexOf( ':', nIndexStart );
+ if( nNextColon != -1 )
+ nIndexEnd = nNextColon;
+ aRet = rString.copy(nIndexStart,nIndexEnd-nIndexStart);
+ }
+
+ return aRet.makeStringAndClear();
+}
+
+sal_Int32 lcl_StringToIndex( const OUString& rIndexString )
+{
+ sal_Int32 nRet = -1;
+ if( rIndexString.getLength() )
+ {
+ nRet = rIndexString.toInt32();
+ if( nRet < -1 )
+ nRet = -1;
+ }
+ return nRet;
+}
+
+void lcl_parseCooSysIndices( sal_Int32& rnDiagram, sal_Int32& rnCooSys, const OUString& rString )
+{
+ rnDiagram = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U("D=") ) );
+ rnCooSys = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U("CS=") ) );
+}
+
+void lcl_parseAxisIndices( sal_Int32& rnDimensionIndex, sal_Int32& rnAxisIndex, const OUString& rString )
+{
+ OUString aAxisIndexString = lcl_getIndexStringAfterString( rString, C2U(":Axis=") );
+ sal_Int32 nCharacterIndex=0;
+ rnDimensionIndex = lcl_StringToIndex( aAxisIndexString.getToken( 0, ',', nCharacterIndex ) );
+ rnAxisIndex = lcl_StringToIndex( aAxisIndexString.getToken( 0, ',', nCharacterIndex ) );
+}
+
+void lcl_parseGridIndices( sal_Int32& rnSubGridIndex, const OUString& rString )
+{
+ rnSubGridIndex = -1;
+ rnSubGridIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U(":SubGrid=") ) );
+}
+
+void lcl_parseSeriesIndices( sal_Int32& rnChartTypeIndex, sal_Int32& rnSeriesIndex, sal_Int32& rnPointIndex, const OUString& rString )
+{
+ rnChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U("CT=") ) );
+ rnSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U("Series=") ) );
+ rnPointIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, C2U("Point=") ) );
+}
+
+void lcl_getDiagramAndCooSys( const OUString& rObjectCID
+ , const Reference< frame::XModel >& xChartModel
+ , Reference< XDiagram >& xDiagram
+ , Reference< XCoordinateSystem >& xCooSys )
+{
+ sal_Int32 nDiagramIndex = -1;
+ sal_Int32 nCooSysIndex = -1;
+ lcl_parseCooSysIndices( nDiagramIndex, nCooSysIndex, rObjectCID );
+ xDiagram = ChartModelHelper::findDiagram( xChartModel );//todo use nDiagramIndex when more than one diagram is possible in future
+ if( !xDiagram.is() )
+ return;
+
+ if( nCooSysIndex > -1 )
+ {
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( xCooSysContainer.is() )
+ {
+ uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ if( nCooSysIndex < aCooSysList.getLength() )
+ xCooSys = aCooSysList[nCooSysIndex];
+ }
+ }
+}
+
+} //anonymous namespace
+
+ObjectIdentifier::ObjectIdentifier()
+ :m_aObjectCID( OUString() )
+ ,m_xAdditionalShape( 0 )
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const OUString& rObjectCID )
+ :m_aObjectCID( rObjectCID )
+ ,m_xAdditionalShape( 0 )
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const Reference< drawing::XShape >& rxShape )
+ :m_aObjectCID( OUString() )
+ ,m_xAdditionalShape( rxShape )
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const Any& rAny )
+ :m_aObjectCID( OUString() )
+ ,m_xAdditionalShape( 0 )
+{
+ const uno::Type& rType = rAny.getValueType();
+ if ( rType == ::getCppuType( static_cast< const OUString* >( 0 ) ) )
+ {
+ rAny >>= m_aObjectCID;
+ }
+ else if ( rType == ::getCppuType( static_cast< const Reference< drawing::XShape >* >( 0 ) ) )
+ {
+ rAny >>= m_xAdditionalShape;
+ }
+}
+
+ObjectIdentifier::~ObjectIdentifier()
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const ObjectIdentifier& rOID )
+ :m_aObjectCID( rOID.m_aObjectCID )
+ ,m_xAdditionalShape( rOID.m_xAdditionalShape )
+{
+
+}
+
+ObjectIdentifier& ObjectIdentifier::operator=( const ObjectIdentifier& rOID )
+{
+ m_aObjectCID = rOID.m_aObjectCID;
+ m_xAdditionalShape = rOID.m_xAdditionalShape;
+ return *this;
+}
+
+bool ObjectIdentifier::operator==( const ObjectIdentifier& rOID ) const
+{
+ if ( areIdenticalObjects( m_aObjectCID, rOID.m_aObjectCID ) &&
+ ( m_xAdditionalShape == rOID.m_xAdditionalShape ) )
+ {
+ return true;
+ }
+ return false;
+}
+
+bool ObjectIdentifier::operator!=( const ObjectIdentifier& rOID ) const
+{
+ return !operator==( rOID );
+}
+
+bool ObjectIdentifier::operator<( const ObjectIdentifier& rOID ) const
+{
+ bool bReturn = false;
+ if ( m_aObjectCID.getLength() && rOID.m_aObjectCID.getLength() )
+ {
+ bReturn = ( m_aObjectCID.compareTo( rOID.m_aObjectCID ) < 0 );
+ }
+ else if ( m_aObjectCID.getLength() )
+ {
+ bReturn = true;
+ }
+ else if ( rOID.m_aObjectCID.getLength() )
+ {
+ bReturn = false;
+ }
+ else if ( m_xAdditionalShape.is() && rOID.m_xAdditionalShape.is() )
+ {
+ bReturn = ( m_xAdditionalShape < rOID.m_xAdditionalShape );
+ }
+ return bReturn;
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifierForObject(
+ const Reference< uno::XInterface >& xObject
+ , const Reference< frame::XModel >& xChartModel )
+{
+ OUString aRet;
+
+ enum ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
+ OUString aObjectID;
+ OUString aParentParticle;
+ OUString aDragMethodServiceName;
+ OUString aDragParameterString;
+
+
+ try
+ {
+ //title
+ Reference< XTitle > xTitle( xObject, uno::UNO_QUERY );
+ if( xTitle.is() )
+ {
+ TitleHelper::eTitleType aTitleType;
+ if( TitleHelper::getTitleType( aTitleType, xTitle, xChartModel ) )
+ {
+ eObjectType = OBJECTTYPE_TITLE;
+ aParentParticle = lcl_getTitleParentParticle( aTitleType );
+ aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
+ eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
+ }
+ return aRet;
+
+ }
+
+ //axis
+ Reference< XAxis > xAxis( xObject, uno::UNO_QUERY );
+ if( xAxis.is() )
+ {
+ Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, ChartModelHelper::findDiagram( xChartModel ) ) );
+ rtl::OUString aCooSysParticle( createParticleForCoordinateSystem( xCooSys, xChartModel ) );
+ sal_Int32 nDimensionIndex=-1;
+ sal_Int32 nAxisIndex=-1;
+ AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
+ rtl::OUString aAxisParticle( createParticleForAxis( nDimensionIndex, nAxisIndex ) );
+ return createClassifiedIdentifierForParticles( aCooSysParticle, aAxisParticle );
+ }
+
+ //legend
+ Reference< XLegend > xLegend( xObject, uno::UNO_QUERY );
+ if( xLegend.is() )
+ {
+ return createClassifiedIdentifierForParticle( createParticleForLegend( xLegend, xChartModel ) );
+ }
+
+ //diagram
+ Reference< XDiagram > xDiagram( xObject, uno::UNO_QUERY );
+ if( xDiagram.is() )
+ {
+ return createClassifiedIdentifierForParticle( createParticleForDiagram( xDiagram, xChartModel ) );
+ }
+
+ //todo
+ //XDataSeries
+ //CooSys
+ //charttype
+ //datapoint?
+ //Gridproperties
+ }
+ catch( uno::Exception& ex)
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ if( eObjectType != OBJECTTYPE_UNKNOWN )
+ {
+ aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
+ eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
+ }
+ else
+ {
+ DBG_ASSERT(false,"give object could not be identifed in createClassifiedIdentifierForObject");
+ }
+
+ return aRet;
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifierForParticle(
+ const OUString& rParticle )
+{
+ return ObjectIdentifier::createClassifiedIdentifierForParticles( rParticle, OUString() );
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifierForParticles(
+ const OUString& rParentParticle
+ , const OUString& rChildParticle
+ , const OUString& rDragMethodServiceName
+ , const OUString& rDragParameterString )
+{
+ ObjectType eObjectType( ObjectIdentifier::getObjectType( rChildParticle ) );
+ if( eObjectType == OBJECTTYPE_UNKNOWN )
+ eObjectType = ObjectIdentifier::getObjectType( rParentParticle );
+
+ OUStringBuffer aRet( m_aProtocol );
+ aRet.append( lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
+ if(aRet.getLength()>m_aProtocol.getLength())
+ aRet.appendAscii("/");
+
+ if(rParentParticle.getLength())
+ {
+ aRet.append(rParentParticle);
+ if( rChildParticle.getLength() )
+ aRet.appendAscii(":");
+ }
+ aRet.append(rChildParticle);
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createParticleForDiagram(
+ const Reference< XDiagram >& /*xDiagram*/
+ , const Reference< frame::XModel >& /*xChartModel*/ )
+{
+ static OUString aRet(C2U("D=0"));
+ //todo: if more than one diagram is implemeted, add the correct diagram index here
+ return aRet;
+}
+
+//static
+OUString ObjectIdentifier::createParticleForCoordinateSystem(
+ const Reference< XCoordinateSystem >& xCooSys
+ , const Reference< frame::XModel >& xChartModel )
+{
+ OUStringBuffer aRet;
+
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
+ if( xCooSysContainer.is() )
+ {
+ sal_Int32 nCooSysIndex = 0;
+ uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
+ for( ; nCooSysIndex < aCooSysList.getLength(); ++nCooSysIndex )
+ {
+ Reference< XCoordinateSystem > xCurrentCooSys( aCooSysList[nCooSysIndex] );
+ if( xCooSys == xCurrentCooSys )
+ {
+ aRet = ObjectIdentifier::createParticleForDiagram( xDiagram, xChartModel );
+ aRet.appendAscii(":CS=");
+ aRet.append( OUString::valueOf( nCooSysIndex ) );
+ break;
+ }
+ }
+ }
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createParticleForAxis(
+ sal_Int32 nDimensionIndex
+ , sal_Int32 nAxisIndex )
+{
+ OUStringBuffer aRet(C2U("Axis="));
+
+ aRet.append( OUString::valueOf( nDimensionIndex ) );
+ aRet.appendAscii(",");
+ aRet.append( OUString::valueOf( nAxisIndex ) );
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createParticleForGrid(
+ sal_Int32 nDimensionIndex
+ , sal_Int32 nAxisIndex )
+{
+ OUStringBuffer aRet(C2U("Axis="));
+ aRet.append( OUString::valueOf( nDimensionIndex ) );
+ aRet.appendAscii(",");
+ aRet.append( OUString::valueOf( nAxisIndex ) );
+ aRet.append( C2U(":Grid=0") );
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifierForGrid(
+ const Reference< XAxis >& xAxis
+ , const Reference< frame::XModel >& xChartModel
+ , sal_Int32 nSubGridIndex )
+{
+ //-1: main grid, 0: first subgrid etc
+
+ rtl::OUString aAxisCID( createClassifiedIdentifierForObject( xAxis, xChartModel ) );
+ rtl::OUString aGridCID( addChildParticle( aAxisCID
+ , createChildParticleWithIndex( OBJECTTYPE_GRID, 0 ) ) );
+ if( nSubGridIndex >= 0 )
+ {
+ aGridCID = addChildParticle( aGridCID
+ , createChildParticleWithIndex( OBJECTTYPE_SUBGRID, 0 ) );
+ }
+ return aGridCID;
+}
+
+//static
+OUString ObjectIdentifier::createParticleForSeries(
+ sal_Int32 nDiagramIndex, sal_Int32 nCooSysIndex
+ , sal_Int32 nChartTypeIndex, sal_Int32 nSeriesIndex )
+{
+ OUStringBuffer aRet;
+
+ aRet.appendAscii("D=");
+ aRet.append( OUString::valueOf( nDiagramIndex ) );
+ aRet.appendAscii(":CS=");
+ aRet.append( OUString::valueOf( nCooSysIndex ) );
+ aRet.appendAscii(":CT=");
+ aRet.append( OUString::valueOf( nChartTypeIndex ) );
+ aRet.appendAscii(":");
+ aRet.append(getStringForType( OBJECTTYPE_DATA_SERIES ));
+ aRet.appendAscii("=");
+ aRet.append( OUString::valueOf( nSeriesIndex ) );
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createParticleForLegend(
+ const Reference< XLegend >& /*xLegend*/
+ , const Reference< frame::XModel >& xChartModel )
+{
+ OUStringBuffer aRet;
+
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
+ //todo: if more than one diagram is implemeted, find the correct diagram wich is owner of the given legend
+
+ aRet.append( ObjectIdentifier::createParticleForDiagram( xDiagram, xChartModel ) );
+ aRet.appendAscii(":");
+ aRet.append(getStringForType( OBJECTTYPE_LEGEND ));
+ aRet.appendAscii("=");
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifier(
+ enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_SERIES
+ , const OUString& rParticleID )//e.g. SeriesID
+{
+ return createClassifiedIdentifierWithParent(
+ eObjectType, rParticleID, m_aEmptyString );
+}
+
+//static
+OUString ObjectIdentifier::createClassifiedIdentifierWithParent(
+ enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_POINT or OBJECTTYPE_GRID
+ , const OUString& rParticleID //e.g. Point Index or SubGrid Index
+ , const OUString& rParentPartical //e.g. "Series=SeriesID" or "Grid=GridId"
+ , const OUString& rDragMethodServiceName
+ , const OUString& rDragParameterString
+ )
+ //, bool bIsMultiClickObject ) //e.g. true
+{
+ //e.g. "MultiClick/Series=2:Point=34"
+
+ OUStringBuffer aRet( m_aProtocol );
+ aRet.append( lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
+ if(aRet.getLength()>m_aProtocol.getLength())
+ aRet.appendAscii("/");
+ aRet.append(rParentPartical);
+ if(rParentPartical.getLength())
+ aRet.appendAscii(":");
+
+ aRet.append(getStringForType( eObjectType ));
+ aRet.appendAscii("=");
+ aRet.append(rParticleID);
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+const OUString& ObjectIdentifier::getPieSegmentDragMethodServiceName()
+{
+ return m_aPieSegmentDragMethodServiceName;
+}
+
+//static
+OUString ObjectIdentifier::createPieSegmentDragParameterString(
+ sal_Int32 nOffsetPercent
+ , const awt::Point& rMinimumPosition
+ , const awt::Point& rMaximumPosition )
+{
+ OUStringBuffer aRet( OUString::valueOf( nOffsetPercent ) );
+ aRet.append( sal_Unicode( ',' ));
+ aRet.append( OUString::valueOf( rMinimumPosition.X ) );
+ aRet.append( sal_Unicode( ',' ));
+ aRet.append( OUString::valueOf( rMinimumPosition.Y ) );
+ aRet.append( sal_Unicode( ',' ));
+ aRet.append( OUString::valueOf( rMaximumPosition.X ) );
+ aRet.append( sal_Unicode( ',' ));
+ aRet.append( OUString::valueOf( rMaximumPosition.Y ) );
+ return aRet.makeStringAndClear();
+}
+
+//static
+bool ObjectIdentifier::parsePieSegmentDragParameterString(
+ const OUString& rDragParameterString
+ , sal_Int32& rOffsetPercent
+ , awt::Point& rMinimumPosition
+ , awt::Point& rMaximumPosition )
+{
+ OUString aValue;
+ sal_Int32 nCharacterIndex = 0;
+
+ OUString aValueString( rDragParameterString.getToken( 0, ',', nCharacterIndex ) );
+ rOffsetPercent = aValueString.toInt32();
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
+ rMinimumPosition.X = aValueString.toInt32();
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
+ rMinimumPosition.Y = aValueString.toInt32();
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
+ rMaximumPosition.X = aValueString.toInt32();
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
+ rMaximumPosition.Y = aValueString.toInt32();
+ if( nCharacterIndex < 0 )
+ return false;
+
+ return true;
+}
+
+//static
+OUString ObjectIdentifier::getDragMethodServiceName( const OUString& rCID )
+{
+ OUString aRet;
+
+ sal_Int32 nIndexStart = rCID.indexOf( m_aDragMethodEquals );
+ if( nIndexStart != -1 )
+ {
+ nIndexStart = rCID.indexOf( '=', nIndexStart );
+ if( nIndexStart != -1 )
+ {
+ nIndexStart++;
+ sal_Int32 nNextSlash = rCID.indexOf( '/', nIndexStart );
+ if( nNextSlash != -1 )
+ {
+ sal_Int32 nIndexEnd = nNextSlash;
+ sal_Int32 nNextColon = rCID.indexOf( ':', nIndexStart );
+ if( nNextColon < nNextSlash )
+ nIndexEnd = nNextColon;
+ aRet = rCID.copy(nIndexStart,nIndexEnd-nIndexStart);
+ }
+ }
+ }
+ return aRet;
+}
+
+//static
+OUString ObjectIdentifier::getDragParameterString( const OUString& rCID )
+{
+ OUString aRet;
+
+ sal_Int32 nIndexStart = rCID.indexOf( m_aDragParameterEquals );
+ if( nIndexStart != -1 )
+ {
+ nIndexStart = rCID.indexOf( '=', nIndexStart );
+ if( nIndexStart != -1 )
+ {
+ nIndexStart++;
+ sal_Int32 nNextSlash = rCID.indexOf( '/', nIndexStart );
+ if( nNextSlash != -1 )
+ {
+ sal_Int32 nIndexEnd = nNextSlash;
+ sal_Int32 nNextColon = rCID.indexOf( ':', nIndexStart );
+ if( nNextColon < nNextSlash )
+ nIndexEnd = nNextColon;
+ aRet = rCID.copy(nIndexStart,nIndexEnd-nIndexStart);
+ }
+ }
+ }
+ return aRet;
+}
+
+//static
+bool ObjectIdentifier::isDragableObject( const OUString& rClassifiedIdentifier )
+{
+ ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier );
+ switch( eObjectType )
+ {
+ case OBJECTTYPE_TITLE:
+ case OBJECTTYPE_LEGEND:
+ case OBJECTTYPE_DIAGRAM:
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ //case OBJECTTYPE_DIAGRAM_WALL:
+ return true;
+ default:
+ OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) );
+ if( aDragMethodServiceName.getLength() )
+ return true;
+ return false;
+ }
+ return false;
+}
+
+bool ObjectIdentifier::isDragableObject()
+{
+ bool bReturn = false;
+ if ( isAutoGeneratedObject() )
+ {
+ bReturn = isDragableObject( m_aObjectCID );
+ }
+ else if ( isAdditionalShape() )
+ {
+ bReturn = true;
+ }
+ return bReturn;
+}
+
+//static
+bool ObjectIdentifier::isRotateableObject( const OUString& rClassifiedIdentifier )
+{
+ ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier );
+ switch( eObjectType )
+ {
+ case OBJECTTYPE_DIAGRAM:
+ //case OBJECTTYPE_DIAGRAM_WALL:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+//static
+bool ObjectIdentifier::isMultiClickObject( const OUString& rClassifiedIdentifier )
+{
+ //the name of a shape is it's ClassifiedIdentifier
+
+ //a MultiClickObject is an object that is selectable by more than one click only ;
+ //before a MultiClickObject can be selected it is necessary that a named parent group object
+ //was selected before;
+
+ //!!!!! by definition the name of a MultiClickObject starts with "CID/MultiClick:"
+ bool bRet = false;
+ bRet = rClassifiedIdentifier.match( m_aMultiClick, m_aProtocol.getLength() );
+ return bRet;
+}
+
+bool ObjectIdentifier::areSiblings( const OUString& rCID1, const OUString& rCID2 )
+{
+ bool bRet=false;
+ sal_Int32 nLastSign1 = rCID1.lastIndexOf( '=' );
+ sal_Int32 nLastSign2 = rCID2.lastIndexOf( '=' );
+ if( nLastSign1 == rCID1.indexOf( '=' ) )//CID cannot be sibling if only one "=" occurs
+ bRet=false;
+ else if( nLastSign2 == rCID2.indexOf( '=' ) )//CID cannot be sibling if only one "=" occurs
+ bRet=false;
+ else if( ObjectIdentifier::areIdenticalObjects( rCID1, rCID2 ) )
+ bRet=false;
+ else
+ {
+ OUString aParent1( ObjectIdentifier::getFullParentParticle( rCID1 ) );
+ if( aParent1.getLength() )
+ {
+ OUString aParent2( ObjectIdentifier::getFullParentParticle( rCID2 ) );
+ bRet=aParent1.equals(aParent2);
+ }
+ //legend entries are special:
+ if(!bRet)
+ {
+ if( OBJECTTYPE_LEGEND_ENTRY == getObjectType(rCID1)
+ && OBJECTTYPE_LEGEND_ENTRY == getObjectType(rCID2) )
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+bool ObjectIdentifier::areIdenticalObjects( const OUString& rCID1, const OUString& rCID2 )
+{
+ if( rCID1.equals( rCID2 ) )
+ return true;
+ //draggable pie or donut segments need special treatment, as their CIDs do change with offset
+ {
+ if( rCID1.indexOf( m_aPieSegmentDragMethodServiceName ) < 0
+ || rCID2.indexOf( m_aPieSegmentDragMethodServiceName ) < 0 )
+ return false;
+
+ OUString aID1( ObjectIdentifier::getObjectID( rCID1 ) );
+ OUString aID2( ObjectIdentifier::getObjectID( rCID2 ) );
+ if( aID1.getLength() && aID1.equals( aID2 ) )
+ return true;
+ }
+ return false;
+}
+
+//static
+OUString ObjectIdentifier::getStringForType( ObjectType eObjectType )
+{
+ OUString aRet;
+ switch( eObjectType )
+ {
+ case OBJECTTYPE_PAGE:
+ aRet=C2U("Page");
+ break;
+ case OBJECTTYPE_TITLE:
+ aRet=C2U("Title");
+ break;
+ case OBJECTTYPE_LEGEND:
+ aRet=C2U("Legend");
+ break;
+ case OBJECTTYPE_LEGEND_ENTRY:
+ aRet=C2U("LegendEntry");
+ break;
+ case OBJECTTYPE_DIAGRAM:
+ aRet=C2U("D");
+ break;
+ case OBJECTTYPE_DIAGRAM_WALL:
+ aRet=C2U("DiagramWall");
+ break;
+ case OBJECTTYPE_DIAGRAM_FLOOR:
+ aRet=C2U("DiagramFloor");
+ break;
+ case OBJECTTYPE_AXIS:
+ aRet=C2U("Axis");
+ break;
+ case OBJECTTYPE_AXIS_UNITLABEL:
+ aRet=C2U("AxisUnitLabel");
+ break;
+ case OBJECTTYPE_GRID:
+ aRet=C2U("Grid");
+ break;
+ case OBJECTTYPE_SUBGRID:
+ aRet=C2U("SubGrid");
+ break;
+ case OBJECTTYPE_DATA_SERIES:
+ aRet=C2U("Series");
+ break;
+ case OBJECTTYPE_DATA_POINT:
+ aRet=C2U("Point");
+ break;
+ case OBJECTTYPE_DATA_LABELS:
+ aRet=C2U("DataLabels");
+ break;
+ case OBJECTTYPE_DATA_LABEL:
+ aRet=C2U("DataLabel");
+ break;
+ case OBJECTTYPE_DATA_ERRORS:
+ aRet=C2U("Errors");
+ break;
+ case OBJECTTYPE_DATA_ERRORS_X:
+ aRet=C2U("ErrorsX");
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ aRet=C2U("ErrorsY");
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ aRet=C2U("ErrorsZ");
+ break;
+ case OBJECTTYPE_DATA_CURVE:
+ aRet=C2U("Curve");
+ break;
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ aRet=C2U("Equation");
+ break;
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ aRet=C2U("Average");
+ break;
+ case OBJECTTYPE_DATA_STOCK_RANGE:
+ aRet=C2U("StockRange");
+ break;
+ case OBJECTTYPE_DATA_STOCK_LOSS:
+ aRet=C2U("StockLoss");
+ break;
+ case OBJECTTYPE_DATA_STOCK_GAIN:
+ aRet=C2U("StockGain");
+ break;
+ default: //OBJECTTYPE_UNKNOWN
+ ;
+ }
+ return aRet;
+}
+
+//static
+ObjectType ObjectIdentifier::getObjectType( const OUString& rCID )
+{
+ ObjectType eRet;
+ sal_Int32 nLastSign = rCID.lastIndexOf( ':' );//last sign before the type string
+ if(nLastSign==-1)
+ nLastSign = rCID.lastIndexOf( '/' );
+ if(nLastSign==-1)
+ {
+ sal_Int32 nEndIndex = rCID.lastIndexOf( '=' );
+ if(nEndIndex==-1)
+ return OBJECTTYPE_UNKNOWN;
+ nLastSign = 0;
+ }
+ if( nLastSign>0 )
+ nLastSign++;
+
+ if( rCID.match(C2U("Page"),nLastSign) )
+ eRet = OBJECTTYPE_PAGE;
+ else if( rCID.match(C2U("Title"),nLastSign) )
+ eRet = OBJECTTYPE_TITLE;
+ else if( rCID.match(C2U("LegendEntry"),nLastSign) )
+ eRet = OBJECTTYPE_LEGEND_ENTRY;
+ else if( rCID.match(C2U("Legend"),nLastSign) )
+ eRet = OBJECTTYPE_LEGEND;
+ else if( rCID.match(C2U("DiagramWall"),nLastSign) )
+ eRet = OBJECTTYPE_DIAGRAM_WALL;
+ else if( rCID.match(C2U("DiagramFloor"),nLastSign) )
+ eRet = OBJECTTYPE_DIAGRAM_FLOOR;
+ else if( rCID.match(C2U("D="),nLastSign) )
+ eRet = OBJECTTYPE_DIAGRAM;
+ else if( rCID.match(C2U("AxisUnitLabel"),nLastSign) )
+ eRet = OBJECTTYPE_AXIS_UNITLABEL;
+ else if( rCID.match(C2U("Axis"),nLastSign) )
+ eRet = OBJECTTYPE_AXIS;
+ else if( rCID.match(C2U("Grid"),nLastSign) )
+ eRet = OBJECTTYPE_GRID;
+ else if( rCID.match(C2U("SubGrid"),nLastSign) )
+ eRet = OBJECTTYPE_SUBGRID;
+ else if( rCID.match(C2U("Series"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_SERIES;
+ else if( rCID.match(C2U("Point"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_POINT;
+ else if( rCID.match(C2U("DataLabels"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_LABELS;
+ else if( rCID.match(C2U("DataLabel"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_LABEL;
+ else if( rCID.match(C2U("ErrorsX"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_ERRORS_X;
+ else if( rCID.match(C2U("ErrorsY"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_ERRORS_Y;
+ else if( rCID.match(C2U("ErrorsZ"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_ERRORS_Z;
+ else if( rCID.match(C2U("Errors"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_ERRORS;
+ else if( rCID.match(C2U("Curve"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_CURVE;
+ else if( rCID.match(C2U("Equation"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_CURVE_EQUATION;
+ else if( rCID.match(C2U("Average"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_AVERAGE_LINE;
+ else if( rCID.match(C2U("StockRange"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_STOCK_RANGE;
+ else if( rCID.match(C2U("StockLoss"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_STOCK_LOSS;
+ else if( rCID.match(C2U("StockGain"),nLastSign) )
+ eRet = OBJECTTYPE_DATA_STOCK_GAIN;
+ else
+ eRet = OBJECTTYPE_UNKNOWN;
+
+ return eRet;
+}
+
+ObjectType ObjectIdentifier::getObjectType()
+{
+ ObjectType eObjectType( OBJECTTYPE_UNKNOWN );
+ if ( isAutoGeneratedObject() )
+ {
+ eObjectType = getObjectType( m_aObjectCID );
+ }
+ else if ( isAdditionalShape() )
+ {
+ eObjectType = OBJECTTYPE_SHAPE;
+ }
+ return eObjectType;
+}
+
+//static
+OUString ObjectIdentifier::createDataCurveCID(
+ const OUString& rSeriesParticle
+ , sal_Int32 nCurveIndex
+ , bool bAverageLine )
+{
+ OUString aParticleID( OUString::valueOf( nCurveIndex ) );
+ ObjectType eType = bAverageLine ? OBJECTTYPE_DATA_AVERAGE_LINE : OBJECTTYPE_DATA_CURVE;
+ return createClassifiedIdentifierWithParent( eType, aParticleID, rSeriesParticle );
+}
+
+//static
+OUString ObjectIdentifier::createDataCurveEquationCID(
+ const OUString& rSeriesParticle
+ , sal_Int32 nCurveIndex )
+{
+ OUString aParticleID( OUString::valueOf( nCurveIndex ) );
+ return createClassifiedIdentifierWithParent( OBJECTTYPE_DATA_CURVE_EQUATION, aParticleID, rSeriesParticle );
+}
+
+//static
+OUString ObjectIdentifier::addChildParticle( const rtl::OUString& rParticle, const rtl::OUString& rChildParticle )
+{
+ OUStringBuffer aRet(rParticle);
+
+ if( aRet.getLength() && rChildParticle.getLength() )
+ aRet.appendAscii(":");
+ if( rChildParticle.getLength() )
+ aRet.append(rChildParticle);
+
+ return aRet.makeStringAndClear();
+}
+
+//static
+rtl::OUString ObjectIdentifier::createChildParticleWithIndex( ObjectType eObjectType, sal_Int32 nIndex )
+{
+ OUStringBuffer aRet( getStringForType( eObjectType ) );
+ if( aRet.getLength() )
+ {
+ aRet.appendAscii("=");
+ aRet.append(OUString::valueOf(nIndex));
+ }
+ return aRet.makeStringAndClear();
+}
+
+//static
+sal_Int32 ObjectIdentifier::getIndexFromParticleOrCID( const rtl::OUString& rParticleOrCID )
+{
+ sal_Int32 nRet = -1;
+
+ OUString aIndexString = lcl_getIndexStringAfterString( rParticleOrCID, C2U("=") );
+ sal_Int32 nCharacterIndex=0;
+ nRet = lcl_StringToIndex( aIndexString.getToken( 0, ',', nCharacterIndex ) );
+
+ return nRet;
+}
+
+//static
+OUString ObjectIdentifier::createSeriesSubObjectStub( ObjectType eSubObjectType
+ , const rtl::OUString& rSeriesParticle
+ , const rtl::OUString& rDragMethodServiceName
+ , const rtl::OUString& rDragParameterString )
+{
+ OUString aChildParticle( getStringForType( eSubObjectType ) );
+ aChildParticle+=(C2U("="));
+
+ return createClassifiedIdentifierForParticles(
+ rSeriesParticle, aChildParticle
+ , rDragMethodServiceName, rDragParameterString );
+}
+
+//static
+OUString ObjectIdentifier::createPointCID( const OUString& rPointCID_Stub, sal_Int32 nIndex )
+{
+ OUString aRet(rPointCID_Stub);
+ return aRet+=OUString::valueOf( nIndex );
+}
+
+//static
+OUString ObjectIdentifier::getParticleID( const OUString& rCID )
+{
+ OUString aRet;
+ sal_Int32 nLast = rCID.lastIndexOf('=');
+ if(nLast>=0)
+ aRet = rCID.copy(++nLast);
+ return aRet;
+}
+
+//static
+OUString ObjectIdentifier::getFullParentParticle( const OUString& rCID )
+{
+ OUString aRet;
+
+ sal_Int32 nStartPos = rCID.lastIndexOf('/');
+ if( nStartPos>=0 )
+ {
+ nStartPos++;
+ sal_Int32 nEndPos = rCID.lastIndexOf(':');
+ if( nEndPos>=0 && nStartPos < nEndPos )
+ {
+ aRet = rCID.copy(nStartPos,nEndPos-nStartPos);
+ }
+ }
+
+ return aRet;
+}
+
+//static
+OUString ObjectIdentifier::getObjectID( const rtl::OUString& rCID )
+{
+ OUString aRet;
+
+ sal_Int32 nStartPos = rCID.lastIndexOf('/');
+ if( nStartPos>=0 )
+ {
+ nStartPos++;
+ sal_Int32 nEndPos = rCID.getLength();
+ aRet = rCID.copy(nStartPos,nEndPos-nStartPos);
+ }
+
+ return aRet;
+}
+
+//static
+bool ObjectIdentifier::isCID( const OUString& rName )
+{
+ return rName.getLength() && rName.match( m_aProtocol );
+}
+
+Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet(
+ const OUString& rObjectCID,
+ const Reference< chart2::XChartDocument >& xChartDocument )
+{
+ return ObjectIdentifier::getObjectPropertySet(
+ rObjectCID, Reference< frame::XModel >( xChartDocument, uno::UNO_QUERY ));
+}
+
+//static
+Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet(
+ const OUString& rObjectCID
+ , const Reference< frame::XModel >& xChartModel )
+{
+ //return the model object that is indicated by rObjectCID
+ if(!rObjectCID.getLength())
+ return NULL;
+ if(!xChartModel.is())
+ return NULL;
+
+ Reference< beans::XPropertySet > xObjectProperties = NULL;
+ try
+ {
+ ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
+ OUString aParticleID = ObjectIdentifier::getParticleID( rObjectCID );
+
+ Reference< XDiagram > xDiagram;
+ Reference< XCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ switch(eObjectType)
+ {
+ case OBJECTTYPE_PAGE:
+ {
+ Reference< XChartDocument > xChartDocument( xChartModel, uno::UNO_QUERY );
+ if( xChartDocument.is())
+ xObjectProperties.set( xChartDocument->getPageBackground() );
+ }
+ break;
+ case OBJECTTYPE_TITLE:
+ {
+ TitleHelper::eTitleType aTitleType = getTitleTypeForCID( rObjectCID );
+ Reference< XTitle > xTitle( TitleHelper::getTitle( aTitleType, xChartModel ) );
+ xObjectProperties.set( xTitle, uno::UNO_QUERY );
+ }
+ break;
+ case OBJECTTYPE_LEGEND:
+ {
+ if( xDiagram.is() )
+ xObjectProperties.set( xDiagram->getLegend(), uno::UNO_QUERY );
+ }
+ break;
+ case OBJECTTYPE_LEGEND_ENTRY:
+ break;
+ case OBJECTTYPE_DIAGRAM:
+ {
+ xObjectProperties.set( xDiagram, uno::UNO_QUERY );
+ }
+ break;
+ case OBJECTTYPE_DIAGRAM_WALL:
+ {
+ if( xDiagram.is() )
+ xObjectProperties.set( xDiagram->getWall() );
+ }
+ break;
+ case OBJECTTYPE_DIAGRAM_FLOOR:
+ {
+ if( xDiagram.is() )
+ xObjectProperties.set( xDiagram->getFloor() );
+ }
+ break;
+ case OBJECTTYPE_AXIS:
+ {
+ sal_Int32 nDimensionIndex = -1;
+ sal_Int32 nAxisIndex = -1;
+ lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
+
+ Reference< chart2::XAxis > xAxis(
+ AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys ) );
+ if( xAxis.is() )
+ xObjectProperties.set( xAxis, uno::UNO_QUERY );
+ }
+ break;
+ case OBJECTTYPE_AXIS_UNITLABEL:
+ break;
+ case OBJECTTYPE_GRID:
+ case OBJECTTYPE_SUBGRID:
+ {
+ sal_Int32 nDimensionIndex = -1;
+ sal_Int32 nAxisIndex = -1;
+ lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
+
+ sal_Int32 nSubGridIndex = -1;
+ lcl_parseGridIndices( nSubGridIndex, rObjectCID );
+
+ xObjectProperties.set( AxisHelper::getGridProperties( xCooSys , nDimensionIndex, nAxisIndex, nSubGridIndex ) );
+ }
+ break;
+ case OBJECTTYPE_DATA_LABELS:
+ case OBJECTTYPE_DATA_SERIES:
+ {
+ Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel ) );
+ if( xSeries.is() )
+ xObjectProperties = Reference< beans::XPropertySet >( xSeries, uno::UNO_QUERY );
+
+ break;
+ }
+ case OBJECTTYPE_DATA_LABEL:
+ case OBJECTTYPE_DATA_POINT:
+ {
+ Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel ) );
+ if(xSeries.is())
+ {
+ sal_Int32 nIndex = aParticleID.toInt32();
+ xObjectProperties = xSeries->getDataPointByIndex( nIndex );
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_ERRORS:
+ {
+ Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel ) );
+ if(xSeries.is())
+ {
+ Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
+ Reference< beans::XPropertySet > xErrorBarProp;
+ if( xSeriesProp.is() )
+ {
+ xSeriesProp->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProp;
+ xObjectProperties = Reference< beans::XPropertySet >( xErrorBarProp, uno::UNO_QUERY );
+ }
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_ERRORS_X:
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ break;
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ case OBJECTTYPE_DATA_CURVE:
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ {
+ Reference< XRegressionCurveContainer > xRegressionContainer( ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel ), uno::UNO_QUERY );
+ if(xRegressionContainer.is())
+ {
+ sal_Int32 nIndex = aParticleID.toInt32();
+ uno::Sequence< Reference< XRegressionCurve > > aCurveList =
+ xRegressionContainer->getRegressionCurves();
+ if( nIndex >= 0 && nIndex <aCurveList.getLength() )
+ {
+ if( eObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
+ xObjectProperties.set( aCurveList[nIndex]->getEquationProperties());
+ else
+ xObjectProperties.set( aCurveList[nIndex], uno::UNO_QUERY );
+ }
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_STOCK_RANGE:
+ break;
+ case OBJECTTYPE_DATA_STOCK_LOSS:
+ {
+ Reference<XChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
+ Reference< beans::XPropertySet > xChartTypeProps( xChartType, uno::UNO_QUERY );
+ if(xChartTypeProps.is())
+ xChartTypeProps->getPropertyValue( C2U( "BlackDay" ) ) >>= xObjectProperties;
+ }
+ break;
+ case OBJECTTYPE_DATA_STOCK_GAIN:
+ {
+ Reference<XChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
+ Reference< beans::XPropertySet > xChartTypeProps( xChartType, uno::UNO_QUERY );
+ if(xChartTypeProps.is())
+ xChartTypeProps->getPropertyValue( C2U( "WhiteDay" ) ) >>= xObjectProperties;
+ }
+ break;
+ default: //OBJECTTYPE_UNKNOWN
+ break;
+ }
+ }
+ catch( uno::Exception& ex)
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return xObjectProperties;
+}
+
+//static
+Reference< XAxis > ObjectIdentifier::getAxisForCID(
+ const OUString& rObjectCID
+ , const Reference< frame::XModel >& xChartModel )
+{
+ Reference< XDiagram > xDiagram;
+ Reference< XCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ sal_Int32 nDimensionIndex = -1;
+ sal_Int32 nAxisIndex = -1;
+ lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
+
+ return AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys );
+}
+
+//static
+Reference< XDataSeries > ObjectIdentifier::getDataSeriesForCID(
+ const OUString& rObjectCID
+ , const Reference< frame::XModel >& xChartModel )
+{
+ Reference< XDataSeries > xSeries(NULL);
+
+ Reference< XDiagram > xDiagram;
+ Reference< XCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ sal_Int32 nChartTypeIndex = -1;
+ sal_Int32 nSeriesIndex = -1;
+ sal_Int32 nPointIndex = -1;
+ lcl_parseSeriesIndices( nChartTypeIndex, nSeriesIndex, nPointIndex, rObjectCID );
+
+ Reference< XDataSeriesContainer > xDataSeriesContainer( DiagramHelper::getChartTypeByIndex( xDiagram, nChartTypeIndex ), uno::UNO_QUERY );
+ if( xDataSeriesContainer.is() )
+ {
+ uno::Sequence< uno::Reference< XDataSeries > > aDataSeriesSeq( xDataSeriesContainer->getDataSeries() );
+ if( nSeriesIndex >= 0 && nSeriesIndex < aDataSeriesSeq.getLength() )
+ xSeries.set( aDataSeriesSeq[nSeriesIndex] );
+ }
+
+ return xSeries;
+}
+
+//static
+Reference< XDiagram > ObjectIdentifier::getDiagramForCID(
+ const rtl::OUString& rObjectCID
+ , const uno::Reference< frame::XModel >& xChartModel )
+{
+ Reference< XDiagram > xDiagram;
+
+ Reference< XCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ return xDiagram;
+}
+
+TitleHelper::eTitleType ObjectIdentifier::getTitleTypeForCID( const OUString& rCID )
+{
+ TitleHelper::eTitleType eRet( TitleHelper::MAIN_TITLE );
+
+ OUString aParentParticle = ObjectIdentifier::getFullParentParticle( rCID );
+ const tTitleMap& rMap = lcl_getTitleMap();
+ tTitleMap::const_iterator aIt( rMap.begin() );
+ for( ;aIt != rMap.end(); ++aIt )
+ {
+ if( aParentParticle.equals( (*aIt).second ) )
+ {
+ eRet = (*aIt).first;
+ break;
+ }
+ }
+
+ return eRet;
+}
+
+// static
+OUString ObjectIdentifier::getSeriesParticleFromCID( const OUString& rCID )
+{
+ sal_Int32 nDiagramIndex = -1;
+ sal_Int32 nCooSysIndex = -1;
+ lcl_parseCooSysIndices( nDiagramIndex, nCooSysIndex, rCID );
+
+ sal_Int32 nChartTypeIndex = -1;
+ sal_Int32 nSeriesIndex = -1;
+ sal_Int32 nPointIndex = -1;
+ lcl_parseSeriesIndices( nChartTypeIndex, nSeriesIndex, nPointIndex, rCID );
+
+ return ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCooSysIndex, nChartTypeIndex, nSeriesIndex );
+}
+
+//static
+OUString ObjectIdentifier::getMovedSeriesCID( const ::rtl::OUString& rObjectCID, sal_Bool bForward )
+{
+ sal_Int32 nDiagramIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, C2U("CID/D=") ) );
+ sal_Int32 nCooSysIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, C2U("CS=") ) );
+ sal_Int32 nChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, C2U("CT=") ) );
+ sal_Int32 nSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, C2U("Series=") ) );
+
+ if( bForward )
+ nSeriesIndex--;
+ else
+ nSeriesIndex++;
+
+ OUString aRet = ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCooSysIndex, nChartTypeIndex, nSeriesIndex );
+ return ObjectIdentifier::createClassifiedIdentifierForParticle( aRet );
+}
+
+bool ObjectIdentifier::isValid() const
+{
+ return ( isAutoGeneratedObject() || isAdditionalShape() );
+}
+
+bool ObjectIdentifier::isAutoGeneratedObject() const
+{
+ return ( m_aObjectCID.getLength() > 0 );
+}
+
+bool ObjectIdentifier::isAdditionalShape() const
+{
+ return m_xAdditionalShape.is();
+}
+
+OUString ObjectIdentifier::getObjectCID() const
+{
+ return m_aObjectCID;
+}
+
+Reference< drawing::XShape > ObjectIdentifier::getAdditionalShape() const
+{
+ return m_xAdditionalShape;
+}
+
+Any ObjectIdentifier::getAny() const
+{
+ Any aAny;
+ if ( isAutoGeneratedObject() )
+ {
+ aAny = uno::makeAny( getObjectCID() );
+ }
+ else if ( isAdditionalShape() )
+ {
+ aAny = uno::makeAny( getAdditionalShape() );
+ }
+ return aAny;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/PotentialRegressionCurveCalculator.cxx b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..b1d10424b9a1
--- /dev/null
+++ b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "PotentialRegressionCurveCalculator.hxx"
+#include "macros.hxx"
+#include "RegressionCalculationHelper.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace chart
+{
+
+PotentialRegressionCurveCalculator::PotentialRegressionCurveCalculator() :
+ m_fSlope( 0.0 ),
+ m_fIntercept( 0.0 )
+{
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+}
+
+PotentialRegressionCurveCalculator::~PotentialRegressionCurveCalculator()
+{}
+
+// ____ XRegressionCurveCalculator ____
+void SAL_CALL PotentialRegressionCurveCalculator::recalculateRegression(
+ const uno::Sequence< double >& aXValues,
+ const uno::Sequence< double >& aYValues )
+ throw (uno::RuntimeException)
+{
+ RegressionCalculationHelper::tDoubleVectorPair aValues(
+ RegressionCalculationHelper::cleanup(
+ aXValues, aYValues,
+ RegressionCalculationHelper::isValidAndBothPositive()));
+
+ const size_t nMax = aValues.first.size();
+ if( nMax == 0 )
+ {
+ ::rtl::math::setNan( & m_fSlope );
+ ::rtl::math::setNan( & m_fIntercept );
+ ::rtl::math::setNan( & m_fCorrelationCoeffitient );
+ return;
+ }
+
+ double fAverageX = 0.0, fAverageY = 0.0;
+ size_t i = 0;
+ for( i = 0; i < nMax; ++i )
+ {
+ fAverageX += log( aValues.first[i] );
+ fAverageY += log( aValues.second[i] );
+ }
+
+ const double fN = static_cast< double >( nMax );
+ fAverageX /= fN;
+ fAverageY /= fN;
+
+ double fQx = 0.0, fQy = 0.0, fQxy = 0.0;
+ for( i = 0; i < nMax; ++i )
+ {
+ double fDeltaX = log( aValues.first[i] ) - fAverageX;
+ double fDeltaY = log( aValues.second[i] ) - fAverageY;
+
+ fQx += fDeltaX * fDeltaX;
+ fQy += fDeltaY * fDeltaY;
+ fQxy += fDeltaX * fDeltaY;
+ }
+
+ m_fSlope = fQxy / fQx;
+ m_fIntercept = fAverageY - m_fSlope * fAverageX;
+ m_fCorrelationCoeffitient = fQxy / sqrt( fQx * fQy );
+
+ m_fIntercept = exp( m_fIntercept );
+}
+
+double SAL_CALL PotentialRegressionCurveCalculator::getCurveValue( double x )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ double fResult;
+ ::rtl::math::setNan( & fResult );
+
+ if( ! ( ::rtl::math::isNan( m_fSlope ) ||
+ ::rtl::math::isNan( m_fIntercept )))
+ {
+ fResult = m_fIntercept * pow( x, m_fSlope );
+ }
+
+ return fResult;
+}
+
+uno::Sequence< geometry::RealPoint2D > SAL_CALL PotentialRegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const uno::Reference< chart2::XScaling >& xScalingX,
+ const uno::Reference< chart2::XScaling >& xScalingY,
+ ::sal_Bool bMaySkipPointsInCalculation )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( bMaySkipPointsInCalculation &&
+ isLogarithmicScaling( xScalingX ) &&
+ isLogarithmicScaling( xScalingY ))
+ {
+ // optimize result
+ uno::Sequence< geometry::RealPoint2D > aResult( 2 );
+ aResult[0].X = min;
+ aResult[0].Y = this->getCurveValue( min );
+ aResult[1].X = max;
+ aResult[1].Y = this->getCurveValue( max );
+
+ return aResult;
+ }
+ return RegressionCurveCalculator::getCurveValues( min, max, nPointCount, xScalingX, xScalingY, bMaySkipPointsInCalculation );
+}
+
+OUString PotentialRegressionCurveCalculator::ImplGetRepresentation(
+ const uno::Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey ) const
+{
+ OUStringBuffer aBuf( C2U( "f(x) = " ));
+
+ if( m_fIntercept == 0.0 )
+ {
+ aBuf.append( sal_Unicode( '0' ));
+ }
+ else if( m_fSlope == 0.0 )
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ }
+ else
+ {
+ if( ! rtl::math::approxEqual( m_fIntercept, 1.0 ) )
+ {
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fIntercept ));
+ aBuf.append( sal_Unicode( ' ' ));
+ }
+ if( m_fSlope != 0.0 )
+ {
+ aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "x^" ));
+ aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, m_fSlope ));
+ }
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/PropertyHelper.cxx b/chart2/source/tools/PropertyHelper.cxx
new file mode 100644
index 000000000000..dd0a1ad6cf2f
--- /dev/null
+++ b/chart2/source/tools/PropertyHelper.cxx
@@ -0,0 +1,314 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "PropertyHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+#include <vector>
+#include <algorithm>
+#include <functional>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+
+namespace
+{
+struct lcl_EqualsElement : public ::std::unary_function< OUString, bool >
+{
+ explicit lcl_EqualsElement( const Any & rValue, const Reference< container::XNameAccess > & xAccess )
+ : m_aValue( rValue ), m_xAccess( xAccess )
+ {
+ OSL_ASSERT( m_xAccess.is());
+ }
+
+ bool operator() ( const OUString & rName )
+ {
+ try
+ {
+ return (m_xAccess->getByName( rName ) == m_aValue);
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return false;
+ }
+
+private:
+ Any m_aValue;
+ Reference< container::XNameAccess > m_xAccess;
+};
+
+struct lcl_StringMatches : public ::std::unary_function< OUString ,bool >
+{
+ lcl_StringMatches( const OUString & rCmpStr ) :
+ m_aCmpStr( rCmpStr )
+ {}
+
+ bool operator() ( const OUString & rStr )
+ {
+ return rStr.match( m_aCmpStr );
+ }
+
+private:
+ OUString m_aCmpStr;
+};
+
+struct lcl_OUStringRestToInt32 : public ::std::unary_function< OUString, sal_Int32 >
+{
+ lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) :
+ m_nPrefixLength( nPrefixLength )
+ {}
+ sal_Int32 operator() ( const OUString & rStr )
+ {
+ if( m_nPrefixLength > rStr.getLength() )
+ return 0;
+ return rStr.copy( m_nPrefixLength ).toInt32( 10 /* radix */ );
+ }
+private:
+ sal_Int32 m_nPrefixLength;
+};
+
+/** adds a fill gradient, fill hatch, fill bitmap, fill transparency gradient,
+ line dash or line marker to the corresponding name container with a unique
+ name.
+
+ @param rPrefix
+ The prefix used for automated name generation.
+
+ @param rPreferredName
+ If this string is not empty it is used as name if it is unique in the
+ table. Otherwise a new name is generated using pPrefix.
+
+ @return the new name under which the property was stored in the table
+*/
+OUString lcl_addNamedPropertyUniqueNameToTable(
+ const Any & rValue,
+ const Reference< container::XNameContainer > & xNameContainer,
+ const OUString & rPrefix,
+ const OUString & rPreferredName )
+{
+ if( ! xNameContainer.is() ||
+ ! rValue.hasValue() ||
+ ( rValue.getValueType() != xNameContainer->getElementType()))
+ return rPreferredName;
+
+ try
+ {
+ Reference< container::XNameAccess > xNameAccess( xNameContainer, uno::UNO_QUERY_THROW );
+ ::std::vector< OUString > aNames( ::chart::ContainerHelper::SequenceToVector( xNameAccess->getElementNames()));
+ ::std::vector< OUString >::const_iterator aIt(
+ ::std::find_if( aNames.begin(), aNames.end(), lcl_EqualsElement( rValue, xNameAccess )));
+
+ // element not found in container
+ if( aIt == aNames.end())
+ {
+ OUString aUniqueName;
+
+ // check if preferred name is already used
+ if( rPreferredName.getLength())
+ {
+ aIt = ::std::find( aNames.begin(), aNames.end(), rPreferredName );
+ if( aIt == aNames.end())
+ aUniqueName = rPreferredName;
+ }
+
+ if( ! aUniqueName.getLength())
+ {
+ // create a unique id using the prefix plus a number
+ ::std::vector< sal_Int32 > aNumbers;
+ ::std::vector< OUString >::iterator aNonConstIt(
+ ::std::partition( aNames.begin(), aNames.end(), lcl_StringMatches( rPrefix )));
+ ::std::transform( aNames.begin(), aNonConstIt,
+ back_inserter( aNumbers ),
+ lcl_OUStringRestToInt32( rPrefix.getLength() ));
+ ::std::vector< sal_Int32 >::const_iterator aMaxIt(
+ ::std::max_element( aNumbers.begin(), aNumbers.end()));
+
+ sal_Int32 nIndex = 1;
+ if( aMaxIt != aNumbers.end())
+ nIndex = (*aMaxIt) + 1;
+
+ aUniqueName = rPrefix + OUString::valueOf( nIndex );
+ }
+
+ OSL_ASSERT( aUniqueName.getLength());
+ xNameContainer->insertByName( aUniqueName, rValue );
+ return aUniqueName;
+ }
+ else
+ // element found => return name
+ return *aIt;
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return rPreferredName;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+namespace PropertyHelper
+{
+
+OUString addLineDashUniqueNameToTable(
+ const Any & rValue,
+ const Reference< lang::XMultiServiceFactory > & xFact,
+ const OUString & rPreferredName )
+{
+ if( xFact.is())
+ {
+ Reference< container::XNameContainer > xNameCnt(
+ xFact->createInstance( C2U( "com.sun.star.drawing.DashTable" )),
+ uno::UNO_QUERY );
+ if( xNameCnt.is())
+ return lcl_addNamedPropertyUniqueNameToTable(
+ rValue, xNameCnt, C2U( "ChartDash " ), rPreferredName );
+ }
+ return OUString();
+}
+
+OUString addGradientUniqueNameToTable(
+ const Any & rValue,
+ const Reference< lang::XMultiServiceFactory > & xFact,
+ const OUString & rPreferredName )
+{
+ if( xFact.is())
+ {
+ Reference< container::XNameContainer > xNameCnt(
+ xFact->createInstance( C2U( "com.sun.star.drawing.GradientTable" )),
+ uno::UNO_QUERY );
+ if( xNameCnt.is())
+ return lcl_addNamedPropertyUniqueNameToTable(
+ rValue, xNameCnt, C2U( "ChartGradient " ), rPreferredName );
+ }
+ return OUString();
+}
+
+
+OUString addTransparencyGradientUniqueNameToTable(
+ const Any & rValue,
+ const Reference< lang::XMultiServiceFactory > & xFact,
+ const OUString & rPreferredName )
+{
+ if( xFact.is())
+ {
+ Reference< container::XNameContainer > xNameCnt(
+ xFact->createInstance( C2U( "com.sun.star.drawing.TransparencyGradientTable" )),
+ uno::UNO_QUERY );
+ if( xNameCnt.is())
+ return lcl_addNamedPropertyUniqueNameToTable(
+ rValue, xNameCnt, C2U( "ChartTransparencyGradient " ), rPreferredName );
+ }
+ return OUString();
+}
+
+OUString addHatchUniqueNameToTable(
+ const Any & rValue,
+ const Reference< lang::XMultiServiceFactory > & xFact,
+ const OUString & rPreferredName )
+{
+ if( xFact.is())
+ {
+ Reference< container::XNameContainer > xNameCnt(
+ xFact->createInstance( C2U( "com.sun.star.drawing.HatchTable" )),
+ uno::UNO_QUERY );
+ if( xNameCnt.is())
+ return lcl_addNamedPropertyUniqueNameToTable(
+ rValue, xNameCnt, C2U( "ChartHatch " ), rPreferredName );
+ }
+ return OUString();
+}
+
+OUString addBitmapUniqueNameToTable(
+ const Any & rValue,
+ const Reference< lang::XMultiServiceFactory > & xFact,
+ const OUString & rPreferredName )
+{
+ if( xFact.is())
+ {
+ Reference< container::XNameContainer > xNameCnt(
+ xFact->createInstance( C2U( "com.sun.star.drawing.BitmapTable" )),
+ uno::UNO_QUERY );
+ if( xNameCnt.is())
+ return lcl_addNamedPropertyUniqueNameToTable(
+ rValue, xNameCnt, C2U( "ChartBitmap " ), rPreferredName );
+ }
+ return OUString();
+}
+
+// ----------------------------------------
+
+void setPropertyValueAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
+{
+ tPropertyValueMap::iterator aIt( rOutMap.find( key ));
+ if( aIt == rOutMap.end())
+ rOutMap.insert( tPropertyValueMap::value_type( key, rAny ));
+ else
+ (*aIt).second = rAny;
+}
+
+template<>
+ void setPropertyValue< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
+{
+ setPropertyValueAny( rOutMap, key, rAny );
+}
+
+void setPropertyValueDefaultAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
+{
+ OSL_ENSURE( rOutMap.end() == rOutMap.find( key ), "Default already exists for property" );
+ setPropertyValue( rOutMap, key, rAny );
+}
+
+template<>
+ void setPropertyValueDefault< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
+{
+ setPropertyValueDefaultAny( rOutMap, key, rAny );
+}
+
+
+void setEmptyPropertyValueDefault( tPropertyValueMap & rOutMap, tPropertyValueMapKey key )
+{
+ setPropertyValueDefault( rOutMap, key, uno::Any());
+}
+
+} // namespace PropertyHelper
+
+} // namespace chart
diff --git a/chart2/source/tools/RangeHighlighter.cxx b/chart2/source/tools/RangeHighlighter.cxx
new file mode 100644
index 000000000000..1565344923b1
--- /dev/null
+++ b/chart2/source/tools/RangeHighlighter.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "RangeHighlighter.hxx"
+#include "WeakListenerAdapter.hxx"
+#include "ChartModelHelper.hxx"
+#include "DataSourceHelper.hxx"
+#include "ContainerHelper.hxx"
+#include "macros.hxx"
+#include "ObjectIdentifier.hxx"
+#include "DataSeriesHelper.hxx"
+
+#include <com/sun/star/chart2/XDataSeries.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+
+#define PREFERED_DEFAULT_COLOR 0x0000ff
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace
+{
+
+void lcl_fillRanges(
+ Sequence< chart2::data::HighlightedRange > & rOutRanges,
+ Sequence< OUString > aRangeStrings,
+ sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR,
+ sal_Int32 nIndex = -1 )
+{
+ rOutRanges.realloc( aRangeStrings.getLength());
+ for( sal_Int32 i=0; i<aRangeStrings.getLength(); ++i )
+ {
+ rOutRanges[i].RangeRepresentation = aRangeStrings[i];
+ rOutRanges[i].PreferredColor = nPreferredColor;
+ rOutRanges[i].AllowMerginigWithOtherRanges = sal_False;
+ rOutRanges[i].Index = nIndex;
+ }
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+RangeHighlighter::RangeHighlighter(
+ const Reference< view::XSelectionSupplier > & xSelectionSupplier ) :
+ impl::RangeHighlighter_Base( m_aMutex ),
+ m_xSelectionSupplier( xSelectionSupplier ),
+ m_nAddedListenerCount( 0 ),
+ m_bIncludeHiddenCells(true)
+{
+}
+
+RangeHighlighter::~RangeHighlighter()
+{}
+
+// ____ XRangeHighlighter ____
+Sequence< chart2::data::HighlightedRange > SAL_CALL RangeHighlighter::getSelectedRanges()
+ throw (uno::RuntimeException)
+{
+ return m_aSelectedRanges;
+}
+
+void RangeHighlighter::determineRanges()
+{
+ m_aSelectedRanges.realloc( 0 );
+ if( m_xSelectionSupplier.is())
+ {
+ try
+ {
+ Reference< frame::XController > xController( m_xSelectionSupplier, uno::UNO_QUERY );
+ Reference< frame::XModel > xChartModel;
+ if( xController.is())
+ xChartModel.set( xController->getModel());
+
+ m_bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( xChartModel );
+
+ uno::Any aSelection( m_xSelectionSupplier->getSelection());
+ const uno::Type& rType = aSelection.getValueType();
+
+ if ( rType == ::getCppuType( static_cast< const OUString* >( 0 ) ) )
+ {
+ // @todo??: maybe getSelection() should return a model object rather than a CID
+
+ OUString aCID;
+ aSelection >>= aCID;
+ if ( aCID.getLength() > 0 )
+ {
+ ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
+ sal_Int32 nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aCID );
+ Reference< chart2::XDataSeries > xDataSeries( ObjectIdentifier::getDataSeriesForCID( aCID, xChartModel ) );
+ if( OBJECTTYPE_LEGEND_ENTRY == eObjectType )
+ {
+ OUString aParentParticel( ObjectIdentifier::getFullParentParticle( aCID ) );
+ ObjectType eParentObjectType = ObjectIdentifier::getObjectType( aParentParticel );
+ eObjectType = eParentObjectType;
+ if( OBJECTTYPE_DATA_POINT == eObjectType )
+ nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aParentParticel );
+ }
+
+ if( OBJECTTYPE_DATA_POINT == eObjectType || OBJECTTYPE_DATA_LABEL == eObjectType )
+ {
+ // Data Point
+ fillRangesForDataPoint( xDataSeries, nIndex );
+ return;
+ }
+ else if( OBJECTTYPE_DATA_ERRORS == eObjectType )
+ {
+ // select error bar ranges, or data series, if the style is
+ // not set to FROM_DATA
+ fillRangesForErrorBars( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), xDataSeries );
+ return;
+ }
+ else if( xDataSeries.is() )
+ {
+ // Data Series
+ fillRangesForDataSeries( xDataSeries );
+ return;
+ }
+ else if( OBJECTTYPE_AXIS == eObjectType )
+ {
+ // Axis (Categories)
+ Reference< chart2::XAxis > xAxis( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), uno::UNO_QUERY );
+ if( xAxis.is())
+ {
+ fillRangesForCategories( xAxis );
+ return;
+ }
+ }
+ else if( OBJECTTYPE_PAGE == eObjectType
+ || OBJECTTYPE_DIAGRAM == eObjectType
+ || OBJECTTYPE_DIAGRAM_WALL == eObjectType
+ || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
+ )
+ {
+ // Diagram
+ Reference< chart2::XDiagram > xDia( ObjectIdentifier::getDiagramForCID( aCID, xChartModel ) );
+ if( xDia.is())
+ {
+ fillRangesForDiagram( xDia );
+ return;
+ }
+ }
+ }
+ }
+ else if ( rType == ::getCppuType( static_cast< const Reference< drawing::XShape >* >( 0 ) ) )
+ {
+ // #i12587# support for shapes in chart
+ Reference< drawing::XShape > xShape;
+ aSelection >>= xShape;
+ if ( xShape.is() )
+ {
+ return;
+ }
+ }
+ else
+ {
+ //if nothing is selected select all ranges
+ Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY_THROW );
+ fillRangesForDiagram( xChartDoc->getFirstDiagram() );
+ return;
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+}
+
+void RangeHighlighter::fillRangesForDiagram( const Reference< chart2::XDiagram > & xDiagram )
+{
+ Sequence< OUString > aSelectedRanges( DataSourceHelper::getUsedDataRanges( xDiagram ));
+ m_aSelectedRanges.realloc( aSelectedRanges.getLength());
+ // @todo: merge ranges
+ for( sal_Int32 i=0; i<aSelectedRanges.getLength(); ++i )
+ {
+ m_aSelectedRanges[i].RangeRepresentation = aSelectedRanges[i];
+ m_aSelectedRanges[i].Index = -1;
+ m_aSelectedRanges[i].PreferredColor = PREFERED_DEFAULT_COLOR;
+ m_aSelectedRanges[i].AllowMerginigWithOtherRanges = sal_True;
+ }
+}
+
+void RangeHighlighter::fillRangesForDataSeries( const uno::Reference< chart2::XDataSeries > & xSeries )
+{
+ sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
+ Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
+ if( xSource.is())
+ lcl_fillRanges( m_aSelectedRanges,
+ ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
+ nPreferredColor );
+}
+
+void RangeHighlighter::fillRangesForErrorBars(
+ const uno::Reference< beans::XPropertySet > & xErrorBar,
+ const uno::Reference< chart2::XDataSeries > & xSeries )
+{
+ // only show error bar ranges, if the style is set to FROM_DATA
+ bool bUsesRangesAsErrorBars = false;
+ try
+ {
+ sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
+ bUsesRangesAsErrorBars =
+ ( xErrorBar.is() &&
+ (xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle) &&
+ nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ if( bUsesRangesAsErrorBars )
+ {
+ sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
+ Reference< chart2::data::XDataSource > xSource( xErrorBar, uno::UNO_QUERY );
+ if( xSource.is())
+ lcl_fillRanges( m_aSelectedRanges,
+ ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
+ nPreferredColor );
+ }
+ else
+ {
+ fillRangesForDataSeries( xSeries );
+ }
+}
+
+void RangeHighlighter::fillRangesForCategories( const Reference< chart2::XAxis > & xAxis )
+{
+ if( ! xAxis.is())
+ return;
+ chart2::ScaleData aData( xAxis->getScaleData());
+ lcl_fillRanges( m_aSelectedRanges,
+ DataSourceHelper::getRangesFromLabeledDataSequence( aData.Categories ));
+}
+
+void RangeHighlighter::fillRangesForDataPoint( const Reference< uno::XInterface > & xDataSeries, sal_Int32 nIndex )
+{
+ sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
+ if( xDataSeries.is())
+ {
+ Reference< chart2::data::XDataSource > xSource( xDataSeries, uno::UNO_QUERY );
+ if( xSource.is() )
+ {
+ ::std::vector< chart2::data::HighlightedRange > aHilightedRanges;
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeqSeq( xSource->getDataSequences());
+ for( sal_Int32 i=0; i<aLSeqSeq.getLength(); ++i )
+ {
+ Reference< chart2::data::XDataSequence > xLabel( aLSeqSeq[i]->getLabel());
+ Reference< chart2::data::XDataSequence > xValues( aLSeqSeq[i]->getValues());
+
+ if( xLabel.is())
+ aHilightedRanges.push_back(
+ chart2::data::HighlightedRange(
+ xLabel->getSourceRangeRepresentation(),
+ -1,
+ nPreferredColor,
+ sal_False ));
+
+ sal_Int32 nUnhiddenIndex = DataSeriesHelper::translateIndexFromHiddenToFullSequence( nIndex, xValues, !m_bIncludeHiddenCells );
+ if( xValues.is())
+ aHilightedRanges.push_back(
+ chart2::data::HighlightedRange(
+ xValues->getSourceRangeRepresentation(),
+ nUnhiddenIndex,
+ nPreferredColor,
+ sal_False ));
+ }
+ m_aSelectedRanges = ContainerHelper::ContainerToSequence( aHilightedRanges );
+ }
+ }
+}
+
+void SAL_CALL RangeHighlighter::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ if(!xListener.is())
+ return;
+
+ if( m_nAddedListenerCount == 0 )
+ startListening();
+ rBHelper.addListener( ::getCppuType( & xListener ), xListener);
+ ++m_nAddedListenerCount;
+
+ //bring the new listener up to the current state
+ lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
+ xListener->selectionChanged( aEvent );
+}
+
+void SAL_CALL RangeHighlighter::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
+ throw (uno::RuntimeException)
+{
+ rBHelper.removeListener( ::getCppuType( & xListener ), xListener );
+ --m_nAddedListenerCount;
+ if( m_nAddedListenerCount == 0 )
+ stopListening();
+}
+
+// ____ XSelectionChangeListener ____
+void SAL_CALL RangeHighlighter::selectionChanged( const lang::EventObject& /*aEvent*/ )
+ throw (uno::RuntimeException)
+{
+ determineRanges();
+
+ // determine ranges of selected view objects
+ // if changed, fire an event
+ fireSelectionEvent();
+}
+
+void RangeHighlighter::fireSelectionEvent()
+{
+ ::cppu::OInterfaceContainerHelper* pIC = rBHelper.getContainer(
+ ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
+ if( pIC )
+ {
+ lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
+ ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ while( aIt.hasMoreElements() )
+ {
+ uno::Reference< view::XSelectionChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
+ if( xListener.is() )
+ xListener->selectionChanged( aEvent );
+ }
+ }
+}
+
+void SAL_CALL RangeHighlighter::disposing( const lang::EventObject& Source )
+ throw (uno::RuntimeException)
+{
+ if( Source.Source == m_xSelectionSupplier )
+ {
+ m_xSelectionSupplier.clear();
+ m_aSelectedRanges.realloc( 0 );
+ fireSelectionEvent();
+ }
+}
+
+void RangeHighlighter::startListening()
+{
+ if( m_xSelectionSupplier.is())
+ {
+ if( ! m_xListener.is())
+ {
+ m_xListener.set( new WeakSelectionChangeListenerAdapter( this ));
+ determineRanges();
+ }
+ m_xSelectionSupplier->addSelectionChangeListener( m_xListener );
+ }
+}
+
+void RangeHighlighter::stopListening()
+{
+ if( m_xSelectionSupplier.is() && m_xListener.is())
+ {
+ m_xSelectionSupplier->removeSelectionChangeListener( m_xListener );
+ m_xListener.clear();
+ }
+}
+
+
+// ____ WeakComponentImplHelperBase ____
+// is called when dispose() is called at this component
+void SAL_CALL RangeHighlighter::disposing()
+{
+ // @todo: remove listener. Currently the controller shows an assertion
+ // because it is already disposed
+// stopListening();
+ m_xListener.clear();
+ m_xSelectionSupplier.clear();
+ m_nAddedListenerCount = 0;
+ m_aSelectedRanges.realloc( 0 );
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/ReferenceSizeProvider.cxx b/chart2/source/tools/ReferenceSizeProvider.cxx
new file mode 100644
index 000000000000..5a37f4980323
--- /dev/null
+++ b/chart2/source/tools/ReferenceSizeProvider.cxx
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ReferenceSizeProvider.hxx"
+#include "RelativeSizeHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "DiagramHelper.hxx"
+#include "macros.hxx"
+#include "AxisHelper.hxx"
+#include "DataSeriesHelper.hxx"
+
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/XTitle.hpp>
+#include <com/sun/star/chart2/XDataSeries.hpp>
+
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+// ================================================================================
+
+namespace chart
+{
+
+ReferenceSizeProvider::ReferenceSizeProvider(
+ awt::Size aPageSize,
+ const Reference< XChartDocument > & xChartDoc ) :
+ m_aPageSize( aPageSize ),
+ m_xChartDoc( xChartDoc ),
+ m_bUseAutoScale( getAutoResizeState( xChartDoc ) == AUTO_RESIZE_YES )
+{}
+
+awt::Size ReferenceSizeProvider::getPageSize() const
+{
+ return m_aPageSize;
+}
+
+bool ReferenceSizeProvider::useAutoScale() const
+{
+ return m_bUseAutoScale;
+}
+
+void ReferenceSizeProvider::impl_setValuesAtTitled(
+ const Reference< XTitled > & xTitled )
+{
+ if( xTitled.is())
+ {
+ Reference< XTitle > xTitle( xTitled->getTitleObject());
+ if( xTitle.is())
+ setValuesAtTitle( xTitle );
+ }
+}
+
+void ReferenceSizeProvider::setValuesAtTitle(
+ const Reference< XTitle > & xTitle )
+{
+ try
+ {
+ Reference< beans::XPropertySet > xTitleProp( xTitle, uno::UNO_QUERY_THROW );
+ awt::Size aOldRefSize;
+ bool bHasOldRefSize(
+ xTitleProp->getPropertyValue( C2U("ReferencePageSize")) >>= aOldRefSize );
+
+ // set from auto-resize on to off -> adapt font sizes at XFormattedStrings
+ if( bHasOldRefSize && ! useAutoScale())
+ {
+ uno::Sequence< uno::Reference< XFormattedString > > aStrSeq(
+ xTitle->getText());
+ for( sal_Int32 i=0; i<aStrSeq.getLength(); ++i )
+ {
+ RelativeSizeHelper::adaptFontSizes(
+ Reference< beans::XPropertySet >( aStrSeq[i], uno::UNO_QUERY ),
+ aOldRefSize, getPageSize());
+ }
+ }
+
+ setValuesAtPropertySet( xTitleProp, /* bAdaptFontSizes = */ false );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ReferenceSizeProvider::setValuesAtAllDataSeries()
+{
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartDoc ));
+
+ // DataSeries/Points
+ ::std::vector< Reference< XDataSeries > > aSeries(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+
+ for( ::std::vector< Reference< XDataSeries > >::const_iterator aIt( aSeries.begin());
+ aIt != aSeries.end(); ++aIt )
+ {
+ Reference< beans::XPropertySet > xSeriesProp( *aIt, uno::UNO_QUERY );
+ if( xSeriesProp.is())
+ {
+ // data points
+ Sequence< sal_Int32 > aPointIndexes;
+ try
+ {
+ if( xSeriesProp->getPropertyValue( C2U("AttributedDataPoints")) >>= aPointIndexes )
+ {
+ for( sal_Int32 i=0; i< aPointIndexes.getLength(); ++i )
+ setValuesAtPropertySet(
+ (*aIt)->getDataPointByIndex( aPointIndexes[i] ) );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ //it is important to correct the datapoint properties first as they do reference the series properties
+ setValuesAtPropertySet( xSeriesProp );
+ }
+ }
+}
+
+void ReferenceSizeProvider::setValuesAtPropertySet(
+ const Reference< beans::XPropertySet > & xProp,
+ bool bAdaptFontSizes /* = true */ )
+{
+ if( ! xProp.is())
+ return;
+
+ static const OUString aRefSizeName( RTL_CONSTASCII_USTRINGPARAM("ReferencePageSize"));
+
+ try
+ {
+ awt::Size aRefSize( getPageSize() );
+ awt::Size aOldRefSize;
+ bool bHasOldRefSize( xProp->getPropertyValue( aRefSizeName ) >>= aOldRefSize );
+
+ if( useAutoScale())
+ {
+ if( ! bHasOldRefSize )
+ xProp->setPropertyValue( aRefSizeName, uno::makeAny( aRefSize ));
+ }
+ else
+ {
+ if( bHasOldRefSize )
+ {
+ xProp->setPropertyValue( aRefSizeName, uno::Any());
+
+ // adapt font sizes
+ if( bAdaptFontSizes )
+ RelativeSizeHelper::adaptFontSizes( xProp, aOldRefSize, aRefSize );
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ReferenceSizeProvider::getAutoResizeFromPropSet(
+ const Reference< beans::XPropertySet > & xProp,
+ ReferenceSizeProvider::AutoResizeState & rInOutState )
+{
+ static const OUString aRefSizeName( RTL_CONSTASCII_USTRINGPARAM("ReferencePageSize"));
+ AutoResizeState eSingleState = AUTO_RESIZE_UNKNOWN;
+
+ if( xProp.is())
+ {
+ try
+ {
+ if( xProp->getPropertyValue( aRefSizeName ).hasValue())
+ eSingleState = AUTO_RESIZE_YES;
+ else
+ eSingleState = AUTO_RESIZE_NO;
+ }
+ catch( uno::Exception )
+ {
+ // unknown property -> state stays unknown
+ }
+ }
+
+ // curent state unknown => nothing changes. Otherwise if current state
+ // differs from state so far, we have an ambiguity
+ if( rInOutState == AUTO_RESIZE_UNKNOWN )
+ {
+ rInOutState = eSingleState;
+ }
+ else if( eSingleState != AUTO_RESIZE_UNKNOWN &&
+ eSingleState != rInOutState )
+ {
+ rInOutState = AUTO_RESIZE_AMBIGUOUS;
+ }
+}
+
+void ReferenceSizeProvider::impl_getAutoResizeFromTitled(
+ const Reference< XTitled > & xTitled,
+ ReferenceSizeProvider::AutoResizeState & rInOutState )
+{
+ if( xTitled.is())
+ {
+ Reference< beans::XPropertySet > xProp( xTitled->getTitleObject(), uno::UNO_QUERY );
+ if( xProp.is())
+ getAutoResizeFromPropSet( xProp, rInOutState );
+ }
+}
+
+/** Retrieves the state auto-resize from all objects that support this
+ feature. If all objects return the same state, AUTO_RESIZE_YES or
+ AUTO_RESIZE_NO is returned.
+
+ If no object supporting the feature is found, AUTO_RESIZE_UNKNOWN is
+ returned. If there are multiple objects, some with state YES and some
+ with state NO, AUTO_RESIZE_AMBIGUOUS is returned.
+*/
+ReferenceSizeProvider::AutoResizeState ReferenceSizeProvider::getAutoResizeState(
+ const Reference< XChartDocument > & xChartDoc )
+{
+ AutoResizeState eResult = AUTO_RESIZE_UNKNOWN;
+
+ // Main Title
+ Reference< XTitled > xDocTitled( xChartDoc, uno::UNO_QUERY );
+ if( xDocTitled.is())
+ impl_getAutoResizeFromTitled( xDocTitled, eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+
+ // diagram is needed by the rest of the objects
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ), uno::UNO_QUERY );
+ if( ! xDiagram.is())
+ return eResult;
+
+ // Sub Title
+ Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
+ if( xDiaTitled.is())
+ impl_getAutoResizeFromTitled( xDiaTitled, eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+
+ // Legend
+ Reference< beans::XPropertySet > xLegendProp( xDiagram->getLegend(), uno::UNO_QUERY );
+ if( xLegendProp.is())
+ getAutoResizeFromPropSet( xLegendProp, eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+
+ // Axes (incl. Axis Titles)
+ Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
+ for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
+ {
+ Reference< beans::XPropertySet > xProp( aAxes[i], uno::UNO_QUERY );
+ if( xProp.is())
+ getAutoResizeFromPropSet( xProp, eResult );
+ Reference< XTitled > xTitled( aAxes[i], uno::UNO_QUERY );
+ if( xTitled.is())
+ {
+ impl_getAutoResizeFromTitled( xTitled, eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+ }
+ }
+
+ // DataSeries/Points
+ ::std::vector< Reference< XDataSeries > > aSeries(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+
+ for( ::std::vector< Reference< XDataSeries > >::const_iterator aIt( aSeries.begin());
+ aIt != aSeries.end(); ++aIt )
+ {
+ Reference< beans::XPropertySet > xSeriesProp( *aIt, uno::UNO_QUERY );
+ if( xSeriesProp.is())
+ {
+ getAutoResizeFromPropSet( xSeriesProp, eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+
+ // data points
+ Sequence< sal_Int32 > aPointIndexes;
+ try
+ {
+ if( xSeriesProp->getPropertyValue( C2U("AttributedDataPoints")) >>= aPointIndexes )
+ {
+ for( sal_Int32 i=0; i< aPointIndexes.getLength(); ++i )
+ {
+ getAutoResizeFromPropSet(
+ (*aIt)->getDataPointByIndex( aPointIndexes[i] ), eResult );
+ if( eResult == AUTO_RESIZE_AMBIGUOUS )
+ return eResult;
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+
+ return eResult;
+}
+
+void ReferenceSizeProvider::toggleAutoResizeState()
+{
+ setAutoResizeState( m_bUseAutoScale ? AUTO_RESIZE_NO : AUTO_RESIZE_YES );
+}
+
+
+/** sets the auto-resize at all objects that support this feature for text.
+ eNewState must be either AUTO_RESIZE_YES or AUTO_RESIZE_NO
+*/
+void ReferenceSizeProvider::setAutoResizeState( ReferenceSizeProvider::AutoResizeState eNewState )
+{
+ m_bUseAutoScale = (eNewState == AUTO_RESIZE_YES);
+
+ // Main Title
+ impl_setValuesAtTitled( Reference< XTitled >( m_xChartDoc, uno::UNO_QUERY ));
+
+ // diagram is needed by the rest of the objects
+ Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartDoc ), uno::UNO_QUERY );
+ if( ! xDiagram.is())
+ return;
+
+ // Sub Title
+ impl_setValuesAtTitled( Reference< XTitled >( xDiagram, uno::UNO_QUERY ));
+
+ // Legend
+ Reference< beans::XPropertySet > xLegendProp( xDiagram->getLegend(), uno::UNO_QUERY );
+ if( xLegendProp.is())
+ setValuesAtPropertySet( xLegendProp );
+
+ // Axes (incl. Axis Titles)
+ Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
+ for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
+ {
+ Reference< beans::XPropertySet > xProp( aAxes[i], uno::UNO_QUERY );
+ if( xProp.is())
+ setValuesAtPropertySet( xProp );
+ impl_setValuesAtTitled( Reference< XTitled >( aAxes[i], uno::UNO_QUERY ));
+ }
+
+ // DataSeries/Points
+ setValuesAtAllDataSeries();
+
+ // recalculate new state (in case it stays unknown or is ambiguous
+ m_bUseAutoScale = (getAutoResizeState( m_xChartDoc ) == AUTO_RESIZE_YES);
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/RegressionCalculationHelper.hxx b/chart2/source/tools/RegressionCalculationHelper.hxx
new file mode 100644
index 000000000000..df407482b34d
--- /dev/null
+++ b/chart2/source/tools/RegressionCalculationHelper.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART2_REGRESSIONCALCULATIONHELPER_HXX
+#define CHART2_REGRESSIONCALCULATIONHELPER_HXX
+
+#include <rtl/math.hxx>
+
+#include <utility>
+#include <functional>
+#include <vector>
+#include <rtl/math.hxx>
+
+#define NUMBER_TO_STR(number) (::rtl::OStringToOUString(::rtl::math::doubleToString( \
+ number, rtl_math_StringFormat_G, 4, '.', true ),RTL_TEXTENCODING_ASCII_US ))
+
+#define UC_SPACE (sal_Unicode(' '))
+#define UC_MINUS_SIGN (sal_Unicode('-'))
+// #define UC_MINUS_SIGN (sal_Unicode(0x2212))
+
+namespace chart
+{
+namespace RegressionCalculationHelper
+{
+
+typedef ::std::pair< ::std::vector< double >, ::std::vector< double > > tDoubleVectorPair;
+
+/** takes the given x- and y-values and copyies them into the resulting pair,
+ which contains x-values in the first element and the y-values in the second
+ one. All tuples for which aPred is false are not copied.
+
+ <p>The functors below provide a set of useful predicates that can be
+ used to pass as parameter aPred.</p>
+ */
+template< class Pred >
+tDoubleVectorPair
+ cleanup( const ::com::sun::star::uno::Sequence< double > & rXValues,
+ const ::com::sun::star::uno::Sequence< double > & rYValues,
+ Pred aPred )
+{
+ tDoubleVectorPair aResult;
+ sal_Int32 nSize = ::std::min( rXValues.getLength(), rYValues.getLength());
+ for( sal_Int32 i=0; i<nSize; ++i )
+ {
+ if( aPred( rXValues[i], rYValues[i] ))
+ {
+ aResult.first.push_back( rXValues[i] );
+ aResult.second.push_back( rYValues[i] );
+ }
+ }
+
+ return aResult;
+}
+
+
+class isValid : public ::std::binary_function< double, double, bool >
+{
+public:
+ inline bool operator()( double x, double y )
+ { return ! ( ::rtl::math::isNan( x ) ||
+ ::rtl::math::isNan( y ) ||
+ ::rtl::math::isInf( x ) ||
+ ::rtl::math::isInf( y ) );
+ }
+};
+
+class isValidAndXPositive : public ::std::binary_function< double, double, bool >
+{
+public:
+ inline bool operator()( double x, double y )
+ { return ! ( ::rtl::math::isNan( x ) ||
+ ::rtl::math::isNan( y ) ||
+ ::rtl::math::isInf( x ) ||
+ ::rtl::math::isInf( y ) ||
+ x <= 0.0 );
+ }
+};
+
+class isValidAndYPositive : public ::std::binary_function< double, double, bool >
+{
+public:
+ inline bool operator()( double x, double y )
+ { return ! ( ::rtl::math::isNan( x ) ||
+ ::rtl::math::isNan( y ) ||
+ ::rtl::math::isInf( x ) ||
+ ::rtl::math::isInf( y ) ||
+ y <= 0.0 );
+ }
+};
+
+class isValidAndBothPositive : public ::std::binary_function< double, double, bool >
+{
+public:
+ inline bool operator()( double x, double y )
+ { return ! ( ::rtl::math::isNan( x ) ||
+ ::rtl::math::isNan( y ) ||
+ ::rtl::math::isInf( x ) ||
+ ::rtl::math::isInf( y ) ||
+ x <= 0.0 ||
+ y <= 0.0 );
+ }
+};
+
+} // namespace RegressionCalculationHelper
+} // namespace chart
+
+// CHART2_REGRESSIONCALCULATIONHELPER_HXX
+#endif
diff --git a/chart2/source/tools/RegressionCurveCalculator.cxx b/chart2/source/tools/RegressionCurveCalculator.cxx
new file mode 100644
index 000000000000..68e041e668ca
--- /dev/null
+++ b/chart2/source/tools/RegressionCurveCalculator.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "RegressionCurveCalculator.hxx"
+#include "RegressionCalculationHelper.hxx"
+#include "servicenames_coosystems.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <rtl/math.hxx>
+
+#include <com/sun/star/lang/XServiceName.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+RegressionCurveCalculator::RegressionCurveCalculator() :
+ m_fCorrelationCoeffitient( 0.0 )
+{
+ ::rtl::math::setNan( & m_fCorrelationCoeffitient );
+}
+
+RegressionCurveCalculator::~RegressionCurveCalculator()
+{}
+
+// static
+bool RegressionCurveCalculator::isLinearScaling(
+ const Reference< chart2::XScaling > & xScaling )
+{
+ // no scaling means linear
+ if( !xScaling.is())
+ return true;
+ static OUString aLinScalingServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.LinearScaling" ));
+ uno::Reference< lang::XServiceName > xServiceName( xScaling, uno::UNO_QUERY );
+ return (xServiceName.is() && xServiceName->getServiceName().equals( aLinScalingServiceName ));
+}
+
+// static
+bool RegressionCurveCalculator::isLogarithmicScaling(
+ const Reference< chart2::XScaling > & xScaling )
+{
+ static OUString aLogScalingServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.LogarithmicScaling" ));
+ uno::Reference< lang::XServiceName > xServiceName( xScaling, uno::UNO_QUERY );
+ return (xServiceName.is() && xServiceName->getServiceName().equals( aLogScalingServiceName ));
+}
+
+
+OUString RegressionCurveCalculator::getFormattedString(
+ const Reference< util::XNumberFormatter >& xNumFormatter,
+ ::sal_Int32 nNumberFormatKey,
+ double fNumber ) const
+{
+ OUString aResult;
+
+ if( xNumFormatter.is())
+ aResult = xNumFormatter->convertNumberToString( nNumberFormatKey, fNumber );
+ else
+ aResult = NUMBER_TO_STR( fNumber );
+
+ return aResult;
+}
+
+Sequence< geometry::RealPoint2D > SAL_CALL RegressionCurveCalculator::getCurveValues(
+ double min, double max, ::sal_Int32 nPointCount,
+ const Reference< chart2::XScaling >& xScalingX,
+ const Reference< chart2::XScaling >& /* xScalingY */,
+ ::sal_Bool /* bMaySkipPointsInCalculation */ )
+ throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if( nPointCount < 2 )
+ throw lang::IllegalArgumentException();
+
+ // determine if scaling and inverse scaling for x-values work
+ bool bDoXScaling( xScalingX.is());
+ uno::Reference< chart2::XScaling > xInverseScaling;
+ if( bDoXScaling )
+ xInverseScaling.set( xScalingX->getInverseScaling());
+ bDoXScaling = bDoXScaling && xInverseScaling.is();
+
+ Sequence< geometry::RealPoint2D > aResult( nPointCount );
+
+ double fMin( min );
+ double fFact = (max - min) / double(nPointCount-1);
+ if( bDoXScaling )
+ {
+ fMin = xScalingX->doScaling( min );
+ fFact = (xScalingX->doScaling( max ) - fMin) / double(nPointCount-1);
+ }
+
+ for(sal_Int32 nP=0; nP<nPointCount; nP++)
+ {
+ double x = fMin + nP * fFact;
+ if( bDoXScaling )
+ x = xInverseScaling->doScaling( x );
+ aResult[nP].X = x;
+ aResult[nP].Y = this->getCurveValue( x );
+ }
+
+ return aResult;
+}
+
+double SAL_CALL RegressionCurveCalculator::getCorrelationCoefficient()
+ throw (uno::RuntimeException)
+{
+ return m_fCorrelationCoeffitient;
+}
+
+OUString SAL_CALL RegressionCurveCalculator::getRepresentation()
+ throw (uno::RuntimeException)
+{
+ return ImplGetRepresentation( Reference< util::XNumberFormatter >(), 0 );
+}
+
+OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation(
+ const Reference< util::XNumberFormatsSupplier > & xNumFmtSupplier,
+ ::sal_Int32 nNumberFormatKey )
+ throw (uno::RuntimeException)
+{
+ // create and prepare a number formatter
+ if( !xNumFmtSupplier.is())
+ return getRepresentation();
+ Reference< util::XNumberFormatter > xNumFormatter;
+ Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
+ if( xFact.is())
+ xNumFormatter.set( xFact->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter"))), uno::UNO_QUERY );
+ if( !xNumFormatter.is())
+ return getRepresentation();
+ xNumFormatter->attachNumberFormatsSupplier( xNumFmtSupplier );
+
+ return ImplGetRepresentation( xNumFormatter, nNumberFormatKey );
+}
+
+
+} // namespace chart
diff --git a/chart2/source/tools/RegressionCurveHelper.cxx b/chart2/source/tools/RegressionCurveHelper.cxx
new file mode 100644
index 000000000000..b553dbc2d217
--- /dev/null
+++ b/chart2/source/tools/RegressionCurveHelper.cxx
@@ -0,0 +1,736 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "RegressionCurveHelper.hxx"
+#include "MeanValueRegressionCurveCalculator.hxx"
+#include "LinearRegressionCurveCalculator.hxx"
+#include "LogarithmicRegressionCurveCalculator.hxx"
+#include "ExponentialRegressionCurveCalculator.hxx"
+#include "PotentialRegressionCurveCalculator.hxx"
+#include "CommonConverters.hxx"
+#include "RegressionCurveModel.hxx"
+#include "ChartTypeHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "macros.hxx"
+#include "PropertyHelper.hxx"
+#include "ResId.hxx"
+#include "Strings.hrc"
+#include "DiagramHelper.hxx"
+#include <com/sun/star/chart2/XChartDocument.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::XComponentContext;
+using ::com::sun::star::lang::XServiceName;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::uno::Exception;
+using ::rtl::OUString;
+
+namespace
+{
+OUString lcl_getServiceNameForType( ::chart::RegressionCurveHelper::tRegressionType eType )
+{
+ OUString aServiceName;
+ switch( eType )
+ {
+ case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LINEAR:
+ aServiceName = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
+ break;
+ case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LOG:
+ aServiceName = C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
+ break;
+ case ::chart::RegressionCurveHelper::REGRESSION_TYPE_EXP:
+ aServiceName = C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
+ break;
+ case ::chart::RegressionCurveHelper::REGRESSION_TYPE_POWER:
+ aServiceName = C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
+ break;
+ default:
+ OSL_ENSURE(false,"unknown regression curve type - use linear instead");
+ aServiceName = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
+ break;
+ }
+ return aServiceName;
+}
+} // anonymous namespace
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+// static
+Reference< XRegressionCurve > RegressionCurveHelper::createMeanValueLine(
+ const Reference< XComponentContext > & xContext )
+{
+ return Reference< XRegressionCurve >(
+ new MeanValueRegressionCurve( xContext ));
+}
+
+// static
+Reference< XRegressionCurve > RegressionCurveHelper::createRegressionCurveByServiceName(
+ const Reference< XComponentContext > & xContext,
+ ::rtl::OUString aServiceName )
+{
+ Reference< XRegressionCurve > xResult;
+
+ // todo: use factory methods with service name
+ if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.LinearRegressionCurve" )))
+ {
+ xResult.set(
+ new LinearRegressionCurve( xContext ));
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.LogarithmicRegressionCurve" )))
+ {
+ xResult.set(
+ new LogarithmicRegressionCurve( xContext ));
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.ExponentialRegressionCurve" )))
+ {
+ xResult.set(
+ new ExponentialRegressionCurve( xContext ));
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.PotentialRegressionCurve" )))
+ {
+ xResult.set(
+ new PotentialRegressionCurve( xContext ));
+ }
+
+ return xResult;
+}
+
+// ------------------------------------------------------------
+
+// static
+Reference< XRegressionCurveCalculator > RegressionCurveHelper::createRegressionCurveCalculatorByServiceName(
+ ::rtl::OUString aServiceName )
+{
+ Reference< XRegressionCurveCalculator > xResult;
+
+ // todo: use factory methods with service name
+ if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.MeanValueRegressionCurve" )))
+ {
+ xResult.set( new MeanValueRegressionCurveCalculator());
+ }
+ if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.LinearRegressionCurve" )))
+ {
+ xResult.set( new LinearRegressionCurveCalculator());
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.LogarithmicRegressionCurve" )))
+ {
+ xResult.set( new LogarithmicRegressionCurveCalculator());
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.ExponentialRegressionCurve" )))
+ {
+ xResult.set( new ExponentialRegressionCurveCalculator());
+ }
+ else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.chart2.PotentialRegressionCurve" )))
+ {
+ xResult.set( new PotentialRegressionCurveCalculator());
+ }
+
+ return xResult;
+}
+
+// static
+void RegressionCurveHelper::initializeCurveCalculator(
+ const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
+ const Reference< data::XDataSource > & xSource,
+ bool bUseXValuesIfAvailable /* = true */ )
+{
+ if( ! (xOutCurveCalculator.is() &&
+ xSource.is() ))
+ return;
+
+ Sequence< double > aXValues, aYValues;
+ bool bXValuesFound = false, bYValuesFound = false;
+
+ Sequence< Reference< data::XLabeledDataSequence > > aDataSeqs( xSource->getDataSequences());
+ sal_Int32 i = 0;
+ for( i=0;
+ ! (bXValuesFound && bYValuesFound) && i<aDataSeqs.getLength();
+ ++i )
+ {
+ try
+ {
+ Reference< data::XDataSequence > xSeq( aDataSeqs[i]->getValues());
+ Reference< XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
+ ::rtl::OUString aRole;
+ if( xProp->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ))) >>= aRole )
+ {
+ if( bUseXValuesIfAvailable &&
+ ! bXValuesFound &&
+ aRole.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "values-x" )))
+ {
+ aXValues = DataSequenceToDoubleSequence( xSeq );
+ bXValuesFound = true;
+ }
+ else if( ! bYValuesFound &&
+ aRole.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "values-y" )))
+ {
+ aYValues = DataSequenceToDoubleSequence( xSeq );
+ bYValuesFound = true;
+ }
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ if( ! bXValuesFound &&
+ bYValuesFound )
+ {
+ // initialize with 1, 2, ...
+ //first category (index 0) matches with real number 1.0
+ aXValues.realloc( aYValues.getLength());
+ for( i=0; i<aXValues.getLength(); ++i )
+ aXValues[i] = i+1;
+ bXValuesFound = true;
+ }
+
+ if( bXValuesFound && bYValuesFound &&
+ aXValues.getLength() > 0 &&
+ aYValues.getLength() > 0 )
+ xOutCurveCalculator->recalculateRegression( aXValues, aYValues );
+}
+
+// static
+void RegressionCurveHelper::initializeCurveCalculator(
+ const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
+ const Reference< XDataSeries > & xSeries,
+ const Reference< frame::XModel > & xModel )
+{
+ sal_Int32 nAxisType = ChartTypeHelper::getAxisType(
+ ChartModelHelper::getChartTypeOfSeries( xModel, xSeries ), 0 ); // x-axis
+
+ initializeCurveCalculator( xOutCurveCalculator,
+ uno::Reference< data::XDataSource >( xSeries, uno::UNO_QUERY ),
+ (nAxisType == AxisType::REALNUMBER) );
+}
+
+// ----------------------------------------
+
+// static
+bool RegressionCurveHelper::hasMeanValueLine(
+ const uno::Reference< XRegressionCurveContainer > & xRegCnt )
+{
+ if( !xRegCnt.is())
+ return false;
+
+ try
+ {
+ uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( isMeanValueLine( aCurves[i] ))
+ return true;
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return false;
+}
+
+// static
+bool RegressionCurveHelper::isMeanValueLine(
+ const uno::Reference< chart2::XRegressionCurve > & xRegCurve )
+{
+ uno::Reference< XServiceName > xServName( xRegCurve, uno::UNO_QUERY );
+ if( xServName.is() &&
+ xServName->getServiceName().equals(
+ C2U( "com.sun.star.chart2.MeanValueRegressionCurve" )))
+ return true;
+ return false;
+}
+
+// static
+uno::Reference< chart2::XRegressionCurve >
+ RegressionCurveHelper::getMeanValueLine(
+ const uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
+{
+ if( xRegCnt.is())
+ {
+ try
+ {
+ uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( isMeanValueLine( aCurves[i] ))
+ return aCurves[i];
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+
+ return uno::Reference< chart2::XRegressionCurve >();
+}
+
+// static
+void RegressionCurveHelper::addMeanValueLine(
+ uno::Reference< XRegressionCurveContainer > & xRegCnt,
+ const uno::Reference< XComponentContext > & xContext,
+ const uno::Reference< XPropertySet > & xSeriesProp )
+{
+ if( !xRegCnt.is() ||
+ ::chart::RegressionCurveHelper::hasMeanValueLine( xRegCnt ) )
+ return;
+
+ // todo: use a valid context
+ uno::Reference< XRegressionCurve > xCurve( createMeanValueLine( xContext ));
+ xRegCnt->addRegressionCurve( xCurve );
+
+ if( xSeriesProp.is())
+ {
+ uno::Reference< XPropertySet > xProp( xCurve, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ xProp->setPropertyValue( C2U( "LineColor" ),
+ xSeriesProp->getPropertyValue( C2U( "Color" )));
+ }
+ }
+}
+
+// static
+void RegressionCurveHelper::removeMeanValueLine(
+ Reference< XRegressionCurveContainer > & xRegCnt )
+{
+ if( !xRegCnt.is())
+ return;
+
+ try
+ {
+ Sequence< Reference< XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( isMeanValueLine( aCurves[i] ))
+ {
+ xRegCnt->removeRegressionCurve( aCurves[i] );
+ // attention: the iterator i has become invalid now
+
+ // note: assume that there is only one mean-value curve
+ // to remove multiple mean-value curves remove the break
+ break;
+ }
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void RegressionCurveHelper::addRegressionCurve(
+ tRegressionType eType,
+ uno::Reference< XRegressionCurveContainer > & xRegCnt,
+ const uno::Reference< XComponentContext > & /* xContext */,
+ const uno::Reference< beans::XPropertySet >& xPropertySource,
+ const uno::Reference< beans::XPropertySet >& xEquationProperties )
+{
+ if( !xRegCnt.is() )
+ return;
+
+ if( eType == REGRESSION_TYPE_NONE )
+ {
+ OSL_ENSURE(false,"don't create a regression curve of type none");
+ return;
+ }
+
+ uno::Reference< chart2::XRegressionCurve > xCurve;
+ ::rtl::OUString aServiceName( lcl_getServiceNameForType( eType ));
+
+ if( aServiceName.getLength())
+ {
+ // todo: use a valid context
+ xCurve.set( createRegressionCurveByServiceName(
+ uno::Reference< uno::XComponentContext >(), aServiceName ));
+
+ if( xEquationProperties.is())
+ xCurve->setEquationProperties( xEquationProperties );
+
+ uno::Reference< beans::XPropertySet > xProp( xCurve, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ if( xPropertySource.is())
+ comphelper::copyProperties( xPropertySource, xProp );
+ else
+ {
+ uno::Reference< XPropertySet > xSeriesProp( xRegCnt, uno::UNO_QUERY );
+ if( xSeriesProp.is())
+ {
+ xProp->setPropertyValue( C2U( "LineColor" ),
+ xSeriesProp->getPropertyValue( C2U( "Color" )));
+ }
+// xProp->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( sal_Int32( 100 )));
+ }
+ }
+ }
+ xRegCnt->addRegressionCurve( xCurve );
+}
+
+/** removes all regression curves that are not of type mean value
+ and returns true, if anything was removed
+ */
+bool RegressionCurveHelper::removeAllExceptMeanValueLine(
+ uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
+{
+ bool bRemovedSomething = false;
+ if( xRegCnt.is())
+ {
+ try
+ {
+ uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ ::std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( ! isMeanValueLine( aCurves[i] ))
+ {
+ aCurvesToDelete.push_back( aCurves[ i ] );
+ }
+ }
+
+ for( ::std::vector< uno::Reference< chart2::XRegressionCurve > >::const_iterator aIt = aCurvesToDelete.begin();
+ aIt != aCurvesToDelete.end(); ++aIt )
+ {
+ xRegCnt->removeRegressionCurve( *aIt );
+ bRemovedSomething = true;
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ return bRemovedSomething;
+}
+
+void RegressionCurveHelper::removeEquations(
+ uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
+{
+ if( xRegCnt.is())
+ {
+ try
+ {
+ uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( !isMeanValueLine( aCurves[i] ) )
+ {
+ uno::Reference< chart2::XRegressionCurve > xRegCurve( aCurves[ i ] );
+ if( xRegCurve.is() )
+ {
+ uno::Reference< beans::XPropertySet > xEqProp( xRegCurve->getEquationProperties() ) ;
+ if( xEqProp.is())
+ {
+ xEqProp->setPropertyValue( C2U("ShowEquation"), uno::makeAny( false ));
+ xEqProp->setPropertyValue( C2U("ShowCorrelationCoefficient"), uno::makeAny( false ));
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+}
+
+// static
+void RegressionCurveHelper::replaceOrAddCurveAndReduceToOne(
+ tRegressionType eType,
+ uno::Reference< XRegressionCurveContainer > & xRegCnt,
+ const uno::Reference< XComponentContext > & xContext )
+{
+ uno::Reference< chart2::XRegressionCurve > xRegressionCurve( getFirstCurveNotMeanValueLine( xRegCnt ));
+ if( ! xRegressionCurve.is())
+ RegressionCurveHelper::addRegressionCurve( eType, xRegCnt, xContext );
+ else
+ {
+ OUString aServiceName( lcl_getServiceNameForType( eType ));
+ if( aServiceName.getLength())
+ {
+ RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCnt );
+ RegressionCurveHelper::addRegressionCurve(
+ eType, xRegCnt, xContext,
+ Reference< beans::XPropertySet >( xRegressionCurve, uno::UNO_QUERY ),
+ xRegressionCurve->getEquationProperties());
+ }
+ }
+}
+
+// static
+uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::getFirstCurveNotMeanValueLine(
+ const Reference< XRegressionCurveContainer > & xRegCnt )
+{
+ if( !xRegCnt.is())
+ return NULL;
+
+ try
+ {
+ uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ ::std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( ! isMeanValueLine( aCurves[i] ))
+ {
+ return aCurves[ i ];
+ }
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return NULL;
+}
+
+// static
+RegressionCurveHelper::tRegressionType RegressionCurveHelper::getRegressionType(
+ const Reference< XRegressionCurve > & xCurve )
+{
+ tRegressionType eResult = REGRESSION_TYPE_UNKNOWN;
+
+ try
+ {
+ Reference< lang::XServiceName > xServName( xCurve, uno::UNO_QUERY );
+ if( xServName.is())
+ {
+ ::rtl::OUString aServiceName( xServName->getServiceName() );
+
+ if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LinearRegressionCurve" )))
+ {
+ eResult = REGRESSION_TYPE_LINEAR;
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LogarithmicRegressionCurve" )))
+ {
+ eResult = REGRESSION_TYPE_LOG;
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ExponentialRegressionCurve" )))
+ {
+ eResult = REGRESSION_TYPE_EXP;
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.PotentialRegressionCurve" )))
+ {
+ eResult = REGRESSION_TYPE_POWER;
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.MeanValueRegressionCurve" )))
+ {
+ eResult = REGRESSION_TYPE_MEAN_VALUE;
+ }
+ }
+ }
+ catch( Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ return eResult;
+}
+
+// static
+RegressionCurveHelper::tRegressionType RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine(
+ const Reference< XRegressionCurveContainer > & xRegCnt )
+{
+ tRegressionType eResult = REGRESSION_TYPE_NONE;
+
+ if( xRegCnt.is())
+ {
+ Sequence< Reference< XRegressionCurve > > aCurves(
+ xRegCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ tRegressionType eType = getRegressionType( aCurves[i] );
+ if( eType != REGRESSION_TYPE_MEAN_VALUE &&
+ eType != REGRESSION_TYPE_UNKNOWN )
+ {
+ eResult = eType;
+ break;
+ }
+ }
+ }
+
+ return eResult;
+}
+
+OUString RegressionCurveHelper::getUINameForRegressionCurve( const Reference< XRegressionCurve >& xRegressionCurve )
+{
+ OUString aResult;
+ Reference< lang::XServiceName > xServiceName( xRegressionCurve, uno::UNO_QUERY );
+ if( ! xServiceName.is())
+ return aResult;
+
+ OUString aServiceName( xServiceName->getServiceName());
+ if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.MeanValueRegressionCurve" )))
+ {
+ OSL_ENSURE( false, "Meanvalue lines in legend not supported" );
+ aResult = OUString();
+ // aResult = ::chart::SchResId::getResString( STR_OBJECT_AVERAGE_LINE );
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LinearRegressionCurve" )))
+ {
+ aResult = ::chart::SchResId::getResString( STR_REGRESSION_LINEAR );
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LogarithmicRegressionCurve" )))
+ {
+ aResult = ::chart::SchResId::getResString( STR_REGRESSION_LOG );
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ExponentialRegressionCurve" )))
+ {
+ aResult = ::chart::SchResId::getResString( STR_REGRESSION_EXP );
+ }
+ else if( aServiceName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.PotentialRegressionCurve" )))
+ {
+ aResult = ::chart::SchResId::getResString( STR_REGRESSION_POWER );
+ }
+
+ return aResult;
+}
+
+// static
+::std::vector< Reference< chart2::XRegressionCurve > >
+ RegressionCurveHelper::getAllRegressionCurvesNotMeanValueLine(
+ const Reference< chart2::XDiagram > & xDiagram )
+{
+ ::std::vector< Reference< chart2::XRegressionCurve > > aResult;
+ ::std::vector< Reference< chart2::XDataSeries > > aSeries( DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
+ for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeries.begin());
+ aIt != aSeries.end(); ++aIt )
+ {
+ Reference< chart2::XRegressionCurveContainer > xCurveCnt( *aIt, uno::UNO_QUERY );
+ if( xCurveCnt.is())
+ {
+ uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
+ xCurveCnt->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( ! isMeanValueLine( aCurves[i] ))
+ aResult.push_back( aCurves[i] );
+ }
+ }
+ }
+
+ return aResult;
+}
+
+// static
+void RegressionCurveHelper::resetEquationPosition(
+ const Reference< chart2::XRegressionCurve > & xCurve )
+{
+ if( xCurve.is())
+ {
+ try
+ {
+ const OUString aPosPropertyName( RTL_CONSTASCII_USTRINGPARAM( "RelativePosition" ));
+ Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); // since m233: , uno::UNO_SET_THROW );
+ if( xEqProp->getPropertyValue( aPosPropertyName ).hasValue())
+ xEqProp->setPropertyValue( aPosPropertyName, uno::Any());
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+}
+
+sal_Int32 RegressionCurveHelper::getRegressionCurveIndex(
+ const Reference< chart2::XRegressionCurveContainer > & xContainer,
+ const Reference< chart2::XRegressionCurve > & xCurve )
+{
+ if( xContainer.is())
+ {
+ uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
+ xContainer->getRegressionCurves());
+ for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
+ {
+ if( xCurve == aCurves[i] )
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool RegressionCurveHelper::hasEquation( const Reference< chart2::XRegressionCurve > & xCurve )
+{
+ bool bHasEquation = false;
+ if( xCurve.is())
+ {
+ uno::Reference< beans::XPropertySet > xEquationProp( xCurve->getEquationProperties());
+ if( xEquationProp.is())
+ {
+ bool bShowEquation = false;
+ bool bShowCoefficient = false;
+ xEquationProp->getPropertyValue( C2U("ShowEquation")) >>= bShowEquation;
+ xEquationProp->getPropertyValue( C2U("ShowCorrelationCoefficient")) >>= bShowCoefficient;
+ bHasEquation = bShowEquation || bShowCoefficient;
+ }
+ }
+ return bHasEquation;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/RegressionCurveModel.cxx b/chart2/source/tools/RegressionCurveModel.cxx
new file mode 100644
index 000000000000..cf5be998308e
--- /dev/null
+++ b/chart2/source/tools/RegressionCurveModel.cxx
@@ -0,0 +1,441 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "RegressionCurveModel.hxx"
+#include "macros.hxx"
+#include "LineProperties.hxx"
+#include "RegressionCurveHelper.hxx"
+#include "RegressionCalculationHelper.hxx"
+#include "RegressionEquation.hxx"
+#include "ContainerHelper.hxx"
+#include "CloneHelper.hxx"
+#include "PropertyHelper.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::com::sun::star::beans::Property;
+using ::osl::MutexGuard;
+
+namespace
+{
+static const OUString lcl_aImplementationName_MeanValue(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.MeanValueRegressionCurve" ));
+static const OUString lcl_aImplementationName_Linear(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LinearRegressionCurve" ));
+static const OUString lcl_aImplementationName_Logarithmic(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LogarithmicRegressionCurve" ));
+static const OUString lcl_aImplementationName_Exponential(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ExponentialRegressionCurve" ));
+static const OUString lcl_aImplementationName_Potential(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.PotentialRegressionCurve" ));
+
+static const OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.RegressionCurve" ));
+
+const uno::Sequence< Property > & lcl_GetPropertySequence()
+{
+ static uno::Sequence< Property > aPropSeq;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aPropSeq.getLength() )
+ {
+ // get properties
+ ::std::vector< ::com::sun::star::beans::Property > aProperties;
+ ::chart::LineProperties::AddPropertiesToVector( aProperties );
+
+ // and sort them for access via bsearch
+ ::std::sort( aProperties.begin(), aProperties.end(),
+ ::chart::PropertyNameLess() );
+
+ // transfer result to static Sequence
+ aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
+ }
+
+ return aPropSeq;
+}
+
+::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper aArrayHelper(
+ lcl_GetPropertySequence(),
+ /* bSorted = */ sal_True );
+
+ return aArrayHelper;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+RegressionCurveModel::RegressionCurveModel(
+ uno::Reference< uno::XComponentContext > const & xContext,
+ tCurveType eCurveType ) :
+ ::property::OPropertySet( m_aMutex ),
+ m_xContext( xContext ),
+ m_eRegressionCurveType( eCurveType ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
+ m_xEquationProperties( new RegressionEquation( xContext ))
+{
+ // set 0 line width (default) hard, so that it is always written to XML,
+ // because the old implementation uses different defaults
+ setFastPropertyValue_NoBroadcast(
+ LineProperties::PROP_LINE_WIDTH, uno::makeAny( sal_Int32( 0 )));
+ ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
+}
+
+RegressionCurveModel::RegressionCurveModel( const RegressionCurveModel & rOther ) :
+ MutexContainer(),
+ impl::RegressionCurveModel_Base(),
+ ::property::OPropertySet( rOther, m_aMutex ),
+ m_xContext( rOther.m_xContext ),
+ m_eRegressionCurveType( rOther.m_eRegressionCurveType ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ m_xEquationProperties.set( CloneHelper::CreateRefClone< uno::Reference< beans::XPropertySet > >()( rOther.m_xEquationProperties ));
+ ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
+}
+
+RegressionCurveModel::~RegressionCurveModel()
+{}
+
+// ____ XRegressionCurve ____
+uno::Reference< chart2::XRegressionCurveCalculator > SAL_CALL
+ RegressionCurveModel::getCalculator()
+ throw (uno::RuntimeException)
+{
+ return RegressionCurveHelper::createRegressionCurveCalculatorByServiceName( getServiceName());
+}
+
+uno::Reference< beans::XPropertySet > SAL_CALL RegressionCurveModel::getEquationProperties()
+ throw (uno::RuntimeException)
+{
+ return m_xEquationProperties;
+}
+
+void SAL_CALL RegressionCurveModel::setEquationProperties( const uno::Reference< beans::XPropertySet >& xEquationProperties )
+ throw (uno::RuntimeException)
+{
+ if( xEquationProperties.is())
+ {
+ if( m_xEquationProperties.is())
+ ModifyListenerHelper::removeListener( m_xEquationProperties, m_xModifyEventForwarder );
+
+ m_xEquationProperties.set( xEquationProperties );
+ ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
+ fireModifyEvent();
+ }
+}
+
+// ____ XServiceName ____
+::rtl::OUString SAL_CALL RegressionCurveModel::getServiceName()
+ throw (uno::RuntimeException)
+{
+ switch( m_eRegressionCurveType )
+ {
+ case CURVE_TYPE_MEAN_VALUE:
+ return C2U( "com.sun.star.chart2.MeanValueRegressionCurve" );
+ case CURVE_TYPE_LINEAR:
+ return C2U( "com.sun.star.chart2.LinearRegressionCurve" );
+ case CURVE_TYPE_LOGARITHM:
+ return C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
+ case CURVE_TYPE_EXPONENTIAL:
+ return C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
+ case CURVE_TYPE_POWER:
+ return C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
+ }
+
+ return ::rtl::OUString();
+}
+
+// ____ XModifyBroadcaster ____
+void SAL_CALL RegressionCurveModel::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL RegressionCurveModel::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// ____ XModifyListener ____
+void SAL_CALL RegressionCurveModel::modified( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ m_xModifyEventForwarder->modified( aEvent );
+}
+
+// ____ XEventListener (base of XModifyListener) ____
+void SAL_CALL RegressionCurveModel::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ // nothing
+}
+
+// ____ OPropertySet ____
+void RegressionCurveModel::firePropertyChangeEvent()
+{
+ fireModifyEvent();
+}
+
+void RegressionCurveModel::fireModifyEvent()
+{
+ m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
+}
+
+// ================================================================================
+
+// ____ OPropertySet ____
+uno::Any RegressionCurveModel::GetDefaultValue( sal_Int32 nHandle ) const
+ throw(beans::UnknownPropertyException)
+{
+ static tPropertyValueMap aStaticDefaults;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aStaticDefaults.size() )
+ {
+ // initialize defaults
+ LineProperties::AddDefaultsToMap( aStaticDefaults );
+ }
+
+ tPropertyValueMap::const_iterator aFound(
+ aStaticDefaults.find( nHandle ));
+
+ if( aFound == aStaticDefaults.end())
+ return uno::Any();
+
+ return (*aFound).second;
+ // \--
+}
+
+::cppu::IPropertyArrayHelper & SAL_CALL RegressionCurveModel::getInfoHelper()
+{
+ return lcl_getInfoHelper();
+}
+
+
+// ____ XPropertySet ____
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ RegressionCurveModel::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is())
+ {
+ xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
+ getInfoHelper());
+ }
+
+ return xInfo;
+ // \--
+}
+
+// ================================================================================
+
+// needed by MSC compiler
+using impl::RegressionCurveModel_Base;
+
+IMPLEMENT_FORWARD_XINTERFACE2( RegressionCurveModel, RegressionCurveModel_Base, OPropertySet )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( RegressionCurveModel, RegressionCurveModel_Base, OPropertySet )
+
+
+
+// implementations
+
+// --------------------------------------------------------------------------------
+
+MeanValueRegressionCurve::MeanValueRegressionCurve(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_MEAN_VALUE )
+{}
+MeanValueRegressionCurve::MeanValueRegressionCurve(
+ const MeanValueRegressionCurve & rOther ) :
+ RegressionCurveModel( rOther )
+{}
+MeanValueRegressionCurve::~MeanValueRegressionCurve()
+{}
+uno::Sequence< ::rtl::OUString > MeanValueRegressionCurve::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.MeanValueRegressionCurve" );
+ return aServices;
+}
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( MeanValueRegressionCurve, lcl_aImplementationName_MeanValue );
+
+uno::Reference< util::XCloneable > SAL_CALL MeanValueRegressionCurve::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new MeanValueRegressionCurve( *this ));
+}
+
+// --------------------------------------------------------------------------------
+
+LinearRegressionCurve::LinearRegressionCurve(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_LINEAR )
+{}
+LinearRegressionCurve::LinearRegressionCurve(
+ const LinearRegressionCurve & rOther ) :
+ RegressionCurveModel( rOther )
+{}
+LinearRegressionCurve::~LinearRegressionCurve()
+{}
+uno::Sequence< ::rtl::OUString > LinearRegressionCurve::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
+ return aServices;
+}
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( LinearRegressionCurve, lcl_aImplementationName_Linear );
+
+uno::Reference< util::XCloneable > SAL_CALL LinearRegressionCurve::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new LinearRegressionCurve( *this ));
+}
+
+// --------------------------------------------------------------------------------
+
+LogarithmicRegressionCurve::LogarithmicRegressionCurve(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_LOGARITHM )
+{}
+LogarithmicRegressionCurve::LogarithmicRegressionCurve(
+ const LogarithmicRegressionCurve & rOther ) :
+ RegressionCurveModel( rOther )
+{}
+LogarithmicRegressionCurve::~LogarithmicRegressionCurve()
+{}
+uno::Sequence< ::rtl::OUString > LogarithmicRegressionCurve::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
+ return aServices;
+}
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( LogarithmicRegressionCurve, lcl_aImplementationName_Logarithmic );
+
+uno::Reference< util::XCloneable > SAL_CALL LogarithmicRegressionCurve::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new LogarithmicRegressionCurve( *this ));
+}
+
+// --------------------------------------------------------------------------------
+
+ExponentialRegressionCurve::ExponentialRegressionCurve(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_EXPONENTIAL )
+{}
+ExponentialRegressionCurve::ExponentialRegressionCurve(
+ const ExponentialRegressionCurve & rOther ) :
+ RegressionCurveModel( rOther )
+{}
+ExponentialRegressionCurve::~ExponentialRegressionCurve()
+{}
+uno::Sequence< ::rtl::OUString > ExponentialRegressionCurve::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
+ return aServices;
+}
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( ExponentialRegressionCurve, lcl_aImplementationName_Exponential );
+
+uno::Reference< util::XCloneable > SAL_CALL ExponentialRegressionCurve::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new ExponentialRegressionCurve( *this ));
+}
+
+// --------------------------------------------------------------------------------
+
+PotentialRegressionCurve::PotentialRegressionCurve(
+ const uno::Reference< uno::XComponentContext > & xContext )
+ : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_POWER )
+{}
+PotentialRegressionCurve::PotentialRegressionCurve(
+ const PotentialRegressionCurve & rOther ) :
+ RegressionCurveModel( rOther )
+{}
+PotentialRegressionCurve::~PotentialRegressionCurve()
+{}
+uno::Sequence< ::rtl::OUString > PotentialRegressionCurve::getSupportedServiceNames_Static()
+{
+ uno::Sequence< ::rtl::OUString > aServices( 2 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
+ return aServices;
+}
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( PotentialRegressionCurve, lcl_aImplementationName_Potential );
+
+uno::Reference< util::XCloneable > SAL_CALL PotentialRegressionCurve::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new PotentialRegressionCurve( *this ));
+}
+
+
+} // namespace chart
diff --git a/chart2/source/tools/RegressionCurveModel.hxx b/chart2/source/tools/RegressionCurveModel.hxx
new file mode 100644
index 000000000000..82098a76e45a
--- /dev/null
+++ b/chart2/source/tools/RegressionCurveModel.hxx
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART2_REGRESSIONCURVEMODEL_HXX
+#define CHART2_REGRESSIONCURVEMODEL_HXX
+
+#include "MutexContainer.hxx"
+#include "OPropertySet.hxx"
+#include "ServiceMacros.hxx"
+#include "ModifyListenerHelper.hxx"
+
+#include <cppuhelper/implbase6.hxx>
+#include <comphelper/uno3.hxx>
+
+#include <com/sun/star/chart2/XRegressionCurve.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+
+namespace chart
+{
+
+namespace impl
+{
+typedef ::cppu::WeakImplHelper6<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XServiceName,
+ ::com::sun::star::chart2::XRegressionCurve,
+ ::com::sun::star::util::XCloneable,
+ ::com::sun::star::util::XModifyBroadcaster,
+ ::com::sun::star::util::XModifyListener >
+ RegressionCurveModel_Base;
+}
+
+class RegressionCurveModel :
+ public MutexContainer,
+ public impl::RegressionCurveModel_Base,
+ public ::property::OPropertySet
+{
+public:
+ enum tCurveType
+ {
+ CURVE_TYPE_MEAN_VALUE,
+ CURVE_TYPE_LINEAR,
+ CURVE_TYPE_LOGARITHM,
+ CURVE_TYPE_EXPONENTIAL,
+ CURVE_TYPE_POWER
+ };
+
+ RegressionCurveModel( ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & xContext,
+ tCurveType eCurveType );
+ RegressionCurveModel( const RegressionCurveModel & rOther );
+ virtual ~RegressionCurveModel();
+
+ /// merge XInterface implementations
+ DECLARE_XINTERFACE()
+ /// merge XTypeProvider implementations
+ DECLARE_XTYPEPROVIDER()
+
+protected:
+ // ____ OPropertySet ____
+ virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
+ throw(::com::sun::star::beans::UnknownPropertyException);
+
+ // ____ OPropertySet ____
+ virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // ____ XPropertySet ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XRegressionCurve ____
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XRegressionCurveCalculator > SAL_CALL getCalculator()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL getEquationProperties()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setEquationProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xEquationProperties )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XServiceName ____
+ virtual ::rtl::OUString SAL_CALL getServiceName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XCloneable ____
+ // not implemented here
+// virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+// throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XModifyBroadcaster ____
+ virtual void SAL_CALL addModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XModifyListener ____
+ virtual void SAL_CALL modified(
+ const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XEventListener (base of XModifyListener) ____
+ virtual void SAL_CALL disposing(
+ const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ using ::cppu::OPropertySetHelper::disposing;
+
+ // ____ OPropertySet ____
+ virtual void firePropertyChangeEvent();
+
+ void fireModifyEvent();
+
+private:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext >
+ m_xContext;
+
+ const tCurveType m_eRegressionCurveType;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xModifyEventForwarder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xEquationProperties;
+};
+
+// implementations for factory instantiation
+
+class MeanValueRegressionCurve : public RegressionCurveModel
+{
+public:
+ explicit MeanValueRegressionCurve(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ explicit MeanValueRegressionCurve(
+ const MeanValueRegressionCurve & rOther );
+ virtual ~MeanValueRegressionCurve();
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( MeanValueRegressionCurve )
+};
+
+class LinearRegressionCurve : public RegressionCurveModel
+{
+public:
+ explicit LinearRegressionCurve(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ explicit LinearRegressionCurve(
+ const LinearRegressionCurve & rOther );
+ virtual ~LinearRegressionCurve();
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( LinearRegressionCurve )
+};
+
+class LogarithmicRegressionCurve : public RegressionCurveModel
+{
+public:
+ explicit LogarithmicRegressionCurve(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ explicit LogarithmicRegressionCurve(
+ const LogarithmicRegressionCurve & rOther );
+ virtual ~LogarithmicRegressionCurve();
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( LogarithmicRegressionCurve )
+};
+
+class ExponentialRegressionCurve : public RegressionCurveModel
+{
+public:
+ explicit ExponentialRegressionCurve(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ explicit ExponentialRegressionCurve(
+ const ExponentialRegressionCurve & rOther );
+ virtual ~ExponentialRegressionCurve();
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( ExponentialRegressionCurve )
+};
+
+class PotentialRegressionCurve : public RegressionCurveModel
+{
+public:
+ explicit PotentialRegressionCurve(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ explicit PotentialRegressionCurve(
+ const PotentialRegressionCurve & rOther );
+ virtual ~PotentialRegressionCurve();
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( PotentialRegressionCurve )
+};
+
+} // namespace chart
+
+// CHART2_REGRESSIONCURVEMODEL_HXX
+#endif
diff --git a/chart2/source/tools/RegressionEquation.cxx b/chart2/source/tools/RegressionEquation.cxx
new file mode 100644
index 000000000000..ea16e5b7702a
--- /dev/null
+++ b/chart2/source/tools/RegressionEquation.cxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "RegressionEquation.hxx"
+#include "LineProperties.hxx"
+#include "FillProperties.hxx"
+#include "UserDefinedProperties.hxx"
+#include "CharacterProperties.hxx"
+#include "PropertyHelper.hxx"
+#include "macros.hxx"
+#include "ContainerHelper.hxx"
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
+#include <com/sun/star/awt/Size.hpp>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::beans::Property;
+using ::osl::MutexGuard;
+
+// ____________________________________________________________
+
+namespace
+{
+
+static const ::rtl::OUString lcl_aImplementationName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.RegressionEquation" ));
+static const ::rtl::OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.RegressionEquation" ));
+
+enum
+{
+ PROP_EQUATION_SHOW,
+ PROP_EQUATION_SHOW_CORRELATION_COEFF,
+// PROP_EQUATION_SEPARATOR,
+ PROP_EQUATION_REF_PAGE_SIZE,
+ PROP_EQUATION_REL_POS,
+ PROP_EQUATION_NUMBER_FORMAT
+};
+
+void lcl_AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ rOutProperties.push_back(
+ Property( C2U( "ShowEquation" ),
+ PROP_EQUATION_SHOW,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "ShowCorrelationCoefficient" ),
+ PROP_EQUATION_SHOW_CORRELATION_COEFF,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+// rOutProperties.push_back(
+// Property( C2U( "Separator" ),
+// PROP_EQUATION_SEPARATOR,
+// ::getCppuType( reinterpret_cast< ::rtl::OUString * >(0)),
+// beans::PropertyAttribute::BOUND
+// | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
+ Property( C2U( "ReferencePageSize" ),
+ PROP_EQUATION_REF_PAGE_SIZE,
+ ::getCppuType( reinterpret_cast< const awt::Size * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "RelativePosition" ),
+ PROP_EQUATION_REL_POS,
+ ::getCppuType( reinterpret_cast< const chart2::RelativePosition * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
+ Property( C2U( "NumberFormat" ),
+ PROP_EQUATION_NUMBER_FORMAT,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+}
+
+void lcl_AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_EQUATION_SHOW, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_EQUATION_SHOW_CORRELATION_COEFF, false );
+// ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_EQUATION_SEPARATOR, ::rtl::OUString( sal_Unicode( '\n' )));
+
+ // override other defaults
+ ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::FillProperties::PROP_FILL_STYLE, drawing::FillStyle_NONE );
+ ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::LineProperties::PROP_LINE_STYLE, drawing::LineStyle_NONE );
+
+ float fDefaultCharHeight = 10.0;
+ ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight );
+ ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight );
+ ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight );
+}
+
+const uno::Sequence< Property > & lcl_GetPropertySequence()
+{
+ static uno::Sequence< Property > aPropSeq;
+
+ // /--
+ MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aPropSeq.getLength() )
+ {
+ // get properties
+ ::std::vector< ::com::sun::star::beans::Property > aProperties;
+ lcl_AddPropertiesToVector( aProperties );
+ ::chart::LineProperties::AddPropertiesToVector( aProperties );
+ ::chart::FillProperties::AddPropertiesToVector( aProperties );
+ ::chart::CharacterProperties::AddPropertiesToVector( aProperties );
+ ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );
+
+ // and sort them for access via bsearch
+ ::std::sort( aProperties.begin(), aProperties.end(),
+ ::chart::PropertyNameLess() );
+
+ // transfer result to static Sequence
+ aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
+ }
+
+ return aPropSeq;
+}
+
+::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper aArrayHelper(
+ lcl_GetPropertySequence(),
+ /* bSorted = */ sal_True );
+
+ return aArrayHelper;
+}
+
+} // anonymous namespace
+
+// ____________________________________________________________
+
+namespace chart
+{
+
+RegressionEquation::RegressionEquation( const Reference< uno::XComponentContext > & xContext ) :
+ ::property::OPropertySet( m_aMutex ),
+ m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder()),
+ m_xContext( xContext )
+{}
+
+RegressionEquation::RegressionEquation( const RegressionEquation & rOther ) :
+ MutexContainer(),
+ impl::RegressionEquation_Base(),
+ ::property::OPropertySet( rOther, m_aMutex ),
+ m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder())
+{}
+
+RegressionEquation::~RegressionEquation()
+{}
+
+
+// ____ XCloneable ____
+uno::Reference< util::XCloneable > SAL_CALL RegressionEquation::createClone()
+ throw (uno::RuntimeException)
+{
+ return uno::Reference< util::XCloneable >( new RegressionEquation( *this ));
+}
+
+// ____ OPropertySet ____
+uno::Any RegressionEquation::GetDefaultValue( sal_Int32 nHandle ) const
+ throw(beans::UnknownPropertyException)
+{
+ static tPropertyValueMap aStaticDefaults;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( 0 == aStaticDefaults.size() )
+ {
+ // initialize defaults
+ LineProperties::AddDefaultsToMap( aStaticDefaults );
+ FillProperties::AddDefaultsToMap( aStaticDefaults );
+ CharacterProperties::AddDefaultsToMap( aStaticDefaults );
+
+ // overrides a line property
+ lcl_AddDefaultsToMap( aStaticDefaults );
+ }
+
+ tPropertyValueMap::const_iterator aFound(
+ aStaticDefaults.find( nHandle ));
+
+ if( aFound == aStaticDefaults.end())
+ return uno::Any();
+
+ return (*aFound).second;
+ // \--
+}
+
+::cppu::IPropertyArrayHelper & SAL_CALL RegressionEquation::getInfoHelper()
+{
+ return lcl_getInfoHelper();
+}
+
+// ____ XPropertySet ____
+Reference< beans::XPropertySetInfo > SAL_CALL
+ RegressionEquation::getPropertySetInfo()
+ throw (uno::RuntimeException)
+{
+ static Reference< beans::XPropertySetInfo > xInfo;
+
+ // /--
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !xInfo.is())
+ {
+ xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
+ lcl_getInfoHelper());
+ }
+
+ return xInfo;
+ // \--
+}
+
+
+// ____ XModifyBroadcaster ____
+void SAL_CALL RegressionEquation::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL RegressionEquation::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+// ____ XModifyListener ____
+void SAL_CALL RegressionEquation::modified( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ m_xModifyEventForwarder->modified( aEvent );
+}
+
+// ____ XEventListener (base of XModifyListener) ____
+void SAL_CALL RegressionEquation::disposing( const lang::EventObject& /* Source */ )
+ throw (uno::RuntimeException)
+{
+ // nothing
+}
+
+// ____ OPropertySet ____
+void RegressionEquation::firePropertyChangeEvent()
+{
+ fireModifyEvent();
+}
+
+void RegressionEquation::fireModifyEvent()
+{
+ m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
+}
+
+// --------------------------------------------------------------------------------
+
+// ____ XTitle ____
+uno::Sequence< uno::Reference< chart2::XFormattedString > > SAL_CALL RegressionEquation::getText()
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ return m_aStrings;
+ // \--
+}
+
+void SAL_CALL RegressionEquation::setText( const uno::Sequence< uno::Reference< chart2::XFormattedString > >& Strings )
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ ModifyListenerHelper::removeListenerFromAllElements(
+ ContainerHelper::SequenceToVector( m_aStrings ), m_xModifyEventForwarder );
+ m_aStrings = Strings;
+ ModifyListenerHelper::addListenerToAllElements(
+ ContainerHelper::SequenceToVector( m_aStrings ), m_xModifyEventForwarder );
+ fireModifyEvent();
+ // \--
+}
+
+// ================================================================================
+
+uno::Sequence< ::rtl::OUString > RegressionEquation::getSupportedServiceNames_Static()
+{
+ const sal_Int32 nNumServices( 5 );
+ sal_Int32 nI = 0;
+ uno::Sequence< ::rtl::OUString > aServices( nNumServices );
+ aServices[ nI++ ] = lcl_aServiceName;
+ aServices[ nI++ ] = C2U( "com.sun.star.beans.PropertySet" );
+ aServices[ nI++ ] = C2U( "com.sun.star.drawing.FillProperties" );
+ aServices[ nI++ ] = C2U( "com.sun.star.drawing.LineProperties" );
+ aServices[ nI++ ] = C2U( "com.sun.star.style.CharacterProperties" );
+ OSL_ASSERT( nNumServices == nI );
+ return aServices;
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( RegressionEquation, lcl_aImplementationName );
+
+using impl::RegressionEquation_Base;
+
+IMPLEMENT_FORWARD_XINTERFACE2( RegressionEquation, RegressionEquation_Base, ::property::OPropertySet )
+
+} // namespace chart
diff --git a/chart2/source/tools/RegressionEquation.hxx b/chart2/source/tools/RegressionEquation.hxx
new file mode 100644
index 000000000000..35dbd828370d
--- /dev/null
+++ b/chart2/source/tools/RegressionEquation.hxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CHART2_REGRESSIONEQUATION_HXX
+#define CHART2_REGRESSIONEQUATION_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <com/sun/star/chart2/XTitle.hpp>
+
+#include "MutexContainer.hxx"
+#include "OPropertySet.hxx"
+#include "ServiceMacros.hxx"
+#include "ModifyListenerHelper.hxx"
+
+#include <cppuhelper/implbase4.hxx>
+#include <comphelper/uno3.hxx>
+
+namespace chart
+{
+
+namespace impl
+{
+typedef ::cppu::WeakImplHelper4<
+ ::com::sun::star::util::XCloneable,
+ ::com::sun::star::util::XModifyBroadcaster,
+ ::com::sun::star::util::XModifyListener,
+ ::com::sun::star::chart2::XTitle >
+ RegressionEquation_Base;
+}
+
+class RegressionEquation :
+ public MutexContainer,
+ public impl::RegressionEquation_Base,
+ public ::property::OPropertySet
+{
+public:
+ explicit RegressionEquation(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > & xContext );
+ virtual ~RegressionEquation();
+
+ /// XServiceInfo declarations
+ APPHELPER_XSERVICEINFO_DECL()
+ /// merge XInterface implementations
+ DECLARE_XINTERFACE()
+ /// establish methods for factory instatiation
+ APPHELPER_SERVICE_FACTORY_HELPER( RegressionEquation )
+
+protected:
+ explicit RegressionEquation( const RegressionEquation & rOther );
+
+ // ____ OPropertySet ____
+ virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
+ throw(::com::sun::star::beans::UnknownPropertyException);
+
+ virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // ____ XPropertySet ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw (::com::sun::star::uno::RuntimeException);
+
+
+ // ____ XCloneable ____
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XModifyBroadcaster ____
+ virtual void SAL_CALL addModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XModifyListener ____
+ virtual void SAL_CALL modified(
+ const ::com::sun::star::lang::EventObject& aEvent )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XEventListener (base of XModifyListener) ____
+ virtual void SAL_CALL disposing(
+ const ::com::sun::star::lang::EventObject& Source )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // ____ XTitle ____
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XFormattedString > > SAL_CALL getText()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setText( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XFormattedString > >& Strings )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ using ::cppu::OPropertySetHelper::disposing;
+
+ // ____ OPropertySet ____
+ virtual void firePropertyChangeEvent();
+
+ void fireModifyEvent();
+
+private:
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XFormattedString > > m_aStrings;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xModifyEventForwarder;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext >
+ m_xContext;
+};
+
+} // namespace chart
+
+// CHART2_REGRESSIONEQUATION_HXX
+#endif
diff --git a/chart2/source/tools/RelativePositionHelper.cxx b/chart2/source/tools/RelativePositionHelper.cxx
new file mode 100644
index 000000000000..4d566b1f7f48
--- /dev/null
+++ b/chart2/source/tools/RelativePositionHelper.cxx
@@ -0,0 +1,399 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "RelativePositionHelper.hxx"
+#include <rtl/math.hxx>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+// static
+chart2::RelativePosition RelativePositionHelper::getReanchoredPosition(
+ const chart2::RelativePosition & rPosition,
+ const chart2::RelativeSize & rObjectSize,
+ drawing::Alignment aNewAnchor )
+{
+ chart2::RelativePosition aResult( rPosition );
+ if( rPosition.Anchor != aNewAnchor )
+ {
+ sal_Int32 nShiftHalfWidths = 0;
+ sal_Int32 nShiftHalfHeights = 0;
+
+ // normalize to top-left
+ switch( rPosition.Anchor )
+ {
+ case drawing::Alignment_TOP_LEFT:
+ break;
+ case drawing::Alignment_LEFT:
+ nShiftHalfHeights -= 1;
+ break;
+ case drawing::Alignment_BOTTOM_LEFT:
+ nShiftHalfHeights -= 2;
+ break;
+ case drawing::Alignment_TOP:
+ nShiftHalfWidths -= 1;
+ break;
+ case drawing::Alignment_CENTER:
+ nShiftHalfWidths -= 1;
+ nShiftHalfHeights -= 1;
+ break;
+ case drawing::Alignment_BOTTOM:
+ nShiftHalfWidths -= 1;
+ nShiftHalfHeights -= 2;
+ break;
+ case drawing::Alignment_TOP_RIGHT:
+ nShiftHalfWidths -= 2;
+ break;
+ case drawing::Alignment_RIGHT:
+ nShiftHalfWidths -= 2;
+ nShiftHalfHeights -= 1;
+ break;
+ case drawing::Alignment_BOTTOM_RIGHT:
+ nShiftHalfWidths -= 2;
+ nShiftHalfHeights -= 2;
+ break;
+ case drawing::Alignment_MAKE_FIXED_SIZE:
+ break;
+ }
+
+ // transform
+ switch( aNewAnchor )
+ {
+ case drawing::Alignment_TOP_LEFT:
+ break;
+ case drawing::Alignment_LEFT:
+ nShiftHalfHeights += 1;
+ break;
+ case drawing::Alignment_BOTTOM_LEFT:
+ nShiftHalfHeights += 2;
+ break;
+ case drawing::Alignment_TOP:
+ nShiftHalfWidths += 1;
+ break;
+ case drawing::Alignment_CENTER:
+ nShiftHalfWidths += 1;
+ nShiftHalfHeights += 1;
+ break;
+ case drawing::Alignment_BOTTOM:
+ nShiftHalfWidths += 1;
+ nShiftHalfHeights += 2;
+ break;
+ case drawing::Alignment_TOP_RIGHT:
+ nShiftHalfWidths += 2;
+ break;
+ case drawing::Alignment_RIGHT:
+ nShiftHalfWidths += 2;
+ nShiftHalfHeights += 1;
+ break;
+ case drawing::Alignment_BOTTOM_RIGHT:
+ nShiftHalfWidths += 2;
+ nShiftHalfHeights += 2;
+ break;
+ case drawing::Alignment_MAKE_FIXED_SIZE:
+ break;
+ }
+
+ if( nShiftHalfWidths != 0 )
+ aResult.Primary += (rObjectSize.Primary / 2.0) * nShiftHalfWidths;
+ if( nShiftHalfHeights != 0 )
+ aResult.Secondary += (rObjectSize.Secondary / 2.0) * nShiftHalfHeights;
+ }
+
+ return aResult;
+}
+
+
+// static
+awt::Point RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
+ awt::Point aPoint
+ , awt::Size aObjectSize
+ , drawing::Alignment aAnchor )
+{
+ awt::Point aResult( aPoint );
+
+ double fXDelta = 0.0;
+ double fYDelta = 0.0;
+
+ // adapt x-value
+ switch( aAnchor )
+ {
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_BOTTOM:
+ fXDelta -= static_cast< double >( aObjectSize.Width ) / 2.0;
+ break;
+ case drawing::Alignment_TOP_RIGHT:
+ case drawing::Alignment_RIGHT:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ fXDelta -= aObjectSize.Width;
+ break;
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_BOTTOM_LEFT:
+ default:
+ // nothing to do
+ break;
+ }
+
+ // adapt y-value
+ switch( aAnchor )
+ {
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_RIGHT:
+ fYDelta -= static_cast< double >( aObjectSize.Height ) / 2.0;
+ break;
+ case drawing::Alignment_BOTTOM_LEFT:
+ case drawing::Alignment_BOTTOM:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ fYDelta -= aObjectSize.Height;
+ break;
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_TOP_RIGHT:
+ default:
+ // nothing to do
+ break;
+ }
+
+ aResult.X += static_cast< sal_Int32 >( ::rtl::math::round( fXDelta ));
+ aResult.Y += static_cast< sal_Int32 >( ::rtl::math::round( fYDelta ));
+
+ return aResult;
+}
+
+// static
+awt::Point RelativePositionHelper::getCenterOfAnchoredObject(
+ awt::Point aPoint
+ , awt::Size aUnrotatedObjectSize
+ , drawing::Alignment aAnchor
+ , double fAnglePi )
+{
+ awt::Point aResult( aPoint );
+
+ double fXDelta = 0.0;
+ double fYDelta = 0.0;
+
+ // adapt x-value
+ switch( aAnchor )
+ {
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_BOTTOM:
+ // nothing to do
+ break;
+ case drawing::Alignment_TOP_RIGHT:
+ case drawing::Alignment_RIGHT:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ fXDelta -= aUnrotatedObjectSize.Width/2;
+ break;
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_BOTTOM_LEFT:
+ default:
+ fXDelta += aUnrotatedObjectSize.Width/2;
+ break;
+ }
+
+ // adapt y-value
+ switch( aAnchor )
+ {
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_RIGHT:
+ // nothing to do
+ break;
+ case drawing::Alignment_BOTTOM_LEFT:
+ case drawing::Alignment_BOTTOM:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ fYDelta -= aUnrotatedObjectSize.Height/2;
+ break;
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_TOP_RIGHT:
+ fYDelta += aUnrotatedObjectSize.Height/2;
+ default:
+ // nothing to do
+ break;
+ }
+
+ //take rotation into account:
+ aResult.X += static_cast< sal_Int32 >(
+ ::rtl::math::round( fXDelta * rtl::math::cos( fAnglePi ) + fYDelta * rtl::math::sin( fAnglePi ) ) );
+ aResult.Y += static_cast< sal_Int32 >(
+ ::rtl::math::round( - fXDelta * rtl::math::sin( fAnglePi ) + fYDelta * rtl::math::cos( fAnglePi ) ) );
+
+ return aResult;
+}
+
+bool RelativePositionHelper::centerGrow(
+ chart2::RelativePosition & rInOutPosition,
+ chart2::RelativeSize & rInOutSize,
+ double fAmountX, double fAmountY,
+ bool bCheck /* = true */ )
+{
+ chart2::RelativePosition aPos( rInOutPosition );
+ chart2::RelativeSize aSize( rInOutSize );
+ const double fPosCheckThreshold = 0.02;
+ const double fSizeCheckThreshold = 0.1;
+
+ // grow/shrink, back to relaative
+ aSize.Primary += fAmountX;
+ aSize.Secondary += fAmountY;
+
+ double fShiftAmountX = fAmountX / 2.0;
+ double fShiftAmountY = fAmountY / 2.0;
+
+ // shift X
+ switch( rInOutPosition.Anchor )
+ {
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_BOTTOM_LEFT:
+ aPos.Primary -= fShiftAmountX;
+ break;
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_BOTTOM:
+ // nothing
+ break;
+ case drawing::Alignment_TOP_RIGHT:
+ case drawing::Alignment_RIGHT:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ aPos.Primary += fShiftAmountX;
+ break;
+ case drawing::Alignment_MAKE_FIXED_SIZE:
+ break;
+ }
+
+ // shift Y
+ switch( rInOutPosition.Anchor )
+ {
+ case drawing::Alignment_TOP:
+ case drawing::Alignment_TOP_LEFT:
+ case drawing::Alignment_TOP_RIGHT:
+ aPos.Secondary -= fShiftAmountY;
+ break;
+ case drawing::Alignment_CENTER:
+ case drawing::Alignment_LEFT:
+ case drawing::Alignment_RIGHT:
+ // nothing
+ break;
+ case drawing::Alignment_BOTTOM:
+ case drawing::Alignment_BOTTOM_LEFT:
+ case drawing::Alignment_BOTTOM_RIGHT:
+ aPos.Secondary += fShiftAmountY;
+ break;
+ case drawing::Alignment_MAKE_FIXED_SIZE:
+ break;
+ }
+
+ // anchor must not be changed
+ OSL_ASSERT( rInOutPosition.Anchor == aPos.Anchor );
+
+ if( rInOutPosition.Primary == aPos.Primary &&
+ rInOutPosition.Secondary == aPos.Secondary &&
+ rInOutSize.Primary == aSize.Primary &&
+ rInOutSize.Secondary == aSize.Secondary )
+ return false;
+
+ // check
+ if( bCheck )
+ {
+ // Note: this somewhat complicated check allows the output being
+ // out-of-bounds if the input was also out-of-bounds, and the change is
+ // for "advantage". E.g., you have a chart that laps out on the left
+ // side. If you shrink it, this should be possible, also if it still
+ // laps out on the left side afterwards. But you shouldn't be able to
+ // grow it then.
+
+ chart2::RelativePosition aUpperLeft(
+ RelativePositionHelper::getReanchoredPosition( aPos, aSize, drawing::Alignment_TOP_LEFT ));
+ chart2::RelativePosition aLowerRight(
+ RelativePositionHelper::getReanchoredPosition( aPos, aSize, drawing::Alignment_BOTTOM_RIGHT ));
+
+ // Do not grow, if this leads to corners being off-screen
+ if( fAmountX > 0.0 &&
+ ( (aUpperLeft.Primary < fPosCheckThreshold) ||
+ (aLowerRight.Primary > (1.0 - fPosCheckThreshold)) ))
+ return false;
+ if( fAmountY > 0.0 &&
+ ( (aUpperLeft.Secondary < fPosCheckThreshold) ||
+ (aLowerRight.Secondary > (1.0 - fPosCheckThreshold)) ))
+ return false;
+
+ // Do not shrink, if this leads to a size too small
+ if( fAmountX < 0.0 &&
+ ( aSize.Primary < fSizeCheckThreshold ))
+ return false;
+ if( fAmountY < 0.0 &&
+ ( aSize.Secondary < fSizeCheckThreshold ))
+ return false;
+ }
+
+ rInOutPosition = aPos;
+ rInOutSize = aSize;
+ return true;
+}
+
+bool RelativePositionHelper::moveObject(
+ chart2::RelativePosition & rInOutPosition,
+ const chart2::RelativeSize & rObjectSize,
+ double fAmountX, double fAmountY,
+ bool bCheck /* = true */ )
+{
+ chart2::RelativePosition aPos( rInOutPosition );
+ aPos.Primary += fAmountX;
+ aPos.Secondary += fAmountY;
+ const double fPosCheckThreshold = 0.02;
+
+ if( bCheck )
+ {
+ chart2::RelativePosition aUpperLeft(
+ RelativePositionHelper::getReanchoredPosition( aPos, rObjectSize, drawing::Alignment_TOP_LEFT ));
+ chart2::RelativePosition aLowerRight( aUpperLeft );
+ aLowerRight.Primary += rObjectSize.Primary;
+ aLowerRight.Secondary += rObjectSize.Secondary;
+
+ const double fFarEdgeThreshold = 1.0 - fPosCheckThreshold;
+ if( ( fAmountX > 0.0 && (aLowerRight.Primary > fFarEdgeThreshold)) ||
+ ( fAmountX < 0.0 && (aUpperLeft.Primary < fPosCheckThreshold)) ||
+ ( fAmountY > 0.0 && (aLowerRight.Secondary > fFarEdgeThreshold)) ||
+ ( fAmountY < 0.0 && (aUpperLeft.Secondary < fPosCheckThreshold)) )
+ return false;
+ }
+
+ rInOutPosition = aPos;
+ return true;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/RelativeSizeHelper.cxx b/chart2/source/tools/RelativeSizeHelper.cxx
new file mode 100644
index 000000000000..d3da090ca397
--- /dev/null
+++ b/chart2/source/tools/RelativeSizeHelper.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "RelativeSizeHelper.hxx"
+#include "macros.hxx"
+
+#include <vector>
+#include <algorithm>
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::std;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::uno::Exception;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+// static
+double RelativeSizeHelper::calculate(
+ double fValue,
+ const Size & rOldReferenceSize,
+ const Size & rNewReferenceSize )
+{
+ if( rOldReferenceSize.Width <= 0 ||
+ rOldReferenceSize.Height <= 0 )
+ return fValue;
+
+ return min(
+ static_cast< double >( rNewReferenceSize.Width ) / static_cast< double >( rOldReferenceSize.Width ),
+ static_cast< double >( rNewReferenceSize.Height ) / static_cast< double >( rOldReferenceSize.Height ))
+ * fValue;
+}
+
+// static
+void RelativeSizeHelper::adaptFontSizes(
+ const Reference< XPropertySet > & xTargetProperties,
+ const Size & rOldReferenceSize,
+ const Size & rNewReferenceSize )
+{
+ if( ! xTargetProperties.is())
+ return;
+
+ float fFontHeight = 0;
+
+ vector< OUString > aProperties;
+ aProperties.push_back( OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" )));
+ aProperties.push_back( OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeightAsian" )));
+ aProperties.push_back( OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeightComplex" )));
+
+ for( vector< OUString >::const_iterator aIt = aProperties.begin();
+ aIt != aProperties.end(); ++aIt )
+ {
+ try
+ {
+ if( xTargetProperties->getPropertyValue( *aIt ) >>= fFontHeight )
+ {
+ xTargetProperties->setPropertyValue(
+ *aIt,
+ makeAny( static_cast< float >(
+ calculate( fFontHeight, rOldReferenceSize, rNewReferenceSize ))));
+ }
+ }
+ catch( const Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/ResId.cxx b/chart2/source/tools/ResId.cxx
new file mode 100644
index 000000000000..0d6e35974aaa
--- /dev/null
+++ b/chart2/source/tools/ResId.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ResId.hxx"
+#include "RessourceManager.hxx"
+#include <tools/string.hxx>
+
+namespace chart
+{
+
+SchResId::SchResId( sal_Int16 nId )
+ : ResId( nId, RessourceManager::getRessourceManager() )
+{}
+
+::rtl::OUString SchResId::getResString( sal_Int16 nId )
+{
+ return ::rtl::OUString( String( SchResId( nId )));
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/RessourceManager.cxx b/chart2/source/tools/RessourceManager.cxx
new file mode 100644
index 000000000000..a2d43b309019
--- /dev/null
+++ b/chart2/source/tools/RessourceManager.cxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "RessourceManager.hxx"
+
+#include <tools/resmgr.hxx>
+
+namespace chart
+{
+
+ResMgr * RessourceManager::m_pRessourceManager = 0;
+
+ResMgr & RessourceManager::getRessourceManager()
+{
+ // not threadsafe
+ if( ! m_pRessourceManager )
+ m_pRessourceManager = CREATEVERSIONRESMGR( chartcontroller );
+ OSL_ASSERT( m_pRessourceManager );
+ return *m_pRessourceManager;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/Scaling.cxx b/chart2/source/tools/Scaling.cxx
new file mode 100644
index 000000000000..e106f1dcc5e2
--- /dev/null
+++ b/chart2/source/tools/Scaling.cxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "Scaling.hxx"
+#include <rtl/math.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+namespace
+{
+
+static const ::rtl::OUString lcl_aServiceName_Logarithmic(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.LogarithmicScaling" ));
+static const ::rtl::OUString lcl_aServiceName_Exponential(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.ExponentialScaling" ));
+static const ::rtl::OUString lcl_aServiceName_Linear(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.LinearScaling" ));
+static const ::rtl::OUString lcl_aServiceName_Power(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.PowerScaling" ));
+
+static const ::rtl::OUString lcl_aImplementationName_Logarithmic(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LogarithmicScaling" ));
+static const ::rtl::OUString lcl_aImplementationName_Exponential(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ExponentialScaling" ));
+static const ::rtl::OUString lcl_aImplementationName_Linear(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LinearScaling" ));
+static const ::rtl::OUString lcl_aImplementationName_Power(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.PowerScaling" ));
+}
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+LogarithmicScaling::LogarithmicScaling( const uno::Reference< uno::XComponentContext > & xContext ) :
+ m_fBase( 10.0 ),
+ m_fLogOfBase( log( 10.0 ) ),
+ m_xContext( xContext )
+{
+}
+
+LogarithmicScaling::LogarithmicScaling( double fBase ) :
+ m_fBase( fBase ),
+ m_fLogOfBase( log( fBase ) )
+{
+}
+
+LogarithmicScaling::~LogarithmicScaling()
+{
+}
+
+ double SAL_CALL
+LogarithmicScaling::doScaling( double value )
+ throw (uno::RuntimeException)
+{
+ double fResult;
+ if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
+ ::rtl::math::setNan( & fResult );
+ else
+ fResult = log( value ) / m_fLogOfBase;
+ return fResult;
+}
+
+ uno::Reference< XScaling > SAL_CALL
+LogarithmicScaling::getInverseScaling()
+ throw (uno::RuntimeException)
+{
+ return new ExponentialScaling( m_fBase );
+}
+
+ ::rtl::OUString SAL_CALL
+LogarithmicScaling::getServiceName()
+ throw (uno::RuntimeException)
+{
+ return lcl_aServiceName_Logarithmic;
+}
+
+uno::Sequence< ::rtl::OUString > LogarithmicScaling::getSupportedServiceNames_Static()
+{
+ return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_Logarithmic, 1 );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( LogarithmicScaling, lcl_aServiceName_Logarithmic )
+
+// ----------------------------------------
+
+ExponentialScaling::ExponentialScaling( const uno::Reference< uno::XComponentContext > & xContext ) :
+ m_fBase( 10.0 ),
+ m_xContext( xContext )
+{
+}
+
+ExponentialScaling::ExponentialScaling( double fBase ) :
+ m_fBase( fBase )
+{
+}
+
+ExponentialScaling::~ExponentialScaling()
+{
+}
+
+ double SAL_CALL
+ExponentialScaling::doScaling( double value )
+ throw (uno::RuntimeException)
+{
+ double fResult;
+ if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
+ ::rtl::math::setNan( & fResult );
+ else
+ fResult = pow( m_fBase, value );
+ return fResult;
+}
+
+ uno::Reference< XScaling > SAL_CALL
+ExponentialScaling::getInverseScaling()
+ throw (uno::RuntimeException)
+{
+ return new LogarithmicScaling( m_fBase );
+}
+
+ ::rtl::OUString SAL_CALL
+ExponentialScaling::getServiceName()
+ throw (uno::RuntimeException)
+{
+ return lcl_aServiceName_Exponential;
+}
+
+uno::Sequence< ::rtl::OUString > ExponentialScaling::getSupportedServiceNames_Static()
+{
+ return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_Exponential, 1 );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( ExponentialScaling, lcl_aServiceName_Exponential )
+
+// ----------------------------------------
+
+LinearScaling::LinearScaling( const uno::Reference< uno::XComponentContext > & xContext ) :
+ m_fSlope( 1.0 ),
+ m_fOffset( 0.0 ),
+ m_xContext( xContext )
+{}
+
+LinearScaling::LinearScaling( double fSlope, double fOffset ) :
+ m_fSlope( fSlope ),
+ m_fOffset( fOffset )
+{}
+
+LinearScaling::~LinearScaling()
+{}
+
+double SAL_CALL LinearScaling::doScaling( double value )
+ throw (uno::RuntimeException)
+{
+ double fResult;
+ if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
+ ::rtl::math::setNan( & fResult );
+ else
+ fResult = m_fOffset + m_fSlope * value;
+ return fResult;
+}
+
+uno::Reference< XScaling > SAL_CALL
+ LinearScaling::getInverseScaling()
+ throw (uno::RuntimeException)
+{
+ // ToDo: ApproxEqual ?
+ if( m_fSlope == 0 )
+ throw uno::RuntimeException();
+
+ return new LinearScaling( 1.0 / m_fSlope, m_fOffset / m_fSlope );
+}
+
+ ::rtl::OUString SAL_CALL
+LinearScaling::getServiceName()
+ throw (uno::RuntimeException)
+{
+ return lcl_aServiceName_Linear;
+}
+
+uno::Sequence< ::rtl::OUString > LinearScaling::getSupportedServiceNames_Static()
+{
+ return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_Linear, 1 );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( LinearScaling, lcl_aServiceName_Linear )
+
+// ----------------------------------------
+
+PowerScaling::PowerScaling( const uno::Reference< uno::XComponentContext > & xContext ) :
+ m_fExponent( 10.0 ),
+ m_xContext( xContext )
+{}
+
+PowerScaling::PowerScaling( double fExponent ) :
+ m_fExponent( fExponent )
+{}
+
+PowerScaling::~PowerScaling()
+{}
+
+double SAL_CALL PowerScaling::doScaling( double value )
+ throw (uno::RuntimeException)
+{
+ double fResult;
+ if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
+ ::rtl::math::setNan( & fResult );
+ else
+ fResult = pow( value, m_fExponent );
+ return fResult;
+}
+
+uno::Reference< XScaling > SAL_CALL
+ PowerScaling::getInverseScaling()
+ throw (uno::RuntimeException)
+{
+ // ToDo: ApproxEqual ?
+ if( m_fExponent == 0 )
+ throw uno::RuntimeException();
+
+ return new PowerScaling( 1.0 / m_fExponent );
+}
+
+ ::rtl::OUString SAL_CALL
+PowerScaling::getServiceName()
+ throw (uno::RuntimeException)
+{
+ return lcl_aServiceName_Power;
+}
+
+uno::Sequence< ::rtl::OUString > PowerScaling::getSupportedServiceNames_Static()
+{
+ return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_Power, 1 );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( PowerScaling, lcl_aServiceName_Power )
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/SceneProperties.cxx b/chart2/source/tools/SceneProperties.cxx
new file mode 100644
index 000000000000..21a95d99be7d
--- /dev/null
+++ b/chart2/source/tools/SceneProperties.cxx
@@ -0,0 +1,382 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "SceneProperties.hxx"
+#include "macros.hxx"
+#include "ChartTypeHelper.hxx"
+#include "ThreeDHelper.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/HomogenMatrix.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/CameraGeometry.hpp>
+
+// for F_PI
+#include <tools/solar.h>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+
+namespace chart
+{
+
+void SceneProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ // transformation matrix
+ rOutProperties.push_back(
+ Property( C2U( "D3DTransformMatrix" ),
+ PROP_SCENE_TRANSF_MATRIX,
+ ::getCppuType( reinterpret_cast< const drawing::HomogenMatrix * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // distance: deprecated ( this is not used by the chart view; it's only here for compatibility with old chart )
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneDistance" ),
+ PROP_SCENE_DISTANCE,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // focalLength: deprecated ( this is not used by the chart view; it's only here for compatibility with old chart )
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneFocalLength" ),
+ PROP_SCENE_FOCAL_LENGTH,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // shadowSlant
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneShadowSlant" ),
+ PROP_SCENE_SHADOW_SLANT,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // shadeMode
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneShadeMode" ),
+ PROP_SCENE_SHADE_MODE,
+ ::getCppuType( reinterpret_cast< const drawing::ShadeMode * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // ambientColor
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneAmbientColor" ),
+ PROP_SCENE_AMBIENT_COLOR,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // lightingMode
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneTwoSidedLighting" ),
+ PROP_SCENE_TWO_SIDED_LIGHTING,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // camera geometry
+ rOutProperties.push_back(
+ Property( C2U( "D3DCameraGeometry" ),
+ PROP_SCENE_CAMERA_GEOMETRY,
+ ::getCppuType( reinterpret_cast< const drawing::CameraGeometry * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ // perspective
+ rOutProperties.push_back(
+ Property( C2U( "D3DScenePerspective" ),
+ PROP_SCENE_PERSPECTIVE,
+ ::getCppuType( reinterpret_cast< const drawing::ProjectionMode * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+
+ // Light Sources
+ // -------------
+ // light source 1
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor1" ),
+ PROP_SCENE_LIGHT_COLOR_1,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection1" ),
+ PROP_SCENE_LIGHT_DIRECTION_1,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn1" ),
+ PROP_SCENE_LIGHT_ON_1,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 2
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor2" ),
+ PROP_SCENE_LIGHT_COLOR_2,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection2" ),
+ PROP_SCENE_LIGHT_DIRECTION_2,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn2" ),
+ PROP_SCENE_LIGHT_ON_2,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 3
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor3" ),
+ PROP_SCENE_LIGHT_COLOR_3,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection3" ),
+ PROP_SCENE_LIGHT_DIRECTION_3,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn3" ),
+ PROP_SCENE_LIGHT_ON_3,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 4
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor4" ),
+ PROP_SCENE_LIGHT_COLOR_4,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection4" ),
+ PROP_SCENE_LIGHT_DIRECTION_4,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn4" ),
+ PROP_SCENE_LIGHT_ON_4,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 5
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor5" ),
+ PROP_SCENE_LIGHT_COLOR_5,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection5" ),
+ PROP_SCENE_LIGHT_DIRECTION_5,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn5" ),
+ PROP_SCENE_LIGHT_ON_5,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 6
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor6" ),
+ PROP_SCENE_LIGHT_COLOR_6,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection6" ),
+ PROP_SCENE_LIGHT_DIRECTION_6,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn6" ),
+ PROP_SCENE_LIGHT_ON_6,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 7
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor7" ),
+ PROP_SCENE_LIGHT_COLOR_7,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection7" ),
+ PROP_SCENE_LIGHT_DIRECTION_7,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn7" ),
+ PROP_SCENE_LIGHT_ON_7,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ // light source 8
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightColor8" ),
+ PROP_SCENE_LIGHT_COLOR_8,
+ ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightDirection8" ),
+ PROP_SCENE_LIGHT_DIRECTION_8,
+ ::getCppuType( reinterpret_cast< const drawing::Direction3D * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+ rOutProperties.push_back(
+ Property( C2U( "D3DSceneLightOn8" ),
+ PROP_SCENE_LIGHT_ON_8,
+ ::getBooleanCppuType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+}
+
+void SceneProperties::AddDefaultsToMap(
+ ::chart::tPropertyValueMap & rOutMap )
+{
+ // Identity Matrix
+ drawing::HomogenMatrix aMtx;
+ aMtx.Line1.Column1 = aMtx.Line2.Column2 =
+ aMtx.Line3.Column3 = aMtx.Line4.Column4 = 1.0;
+ aMtx.Line1.Column2 = aMtx.Line1.Column3 = aMtx.Line1.Column4 =
+ aMtx.Line2.Column1 = aMtx.Line2.Column3 = aMtx.Line2.Column4 =
+ aMtx.Line3.Column1 = aMtx.Line3.Column2 = aMtx.Line3.Column4 =
+ aMtx.Line4.Column1 = aMtx.Line4.Column2 = aMtx.Line4.Column3 = 0.0;
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_TRANSF_MATRIX, aMtx );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCENE_DISTANCE, 4200 );
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCENE_FOCAL_LENGTH, 8000 );
+
+// PROP_SCENE_SHADOW_SLANT;
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_SHADE_MODE, drawing::ShadeMode_SMOOTH );
+
+ ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >(
+ rOutMap, PROP_SCENE_AMBIENT_COLOR, ChartTypeHelper::getDefaultAmbientLightColor(ThreeDLookScheme_Simple,0));
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_TWO_SIDED_LIGHTING, true );
+
+ drawing::Position3D vrp( 0.0, 0.0, 1.0 );
+ drawing::Direction3D vpn( 0.0, 0.0, 1.0 );
+ drawing::Direction3D vup( 0.0, 1.0, 0.0 );
+ drawing::CameraGeometry aDefaultCameraGeometry( vrp, vpn, vup );
+
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_CAMERA_GEOMETRY, aDefaultCameraGeometry );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_PERSPECTIVE, drawing::ProjectionMode_PERSPECTIVE );
+
+ // Light Sources
+ // -------------
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_1, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_2, true );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_3, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_4, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_5, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_6, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_7, false );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_ON_8, false );
+
+ uno::Any aDefaultLightDirection( uno::makeAny( drawing::Direction3D( 0.0, 0.0, 1.0 ) ) );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_1, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_2, ChartTypeHelper::getDefaultSimpleLightDirection(0));
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_3, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_4, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_5, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_6, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_7, aDefaultLightDirection );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_DIRECTION_8, aDefaultLightDirection );
+
+ uno::Any aDefaultLightColor;
+ aDefaultLightColor <<= ChartTypeHelper::getDefaultDirectLightColor(ThreeDLookScheme_Simple,0);
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_1, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_2, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_3, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_4, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_5, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_6, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_7, aDefaultLightColor );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCENE_LIGHT_COLOR_8, aDefaultLightColor );
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/StatisticsHelper.cxx b/chart2/source/tools/StatisticsHelper.cxx
new file mode 100644
index 000000000000..721451c276da
--- /dev/null
+++ b/chart2/source/tools/StatisticsHelper.cxx
@@ -0,0 +1,403 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "StatisticsHelper.hxx"
+#include "DataSeriesHelper.hxx"
+#include "ErrorBar.hxx"
+#include "macros.hxx"
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
+#include <com/sun/star/chart2/data/XDataSink.hpp>
+#include <com/sun/star/chart/ErrorBarStyle.hpp>
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star;
+
+namespace
+{
+
+double lcl_getVariance( const Sequence< double > & rData, sal_Int32 & rOutValidCount,
+ bool bUnbiasedEstimator )
+{
+ const sal_Int32 nCount = rData.getLength();
+ rOutValidCount = nCount;
+
+ double fSum = 0.0;
+ double fQuadSum = 0.0;
+
+ for( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ const double fData = rData[i];
+ if( ::rtl::math::isNan( fData ))
+ --rOutValidCount;
+ else
+ {
+ fSum += fData;
+ fQuadSum += fData * fData;
+ }
+ }
+
+ double fResult;
+ if( rOutValidCount == 0 )
+ ::rtl::math::setNan( & fResult );
+ else
+ {
+ const double fN = static_cast< double >( rOutValidCount );
+ if( bUnbiasedEstimator )
+ fResult = (fQuadSum - fSum*fSum/fN) / (fN - 1);
+ else
+ fResult = (fQuadSum - fSum*fSum/fN) / fN;
+ }
+
+ return fResult;
+}
+
+Reference< chart2::data::XLabeledDataSequence > lcl_getErrorBarLabeledSequence(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ bool bPositiveValue, bool bYError,
+ OUString & rOutRoleNameUsed )
+{
+ OUStringBuffer aRole( C2U("error-bars-"));
+ if( bYError )
+ aRole.append( sal_Unicode( 'y' ));
+ else
+ aRole.append( sal_Unicode( 'x' ));
+
+ OUString aPlainRole = aRole.makeStringAndClear();
+ aRole.append( aPlainRole );
+ aRole.append( sal_Unicode( '-' ));
+
+ if( bPositiveValue )
+ aRole = aRole.appendAscii( "positive" );
+ else
+ aRole = aRole.appendAscii( "negative" );
+
+ OUString aLongRole = aRole.makeStringAndClear();
+ Reference< chart2::data::XLabeledDataSequence > xLSeq(
+ ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aLongRole ));
+ // try role without "-negative" or "-positive" postfix
+ if( xLSeq.is())
+ rOutRoleNameUsed = aLongRole;
+ else
+ {
+ xLSeq.set( ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aPlainRole ));
+ if( xLSeq.is())
+ rOutRoleNameUsed = aPlainRole;
+ else
+ rOutRoleNameUsed = aLongRole;
+ }
+
+ return xLSeq;
+}
+
+void lcl_setRole(
+ const Reference< chart2::data::XDataSequence > & xNewSequence,
+ const OUString & rRole )
+{
+ Reference< beans::XPropertySet > xSeqProp( xNewSequence, uno::UNO_QUERY );
+ if( xSeqProp.is())
+ xSeqProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
+}
+
+void lcl_addSequenceToDataSource(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ const Reference< chart2::data::XDataSequence > & xNewSequence,
+ const OUString & rRole )
+{
+ Reference< chart2::data::XDataSink > xSink( xDataSource, uno::UNO_QUERY );
+ Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ if( ! ( xFact.is() && xSink.is() ))
+ return;
+
+ Reference< chart2::data::XLabeledDataSequence > xLSeq(
+ xFact->createInstance( C2U("com.sun.star.chart2.data.LabeledDataSequence")), uno::UNO_QUERY );
+ if( xLSeq.is())
+ {
+ lcl_setRole( xNewSequence, rRole );
+ xLSeq->setValues( xNewSequence );
+ Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
+ xDataSource->getDataSequences());
+ aSequences.realloc( aSequences.getLength() + 1 );
+ aSequences[ aSequences.getLength() - 1 ] = xLSeq;
+ xSink->setData( aSequences );
+ }
+}
+
+void lcl_setXMLRangePropertyAtDataSequence(
+ const Reference< chart2::data::XDataSequence > & xDataSequence,
+ const OUString & rXMLRange )
+{
+ try
+ {
+ const OUString aXMLRangePropName( C2U( "CachedXMLRange" ));
+ Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
+ Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
+ if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
+ xProp->setPropertyValue( aXMLRangePropName, uno::makeAny( rXMLRange ));
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+// static
+double StatisticsHelper::getVariance(
+ const Sequence< double > & rData,
+ bool bUnbiasedEstimator /* = false */ )
+{
+ sal_Int32 nValCount;
+ return lcl_getVariance( rData, nValCount, bUnbiasedEstimator );
+}
+
+// static
+double StatisticsHelper::getStandardDeviation( const Sequence< double > & rData )
+{
+ double fResult = getVariance( rData );
+ if( ! ::rtl::math::isNan( fResult ))
+ fResult = sqrt( fResult );
+
+ return fResult;
+}
+
+// static
+double StatisticsHelper::getStandardError( const Sequence< double > & rData )
+{
+ sal_Int32 nValCount;
+ double fVar = lcl_getVariance( rData, nValCount, false );
+ double fResult;
+
+ if( nValCount == 0 ||
+ ::rtl::math::isNan( fVar ))
+ {
+ ::rtl::math::setNan( & fResult );
+ }
+ else
+ {
+ // standard-deviation / sqrt(n)
+ fResult = sqrt( fVar ) / sqrt( double(nValCount) );
+ }
+
+ return fResult;
+}
+
+// static
+Reference< chart2::data::XLabeledDataSequence > StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ bool bPositiveValue,
+ bool bYError /* = true */ )
+{
+ Reference< chart2::data::XLabeledDataSequence > xResult;
+ if( !xDataSource.is())
+ return xResult;
+
+ OUString aRole;
+ Reference< chart2::data::XLabeledDataSequence > xLSeq(
+ lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
+ if( xLSeq.is())
+ xResult.set( xLSeq );
+
+ return xResult;
+}
+
+// static
+Reference< chart2::data::XDataSequence > StatisticsHelper::getErrorDataSequenceFromDataSource(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ bool bPositiveValue,
+ bool bYError /* = true */ )
+{
+ Reference< chart2::data::XLabeledDataSequence > xLSeq(
+ StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
+ xDataSource, bPositiveValue,
+ bYError ));
+ if( !xLSeq.is())
+ return Reference< chart2::data::XDataSequence >();
+
+ return xLSeq->getValues();
+}
+
+// static
+double StatisticsHelper::getErrorFromDataSource(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ sal_Int32 nIndex,
+ bool bPositiveValue,
+ bool bYError /* = true */ )
+{
+ double fResult = 0.0;
+ ::rtl::math::setNan( & fResult );
+
+ Reference< chart2::data::XDataSequence > xValues(
+ StatisticsHelper::getErrorDataSequenceFromDataSource( xDataSource, bPositiveValue, bYError ));
+
+ Reference< chart2::data::XNumericalDataSequence > xNumValues( xValues, uno::UNO_QUERY );
+ if( xNumValues.is())
+ {
+ Sequence< double > aData( xNumValues->getNumericalData());
+ if( nIndex < aData.getLength())
+ fResult = aData[nIndex];
+ }
+ else if( xValues.is())
+ {
+ Sequence< uno::Any > aData( xValues->getData());
+ if( nIndex < aData.getLength())
+ aData[nIndex] >>= fResult;
+ }
+
+ return fResult;
+}
+
+// static
+void StatisticsHelper::setErrorDataSequence(
+ const Reference< chart2::data::XDataSource > & xDataSource,
+ const Reference< chart2::data::XDataProvider > & xDataProvider,
+ const OUString & rNewRange,
+ bool bPositiveValue,
+ bool bYError /* = true */,
+ OUString * pXMLRange /* = 0 */ )
+{
+ Reference< chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
+ if( ! ( xDataSink.is() && xDataProvider.is()))
+ return;
+
+ OUString aRole;
+ Reference< chart2::data::XLabeledDataSequence > xLSeq(
+ lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
+ Reference< chart2::data::XDataSequence > xNewSequence(
+ xDataProvider->createDataSequenceByRangeRepresentation( rNewRange ));
+ if( xNewSequence.is())
+ {
+ if( pXMLRange )
+ lcl_setXMLRangePropertyAtDataSequence( xNewSequence, *pXMLRange );
+ if( xLSeq.is())
+ {
+ lcl_setRole( xNewSequence, aRole );
+ xLSeq->setValues( xNewSequence );
+ }
+ else
+ lcl_addSequenceToDataSource( xDataSource, xNewSequence, aRole );
+ }
+}
+
+// static
+Reference< beans::XPropertySet > StatisticsHelper::addErrorBars(
+ const Reference< chart2::XDataSeries > & xDataSeries,
+ const Reference< uno::XComponentContext > & xContext,
+ sal_Int32 nStyle,
+ bool bYError /* = true */ )
+{
+ Reference< beans::XPropertySet > xErrorBar;
+ Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
+ if( !xSeriesProp.is())
+ return xErrorBar;
+
+ const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));
+ if( !( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar ) ||
+ !xErrorBar.is())
+ {
+ xErrorBar.set( createErrorBar( xContext ));
+ }
+
+ OSL_ASSERT( xErrorBar.is());
+ if( xErrorBar.is())
+ {
+ xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny( nStyle ));
+ }
+
+ xSeriesProp->setPropertyValue( aPropName, uno::makeAny( xErrorBar ));
+
+ return xErrorBar;
+}
+
+// static
+Reference< beans::XPropertySet > StatisticsHelper::getErrorBars(
+ const Reference< chart2::XDataSeries > & xDataSeries,
+ bool bYError /* = true */ )
+{
+ Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
+ Reference< beans::XPropertySet > xErrorBar;
+ const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));
+
+ if ( xSeriesProp.is())
+ xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar;
+
+ return xErrorBar;
+}
+
+// static
+bool StatisticsHelper::hasErrorBars(
+ const Reference< chart2::XDataSeries > & xDataSeries,
+ bool bYError /* = true */ )
+{
+ Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
+ sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
+
+ return ( xErrorBar.is() &&
+ ( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
+ nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE );
+}
+
+// static
+void StatisticsHelper::removeErrorBars(
+ const Reference< chart2::XDataSeries > & xDataSeries,
+ bool bYError /* = true */ )
+{
+ Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
+ if ( xErrorBar.is())
+ xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny(
+ ::com::sun::star::chart::ErrorBarStyle::NONE ));
+}
+
+// static
+bool StatisticsHelper::usesErrorBarRanges(
+ const Reference< chart2::XDataSeries > & xDataSeries,
+ bool bYError /* = true */ )
+{
+ Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
+ sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
+
+ return ( xErrorBar.is() &&
+ ( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
+ nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/ThreeDHelper.cxx b/chart2/source/tools/ThreeDHelper.cxx
new file mode 100644
index 000000000000..44ed73eade43
--- /dev/null
+++ b/chart2/source/tools/ThreeDHelper.cxx
@@ -0,0 +1,1527 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "ThreeDHelper.hxx"
+#include "macros.hxx"
+#include "DiagramHelper.hxx"
+#include "ChartTypeHelper.hxx"
+#include "BaseGFXHelper.hxx"
+#include "DataSeriesHelper.hxx"
+#include <editeng/unoprnms.hxx>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+
+#include <tools/debug.hxx>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+using ::rtl::math::cos;
+using ::rtl::math::sin;
+using ::rtl::math::tan;
+
+#define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0)
+
+namespace
+{
+
+bool lcl_isRightAngledAxesSetAndSupported( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ sal_Bool bRightAngledAxes = sal_False;
+ if( xSceneProperties.is() )
+ {
+ xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
+ if(bRightAngledAxes)
+ {
+ uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
+ if( ChartTypeHelper::isSupportingRightAngledAxes(
+ DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void lcl_RotateLightSource( const Reference< beans::XPropertySet >& xSceneProperties
+ , const OUString& rLightSourceDirection
+ , const OUString& rLightSourceOn
+ , const ::basegfx::B3DHomMatrix& rRotationMatrix )
+{
+ if( xSceneProperties.is() )
+ {
+ sal_Bool bLightOn = sal_False;
+ if( xSceneProperties->getPropertyValue( rLightSourceOn ) >>= bLightOn )
+ {
+ if( bLightOn )
+ {
+ drawing::Direction3D aLight;
+ if( xSceneProperties->getPropertyValue( rLightSourceDirection ) >>= aLight )
+ {
+ ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aLight ) );
+ aLightVector = rRotationMatrix*aLightVector;
+
+ xSceneProperties->setPropertyValue( rLightSourceDirection
+ , uno::makeAny( BaseGFXHelper::B3DVectorToDirection3D( aLightVector ) ) );
+ }
+ }
+ }
+ }
+}
+
+void lcl_rotateLights( const ::basegfx::B3DHomMatrix& rLightRottion, const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ if(!xSceneProperties.is())
+ return;
+
+ ::basegfx::B3DHomMatrix aLightRottion( rLightRottion );
+ BaseGFXHelper::ReduceToRotationMatrix( aLightRottion );
+
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection1"), C2U("D3DSceneLightOn1"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection3"), C2U("D3DSceneLightOn3"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection4"), C2U("D3DSceneLightOn4"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection5"), C2U("D3DSceneLightOn5"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection6"), C2U("D3DSceneLightOn6"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection7"), C2U("D3DSceneLightOn7"), aLightRottion );
+ lcl_RotateLightSource( xSceneProperties, C2U("D3DSceneLightDirection8"), C2U("D3DSceneLightOn8"), aLightRottion );
+}
+
+::basegfx::B3DHomMatrix lcl_getInverseRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ ::basegfx::B3DHomMatrix aInverseRotation;
+ double fXAngleRad=0.0;
+ double fYAngleRad=0.0;
+ double fZAngleRad=0.0;
+ ThreeDHelper::getRotationAngleFromDiagram(
+ xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
+ aInverseRotation.rotate( 0.0, 0.0, -fZAngleRad );
+ aInverseRotation.rotate( 0.0, -fYAngleRad, 0.0 );
+ aInverseRotation.rotate( -fXAngleRad, 0.0, 0.0 );
+ return aInverseRotation;
+}
+
+::basegfx::B3DHomMatrix lcl_getCompleteRotationMatrix( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ ::basegfx::B3DHomMatrix aCompleteRotation;
+ double fXAngleRad=0.0;
+ double fYAngleRad=0.0;
+ double fZAngleRad=0.0;
+ ThreeDHelper::getRotationAngleFromDiagram(
+ xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
+ aCompleteRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
+ return aCompleteRotation;
+}
+
+bool lcl_isEqual( const drawing::Direction3D& rA, const drawing::Direction3D& rB )
+{
+ return ::rtl::math::approxEqual(rA.DirectionX, rB.DirectionX)
+ && ::rtl::math::approxEqual(rA.DirectionY, rB.DirectionY)
+ && ::rtl::math::approxEqual(rA.DirectionZ, rB.DirectionZ);
+}
+
+bool lcl_isLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, bool bRealistic )
+{
+ if(!xDiagramProps.is())
+ return false;
+
+ sal_Bool bIsOn = sal_False;
+ xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2 ) ) >>= bIsOn;
+ if(!bIsOn)
+ return false;
+
+ uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
+ uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
+
+ sal_Int32 nColor = 0;
+ xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ) ) >>= nColor;
+ if( nColor != ::chart::ChartTypeHelper::getDefaultDirectLightColor( !bRealistic, xChartType ) )
+ return false;
+
+ sal_Int32 nAmbientColor = 0;
+ xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR ) ) >>= nAmbientColor;
+ if( nAmbientColor != ::chart::ChartTypeHelper::getDefaultAmbientLightColor( !bRealistic, xChartType ) )
+ return false;
+
+ drawing::Direction3D aDirection(0,0,0);
+ xDiagramProps->getPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ) ) >>= aDirection;
+
+ drawing::Direction3D aDefaultDirection( bRealistic
+ ? ChartTypeHelper::getDefaultRealisticLightDirection(xChartType)
+ : ChartTypeHelper::getDefaultSimpleLightDirection(xChartType) );
+
+ //rotate default light direction when right angled axes are off but supported
+ {
+ sal_Bool bRightAngledAxes = sal_False;
+ xDiagramProps->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
+ if(!bRightAngledAxes)
+ {
+ if( ChartTypeHelper::isSupportingRightAngledAxes(
+ DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
+ {
+ ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
+ BaseGFXHelper::ReduceToRotationMatrix( aRotation );
+ ::basegfx::B3DVector aLightVector( BaseGFXHelper::Direction3DToB3DVector( aDefaultDirection ) );
+ aLightVector = aRotation*aLightVector;
+ aDefaultDirection = BaseGFXHelper::B3DVectorToDirection3D( aLightVector );
+ }
+ }
+ }
+
+ return lcl_isEqual( aDirection, aDefaultDirection );
+}
+
+bool lcl_isRealisticLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
+{
+ return lcl_isLightScheme( xDiagramProps, true /*bRealistic*/ );
+}
+bool lcl_isSimpleLightScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps )
+{
+ return lcl_isLightScheme( xDiagramProps, false /*bRealistic*/ );
+}
+void lcl_setLightsForScheme( const uno::Reference< beans::XPropertySet >& xDiagramProps, const ThreeDLookScheme& rScheme )
+{
+ if(!xDiagramProps.is())
+ return;
+ if( rScheme == ThreeDLookScheme_Unknown)
+ return;
+
+ xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_2 ), uno::makeAny( sal_True ) );
+
+ uno::Reference< chart2::XDiagram > xDiagram( xDiagramProps, uno::UNO_QUERY );
+ uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
+ uno::Any aADirection( uno::makeAny( rScheme == ThreeDLookScheme_Simple
+ ? ChartTypeHelper::getDefaultSimpleLightDirection(xChartType)
+ : ChartTypeHelper::getDefaultRealisticLightDirection(xChartType) ) );
+
+ xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2 ), aADirection );
+ //rotate light direction when right angled axes are off but supported
+ {
+ sal_Bool bRightAngledAxes = sal_False;
+ xDiagramProps->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
+ if(!bRightAngledAxes)
+ {
+ if( ChartTypeHelper::isSupportingRightAngledAxes( xChartType ) )
+ {
+ ::basegfx::B3DHomMatrix aRotation( lcl_getCompleteRotationMatrix( xDiagramProps ) );
+ BaseGFXHelper::ReduceToRotationMatrix( aRotation );
+ lcl_RotateLightSource( xDiagramProps, C2U("D3DSceneLightDirection2"), C2U("D3DSceneLightOn2"), aRotation );
+ }
+ }
+ }
+
+ sal_Int32 nColor = ::chart::ChartTypeHelper::getDefaultDirectLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
+ xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTCOLOR_2 ), uno::makeAny( nColor ) );
+
+ sal_Int32 nAmbientColor = ::chart::ChartTypeHelper::getDefaultAmbientLightColor( rScheme==ThreeDLookScheme_Simple, xChartType );
+ xDiagramProps->setPropertyValue( C2U( UNO_NAME_3D_SCENE_AMBIENTCOLOR ), uno::makeAny( nAmbientColor ) );
+}
+
+bool lcl_isRealisticScheme( drawing::ShadeMode aShadeMode
+ , sal_Int32 nRoundedEdges
+ , sal_Int32 nObjectLines )
+{
+ if(aShadeMode!=drawing::ShadeMode_SMOOTH)
+ return false;
+ if(nRoundedEdges!=5)
+ return false;
+ if(nObjectLines!=0)
+ return false;
+ return true;
+}
+
+bool lcl_isSimpleScheme( drawing::ShadeMode aShadeMode
+ , sal_Int32 nRoundedEdges
+ , sal_Int32 nObjectLines
+ , const uno::Reference< XDiagram >& xDiagram )
+{
+ if(aShadeMode!=drawing::ShadeMode_FLAT)
+ return false;
+ if(nRoundedEdges!=0)
+ return false;
+ if(nObjectLines==0)
+ {
+ uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
+ return ChartTypeHelper::noBordersForSimpleScheme( xChartType );
+ }
+ if(nObjectLines!=1)
+ return false;
+ return true;
+}
+
+void lcl_setRealisticScheme( drawing::ShadeMode& rShadeMode
+ , sal_Int32& rnRoundedEdges
+ , sal_Int32& rnObjectLines )
+{
+ rShadeMode = drawing::ShadeMode_SMOOTH;
+ rnRoundedEdges = 5;
+ rnObjectLines = 0;
+}
+
+void lcl_setSimpleScheme( drawing::ShadeMode& rShadeMode
+ , sal_Int32& rnRoundedEdges
+ , sal_Int32& rnObjectLines
+ , const uno::Reference< XDiagram >& xDiagram )
+{
+ rShadeMode = drawing::ShadeMode_FLAT;
+ rnRoundedEdges = 0;
+
+ uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
+ rnObjectLines = ChartTypeHelper::noBordersForSimpleScheme( xChartType ) ? 0 : 1;
+}
+
+} //end anonymous namespace
+
+
+drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
+{
+ // ViewReferencePoint (Point on the View plane)
+ drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
+ // ViewPlaneNormal (Normal to the View Plane)
+ drawing::Direction3D vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
+ // ViewUpVector (determines the v-axis direction on the view plane as
+ // projection of VUP parallel to VPN onto th view pane)
+ drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
+
+ if( bPie )
+ {
+ vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspecitve
+ vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
+ vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
+ }
+
+ return drawing::CameraGeometry( vrp, vpn, vup );
+}
+
+namespace
+{
+::basegfx::B3DHomMatrix lcl_getCameraMatrix( const uno::Reference< beans::XPropertySet >& xSceneProperties )
+{
+ drawing::HomogenMatrix aCameraMatrix;
+
+ drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
+ if( xSceneProperties.is() )
+ xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;
+
+ ::basegfx::B3DVector aVPN( BaseGFXHelper::Direction3DToB3DVector( aCG.vpn ) );
+ ::basegfx::B3DVector aVUP( BaseGFXHelper::Direction3DToB3DVector( aCG.vup ) );
+
+ //normalize vectors:
+ aVPN.normalize();
+ aVUP.normalize();
+
+ ::basegfx::B3DVector aCross = ::basegfx::cross( aVUP, aVPN );
+
+ //first line is VUP x VPN
+ aCameraMatrix.Line1.Column1 = aCross[0];
+ aCameraMatrix.Line1.Column2 = aCross[1];
+ aCameraMatrix.Line1.Column3 = aCross[2];
+ aCameraMatrix.Line1.Column4 = 0.0;
+
+ //second line is VUP
+ aCameraMatrix.Line2.Column1 = aVUP[0];
+ aCameraMatrix.Line2.Column2 = aVUP[1];
+ aCameraMatrix.Line2.Column3 = aVUP[2];
+ aCameraMatrix.Line2.Column4 = 0.0;
+
+ //third line is VPN
+ aCameraMatrix.Line3.Column1 = aVPN[0];
+ aCameraMatrix.Line3.Column2 = aVPN[1];
+ aCameraMatrix.Line3.Column3 = aVPN[2];
+ aCameraMatrix.Line3.Column4 = 0.0;
+
+ //fourth line is 0 0 0 1
+ aCameraMatrix.Line4.Column1 = 0.0;
+ aCameraMatrix.Line4.Column2 = 0.0;
+ aCameraMatrix.Line4.Column3 = 0.0;
+ aCameraMatrix.Line4.Column4 = 1.0;
+
+ return BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aCameraMatrix );
+}
+
+double lcl_shiftAngleToIntervalMinusPiToPi( double fAngleRad )
+{
+ //valid range: ]-Pi,Pi]
+ while( fAngleRad<=-F_PI )
+ fAngleRad+=(2*F_PI);
+ while( fAngleRad>F_PI )
+ fAngleRad-=(2*F_PI);
+ return fAngleRad;
+}
+
+void lcl_shiftAngleToIntervalMinus180To180( sal_Int32& rnAngleDegree )
+{
+ //valid range: ]-180,180]
+ while( rnAngleDegree<=-180 )
+ rnAngleDegree+=360;
+ while( rnAngleDegree>180 )
+ rnAngleDegree-=360;
+}
+
+void lcl_shiftAngleToIntervalZeroTo360( sal_Int32& rnAngleDegree )
+{
+ //valid range: [0,360[
+ while( rnAngleDegree<0 )
+ rnAngleDegree+=360;
+ while( rnAngleDegree>=360 )
+ rnAngleDegree-=360;
+}
+
+void lcl_ensureIntervalMinus1To1( double& rSinOrCos )
+{
+ if (rSinOrCos < -1.0)
+ rSinOrCos = -1.0;
+ else if (rSinOrCos > 1.0)
+ rSinOrCos = 1.0;
+}
+
+bool lcl_isSinZero( double fAngleRad )
+{
+ return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
+}
+bool lcl_isCosZero( double fAngleRad )
+{
+ return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
+}
+
+}
+
+void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
+ sal_Int32 nElevationDeg, sal_Int32 nRotationDeg,
+ double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad)
+{
+ // for a description of the algorithm see issue 72994
+ //http://www.openoffice.org/issues/show_bug.cgi?id=72994
+ //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
+
+ lcl_shiftAngleToIntervalZeroTo360( nElevationDeg );
+ lcl_shiftAngleToIntervalZeroTo360( nRotationDeg );
+
+ double& x = rfXAngleRad;
+ double& y = rfYAngleRad;
+ double& z = rfZAngleRad;
+
+ double E = F_PI*nElevationDeg/180; //elevation in Rad
+ double R = F_PI*nRotationDeg/180; //rotation in Rad
+
+ if( (nRotationDeg == 0 || nRotationDeg == 180 )
+ && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
+ {
+ //sR==0 && cE==0
+ z = 0.0;
+ //element 23
+ double f23 = cos(R)*sin(E);
+ if(f23>0)
+ x = F_PI/2;
+ else
+ x = -F_PI/2;
+ y = R;
+ }
+ else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
+ && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
+ {
+ //cR==0 && cE==0
+ z = F_PI/2;
+ if( sin(R)>0 )
+ x = F_PI/2.0;
+ else
+ x = -F_PI/2.0;
+
+ if( (sin(R)*sin(E))>0 )
+ y = 0.0;
+ else
+ y = F_PI;
+ }
+ else if( (nRotationDeg == 0 || nRotationDeg == 180 )
+ && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
+ {
+ //sR==0 && sE==0
+ z = 0.0;
+ y = R;
+ x = E;
+ }
+ else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
+ && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
+ {
+ //cR==0 && sE==0
+ z = 0.0;
+
+ if( (sin(R)/cos(E))>0 )
+ y = F_PI/2;
+ else
+ y = -F_PI/2;
+
+ if( (cos(E))>0 )
+ x = 0;
+ else
+ x = F_PI;
+ }
+ else if ( nElevationDeg == 0 || nElevationDeg == 180 )
+ {
+ //sR!=0 cR!=0 sE==0
+ z = 0.0;
+ x = E;
+ y = R;
+ //use element 13 for sign
+ if((cos(x)*sin(y)*sin(R))<0.0)
+ y *= -1.0;
+ }
+ else if ( nElevationDeg == 90 || nElevationDeg == 270 )
+ {
+ //sR!=0 cR!=0 cE==0
+ //element 12 + 22 --> y=0 or F_PI and x=+-F_PI/2
+ //-->element 13/23:
+ z = atan(sin(R)/(cos(R)*sin(E)));
+ //use element 13 for sign for x
+ if( (sin(R)*sin(z))>0.0 )
+ x = F_PI/2;
+ else
+ x = -F_PI/2;
+ //use element 21 for y
+ if( (sin(R)*sin(E)*sin(z))>0.0)
+ y = 0.0;
+ else
+ y = F_PI;
+ }
+ else if ( nRotationDeg == 0 || nRotationDeg == 180 )
+ {
+ //sE!=0 cE!=0 sR==0
+ z = 0.0;
+ x = E;
+ y = R;
+ double f23 = cos(R)*sin(E);
+ if( (f23 * sin(x)) < 0.0 )
+ x *= -1.0; //todo ??
+ }
+ else if (nRotationDeg == 90 || nRotationDeg == 270)
+ {
+ //sE!=0 cE!=0 cR==0
+ //z = +- F_PI/2;
+ //x = +- F_PI/2;
+ z = F_PI/2;
+ x = F_PI/2;
+ double sR = sin(R);
+ if( sR<0.0 )
+ x *= -1.0; //different signs for x and z
+
+ //use element 21:
+ double cy = sR*sin(E)/sin(z);
+ lcl_ensureIntervalMinus1To1(cy);
+ y = acos(cy);
+
+ //use element 22 for sign:
+ if( (sin(x)*sin(y)*sin(z)*cos(E))<0.0)
+ y *= -1.0;
+ }
+ else
+ {
+ z = atan(tan(R) * sin(E));
+ if(cos(z)==0.0)
+ {
+ DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
+ return;
+ }
+ double cy = cos(R)/cos(z);
+ lcl_ensureIntervalMinus1To1(cy);
+ y = acos(cy);
+
+ //element 12 in 23
+ double fDenominator = cos(z)*(1.0-pow(sin(y),2));
+ if(fDenominator==0.0)
+ {
+ DBG_ERROR("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
+ return;
+ }
+ double sx = cos(R)*sin(E)/fDenominator;
+ lcl_ensureIntervalMinus1To1(sx);
+ x = asin( sx );
+
+ //use element 13 for sign:
+ double f13a = cos(x)*cos(z)*sin(y);
+ double f13b = sin(R)-sx*sin(z);
+ if( (f13b*f13a)<0.0 )
+ {
+ //change x or y
+ //use element 22 for further investigations:
+ //try
+ y *= -1;
+ double f22a = cos(x)*cos(z);
+ double f22b = cos(E)-(sx*sin(y)*sin(z));
+ if( (f22a*f22b)<0.0 )
+ {
+ y *= -1;
+ x=(F_PI-x);
+ }
+ }
+ else
+ {
+ //change nothing or both
+ //use element 22 for further investigations:
+ double f22a = cos(x)*cos(z);
+ double f22b = cos(E)-(sx*sin(y)*sin(z));
+ if( (f22a*f22b)<0.0 )
+ {
+ y *= -1;
+ x=(F_PI-x);
+ }
+ }
+ }
+}
+
+void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
+ sal_Int32& rnElevationDeg, sal_Int32& rnRotationDeg,
+ double fXRad, double fYRad, double fZRad)
+{
+ // for a description of the algorithm see issue 72994
+ //http://www.openoffice.org/issues/show_bug.cgi?id=72994
+ //http://www.openoffice.org/nonav/issues/showattachment.cgi/50608/DescriptionCorrected.odt
+
+ double R = 0.0; //Rotation in Rad
+ double E = 0.0; //Elevation in Rad
+
+ double& x = fXRad;
+ double& y = fYRad;
+ double& z = fZRad;
+
+ double f11 = cos(y)*cos(z);
+
+ if( lcl_isSinZero(y) )
+ {
+ //siny == 0
+
+ if( lcl_isCosZero(x) )
+ {
+ //siny == 0 && cosx == 0
+
+ if( lcl_isSinZero(z) )
+ {
+ //siny == 0 && cosx == 0 && sinz == 0
+ //example: x=+-90 y=0oder180 z=0(oder180)
+
+ //element 13+11
+ if( f11 > 0 )
+ R = 0.0;
+ else
+ R = F_PI;
+
+ //element 23
+ double f23 = cos(z)*sin(x) / cos(R);
+ if( f23 > 0 )
+ E = F_PI/2.0;
+ else
+ E = -F_PI/2.0;
+ }
+ else if( lcl_isCosZero(z) )
+ {
+ //siny == 0 && cosx == 0 && cosz == 0
+ //example: x=+-90 y=0oder180 z=+-90
+
+ double f13 = sin(x)*sin(z);
+ //element 13+11
+ if( f13 > 0 )
+ R = F_PI/2.0;
+ else
+ R = -F_PI/2.0;
+
+ //element 21
+ double f21 = cos(y)*sin(z) / sin(R);
+ if( f21 > 0 )
+ E = F_PI/2.0;
+ else
+ E = -F_PI/2.0;
+ }
+ else
+ {
+ //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
+ //element 11 && 13
+ double f13 = sin(x)*sin(z);
+ R = atan( f13/f11 );
+
+ if(f11<0)
+ R+=F_PI;
+
+ //element 23
+ double f23 = cos(z)*sin(x);
+ if( f23/cos(R) > 0 )
+ E = F_PI/2.0;
+ else
+ E = -F_PI/2.0;
+ }
+ }
+ else if( lcl_isSinZero(x) )
+ {
+ //sinY==0 sinX==0
+ //element 13+11
+ if( f11 > 0 )
+ R = 0.0;
+ else
+ R = F_PI;
+
+ double f22 = cos(x)*cos(z);
+ if( f22 > 0 )
+ E = 0.0;
+ else
+ E = F_PI;
+ }
+ else if( lcl_isSinZero(z) )
+ {
+ //sinY==0 sinZ==0 sinx!=0 cosx!=0
+ //element 13+11
+ if( f11 > 0 )
+ R = 0.0;
+ else
+ R = F_PI;
+
+ //element 22 && 23
+ double f22 = cos(x)*cos(z);
+ double f23 = cos(z)*sin(x);
+ E = atan( f23/(f22*cos(R)) );
+ if( (f22*cos(E))<0 )
+ E+=F_PI;
+ }
+ else if( lcl_isCosZero(z) )
+ {
+ //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
+ double f13 = sin(x)*sin(z);
+ //element 13+11
+ if( f13 > 0 )
+ R = F_PI/2.0;
+ else
+ R = -F_PI/2.0;
+
+ //element 21+22
+ double f21 = cos(y)*sin(z);
+ if( f21/sin(R) > 0 )
+ E = F_PI/2.0;
+ else
+ E = -F_PI/2.0;
+ }
+ else
+ {
+ //sinY == 0 && all other !=0
+ double f13 = sin(x)*sin(z);
+ R = atan( f13/f11 );
+ if( (f11*cos(R))<0.0 )
+ R+=F_PI;
+
+ double f22 = cos(x)*cos(z);
+ if( !lcl_isCosZero(R) )
+ E = atan( cos(z)*sin(x) /( f22*cos(R) ) );
+ else
+ E = atan( cos(y)*sin(z) /( f22*sin(R) ) );
+ if( (f22*cos(E))<0 )
+ E+=F_PI;
+ }
+ }
+ else if( lcl_isCosZero(y) )
+ {
+ //cosY==0
+
+ double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
+ if( f13 >= 0 )
+ R = F_PI/2.0;
+ else
+ R = -F_PI/2.0;
+
+ double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
+ if( f22 >= 0 )
+ E = 0.0;
+ else
+ E = F_PI;
+ }
+ else if( lcl_isSinZero(x) )
+ {
+ //cosY!=0 sinY!=0 sinX=0
+ if( lcl_isSinZero(z) )
+ {
+ //cosY!=0 sinY!=0 sinX=0 sinZ=0
+ double f13 = cos(x)*cos(z)*sin(y);
+ R = atan( f13/f11 );
+ //R = asin(f13);
+ if( f11<0 )
+ R+=F_PI;
+
+ double f22 = cos(x)*cos(z);
+ if( f22>0 )
+ E = 0.0;
+ else
+ E = F_PI;
+ }
+ else if( lcl_isCosZero(z) )
+ {
+ //cosY!=0 sinY!=0 sinX=0 cosZ=0
+ R = x;
+ E = y;//or -y
+ //use 23 for 'signs'
+ double f23 = -1.0*cos(x)*sin(y)*sin(z);
+ if( (f23*cos(R)*sin(E))<0.0 )
+ {
+ //change R or E
+ E = -y;
+ }
+ }
+ else
+ {
+ //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
+ double f13 = cos(x)*cos(z)*sin(y);
+ R = atan( f13/f11 );
+
+ if( f11<0 )
+ R+=F_PI;
+
+ double f21 = cos(y)*sin(z);
+ double f22 = cos(x)*cos(z);
+ E = atan(f21/(f22*sin(R)) );
+
+ if( (f22*cos(E))<0.0 )
+ E+=F_PI;
+ }
+ }
+ else if( lcl_isCosZero(x) )
+ {
+ //cosY!=0 sinY!=0 cosX=0
+
+ if( lcl_isSinZero(z) )
+ {
+ //cosY!=0 sinY!=0 cosX=0 sinZ=0
+ R=0;//13 -> R=0 or F_PI
+ if( f11<0.0 )
+ R=F_PI;
+ E=F_PI/2;//22 -> E=+-F_PI/2
+ //use element 11 and 23 for sign
+ double f23 = cos(z)*sin(x);
+ if( (f11*f23*sin(E))<0.0 )
+ E=-F_PI/2.0;
+ }
+ else if( lcl_isCosZero(z) )
+ {
+ //cosY!=0 sinY!=0 cosX=0 cosZ=0
+ //element 11 & 13:
+ if( (sin(x)*sin(z))>0.0 )
+ R=F_PI/2.0;
+ else
+ R=-F_PI/2.0;
+ //element 22:
+ E=acos( sin(x)*sin(y)*sin(z));
+ //use element 21 for sign:
+ if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
+ E*=-1.0;
+ }
+ else
+ {
+ //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
+ //element 13/11
+ R = atan( sin(x)*sin(z)/(cos(y)*cos(z)) );
+ //use 13 for 'sign'
+ if( (sin(x)*sin(z))<0.0 )
+ R += F_PI;
+ //element 22
+ E = acos(sin(x)*sin(y)*sin(z) );
+ //use 21 for sign
+ if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
+ E*=-1.0;
+ }
+ }
+ else if( lcl_isSinZero(z) )
+ {
+ //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
+ //element 11
+ R=y;
+ //use elenment 13 for sign
+ if( (cos(x)*cos(z)*sin(y)*sin(R))<0.0 )
+ R*=-1.0;
+ //element 22
+ E = acos( cos(x)*cos(z) );
+ //use element 23 for sign
+ if( (cos(z)*sin(x)*cos(R)*sin(E))<0.0 )
+ E*=-1.0;
+ }
+ else if( lcl_isCosZero(z) )
+ {
+ //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
+ //element 21/23
+ R=atan(-cos(y)/(cos(x)*sin(y)));
+ //use element 13 for 'sign'
+ if( (sin(x)*sin(z)*sin(R))<0.0 )
+ R+=F_PI;
+ //element 21/22
+ E=atan( cos(y)*sin(z)/(sin(R)*sin(x)*sin(y)*sin(z)) );
+ //use element 23 for 'sign'
+ if( (-cos(x)*sin(y)*sin(z)*cos(R)*sin(E))<0.0 )
+ E+=F_PI;
+ }
+ else
+ {
+ //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
+ //13/11:
+ double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
+ R = atan( f13/ f11 );
+ if(f11<0.0)
+ R+=F_PI;
+ double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
+ double f23 = cos(x)*sin(y)*sin(z)-cos(z)*sin(x);
+ //23/22:
+ E = atan( -1.0*f23/(f22*cos(R)) );
+ if(f22<0.0)
+ E+=F_PI;
+ }
+
+ rnElevationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( E ) );
+ rnRotationDeg = ::basegfx::fround( BaseGFXHelper::Rad2Deg( R ) );
+}
+
+double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
+{
+ if( fAngle<-1*fPositivLimit )
+ fAngle=-1*fPositivLimit;
+ else if( fAngle>fPositivLimit )
+ fAngle=fPositivLimit;
+ return fAngle;
+}
+
+double ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()
+{
+ return 90.0;
+}
+
+double ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()
+{
+ return 45.0;
+}
+
+void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
+{
+ rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
+ rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, BaseGFXHelper::Deg2Rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
+}
+
+void ThreeDHelper::getRotationAngleFromDiagram(
+ const Reference< beans::XPropertySet >& xSceneProperties, double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad )
+{
+ //takes the camera and the transformation matrix into account
+
+ rfXAngleRad = rfYAngleRad = rfZAngleRad = 0.0;
+
+ if( !xSceneProperties.is() )
+ return;
+
+ //get camera rotation
+ ::basegfx::B3DHomMatrix aFixCameraRotationMatrix( lcl_getCameraMatrix( xSceneProperties ) );
+ BaseGFXHelper::ReduceToRotationMatrix( aFixCameraRotationMatrix );
+
+ //get scene rotation
+ ::basegfx::B3DHomMatrix aSceneRotation;
+ {
+ drawing::HomogenMatrix aHomMatrix;
+ if( xSceneProperties->getPropertyValue( C2U("D3DTransformMatrix")) >>= aHomMatrix )
+ {
+ aSceneRotation = BaseGFXHelper::HomogenMatrixToB3DHomMatrix( aHomMatrix );
+ BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
+ }
+ }
+
+ ::basegfx::B3DHomMatrix aResultRotation = aFixCameraRotationMatrix * aSceneRotation;
+ ::basegfx::B3DTuple aRotation( BaseGFXHelper::GetRotationFromMatrix( aResultRotation ) );
+
+ rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getX());
+ rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getY());
+ rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(aRotation.getZ());
+
+ if(rfZAngleRad<(-F_PI/2) || rfZAngleRad>(F_PI/2))
+ {
+ rfZAngleRad-=F_PI;
+ rfXAngleRad-=F_PI;
+ rfYAngleRad=(F_PI-rfYAngleRad);
+
+ rfXAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfXAngleRad);
+ rfYAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfYAngleRad);
+ rfZAngleRad = lcl_shiftAngleToIntervalMinusPiToPi(rfZAngleRad);
+ }
+}
+
+void ThreeDHelper::switchRightAngledAxes( const Reference< beans::XPropertySet >& xSceneProperties, sal_Bool bRightAngledAxes, bool bRotateLights )
+{
+ try
+ {
+ if( xSceneProperties.is() )
+ {
+ sal_Bool bOldRightAngledAxes = sal_False;
+ xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bOldRightAngledAxes;
+ if( bOldRightAngledAxes!=bRightAngledAxes)
+ {
+ xSceneProperties->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( bRightAngledAxes ));
+ if( bRotateLights )
+ {
+ if(bRightAngledAxes)
+ {
+ ::basegfx::B3DHomMatrix aInverseRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
+ lcl_rotateLights( aInverseRotation, xSceneProperties );
+ }
+ else
+ {
+ ::basegfx::B3DHomMatrix aCompleteRotation( lcl_getCompleteRotationMatrix( xSceneProperties ) );
+ lcl_rotateLights( aCompleteRotation, xSceneProperties );
+ }
+ }
+ }
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ThreeDHelper::setRotationAngleToDiagram(
+ const Reference< beans::XPropertySet >& xSceneProperties
+ , double fXAngleRad, double fYAngleRad, double fZAngleRad )
+{
+ //the rotation of the camera is not touched but taken into account
+ //the rotation difference is applied to the transformation matrix
+
+ //the light sources will be adapted also
+
+ if( !xSceneProperties.is() )
+ return;
+
+ try
+ {
+ //remind old rotation for adaption of light directions
+ ::basegfx::B3DHomMatrix aInverseOldRotation( lcl_getInverseRotationMatrix( xSceneProperties ) );
+
+ ::basegfx::B3DHomMatrix aInverseCameraRotation;
+ {
+ ::basegfx::B3DTuple aR( BaseGFXHelper::GetRotationFromMatrix(
+ lcl_getCameraMatrix( xSceneProperties ) ) );
+ aInverseCameraRotation.rotate( 0.0, 0.0, -aR.getZ() );
+ aInverseCameraRotation.rotate( 0.0, -aR.getY(), 0.0 );
+ aInverseCameraRotation.rotate( -aR.getX(), 0.0, 0.0 );
+ }
+
+ ::basegfx::B3DHomMatrix aCumulatedRotation;
+ aCumulatedRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
+
+ //calculate new scene matrix
+ ::basegfx::B3DHomMatrix aSceneRotation = aInverseCameraRotation*aCumulatedRotation;
+ BaseGFXHelper::ReduceToRotationMatrix( aSceneRotation );
+
+ //set new rotation to transformation matrix
+ xSceneProperties->setPropertyValue(
+ C2U("D3DTransformMatrix"), uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
+
+ //rotate lights if RightAngledAxes are not set or not supported
+ sal_Bool bRightAngledAxes = sal_False;
+ xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
+ uno::Reference< chart2::XDiagram > xDiagram( xSceneProperties, uno::UNO_QUERY );
+ if(!bRightAngledAxes || !ChartTypeHelper::isSupportingRightAngledAxes(
+ DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
+ {
+ ::basegfx::B3DHomMatrix aNewRotation;
+ aNewRotation.rotate( fXAngleRad, fYAngleRad, fZAngleRad );
+ lcl_rotateLights( aNewRotation*aInverseOldRotation, xSceneProperties );
+ }
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void ThreeDHelper::getRotationFromDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
+ , sal_Int32& rnHorizontalAngleDegree, sal_Int32& rnVerticalAngleDegree )
+{
+ double fXAngle, fYAngle, fZAngle;
+ ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
+
+ if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
+ {
+ ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
+ rnHorizontalAngleDegree, rnVerticalAngleDegree, fXAngle, fYAngle, fZAngle);
+ rnVerticalAngleDegree*=-1;
+ }
+ else
+ {
+ fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
+ fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
+ fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );
+
+ rnHorizontalAngleDegree = ::basegfx::fround(fXAngle);
+ rnVerticalAngleDegree = ::basegfx::fround(-1.0*fYAngle);
+ //nZRotation = ::basegfx::fround(-1.0*fZAngle);
+ }
+
+ lcl_shiftAngleToIntervalMinus180To180( rnHorizontalAngleDegree );
+ lcl_shiftAngleToIntervalMinus180To180( rnVerticalAngleDegree );
+}
+
+void ThreeDHelper::setRotationToDiagram( const uno::Reference< beans::XPropertySet >& xSceneProperties
+ , sal_Int32 nHorizontalAngleDegree, sal_Int32 nVerticalYAngleDegree )
+{
+ //todo: x and y is not equal to horz and vert in case of RightAngledAxes==false
+ double fXAngle = BaseGFXHelper::Deg2Rad( nHorizontalAngleDegree );
+ double fYAngle = BaseGFXHelper::Deg2Rad( -1*nVerticalYAngleDegree );
+ double fZAngle = 0.0;
+
+ if( !lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
+ ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
+ nHorizontalAngleDegree, -1*nVerticalYAngleDegree, fXAngle, fYAngle, fZAngle );
+
+ ThreeDHelper::setRotationAngleToDiagram( xSceneProperties, fXAngle, fYAngle, fZAngle );
+}
+
+void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
+{
+ rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
+ rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
+}
+
+void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
+{
+ double fMin, fMax;
+ getCameraDistanceRange( fMin, fMax );
+ if( rfCameraDistance < fMin )
+ rfCameraDistance = fMin;
+ if( rfCameraDistance > fMax )
+ rfCameraDistance = fMax;
+}
+
+double ThreeDHelper::getCameraDistance(
+ const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ double fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
+
+ if( !xSceneProperties.is() )
+ return fCameraDistance;
+
+ try
+ {
+ drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
+ xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;
+ ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
+ fCameraDistance = aVRP.getLength();
+
+ ensureCameraDistanceRange( fCameraDistance );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return fCameraDistance;
+}
+
+void ThreeDHelper::setCameraDistance(
+ const Reference< beans::XPropertySet >& xSceneProperties, double fCameraDistance )
+{
+ if( !xSceneProperties.is() )
+ return;
+
+ try
+ {
+ if( fCameraDistance <= 0 )
+ fCameraDistance = FIXED_SIZE_FOR_3D_CHART_VOLUME;
+
+ drawing::CameraGeometry aCG( ThreeDHelper::getDefaultCameraGeometry() );
+ xSceneProperties->getPropertyValue( C2U( "D3DCameraGeometry" ) ) >>= aCG;
+ ::basegfx::B3DVector aVRP( BaseGFXHelper::Position3DToB3DVector( aCG.vrp ) );
+ if( ::basegfx::fTools::equalZero( aVRP.getLength() ) )
+ aVRP = ::basegfx::B3DVector(0,0,1);
+ aVRP.setLength(fCameraDistance);
+ aCG.vrp = BaseGFXHelper::B3DVectorToPosition3D( aVRP );
+
+ xSceneProperties->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCG ));
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+//static
+double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
+{
+ double fRet = fCameraDistance;
+ double fMin, fMax;
+ ThreeDHelper::getCameraDistanceRange( fMin, fMax );
+ //fMax <-> 0; fMin <->100
+ //a/x + b = y
+ double a = 100.0*fMax*fMin/(fMax-fMin);
+ double b = -a/fMax;
+
+ fRet = a/fCameraDistance + b;
+
+ return fRet;
+}
+
+//static
+double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
+{
+ double fRet = fPerspective;
+ double fMin, fMax;
+ ThreeDHelper::getCameraDistanceRange( fMin, fMax );
+ //fMax <-> 0; fMin <->100
+ //a/x + b = y
+ double a = 100.0*fMax*fMin/(fMax-fMin);
+ double b = -a/fMax;
+
+ fRet = a/(fPerspective - b);
+
+ return fRet;
+}
+
+//static
+ThreeDLookScheme ThreeDHelper::detectScheme( const uno::Reference< XDiagram >& xDiagram )
+{
+ ThreeDLookScheme aScheme = ThreeDLookScheme_Unknown;
+
+ sal_Int32 nRoundedEdges;
+ sal_Int32 nObjectLines;
+ ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
+
+ //get shade mode and light settings:
+ drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
+ uno::Reference< beans::XPropertySet > xDiagramProps( xDiagram, uno::UNO_QUERY );
+ try
+ {
+ if( xDiagramProps.is() )
+ xDiagramProps->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode;
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ if( lcl_isSimpleScheme( aShadeMode, nRoundedEdges, nObjectLines, xDiagram ) )
+ {
+ if( lcl_isSimpleLightScheme(xDiagramProps) )
+ aScheme = ThreeDLookScheme_Simple;
+ }
+ else if( lcl_isRealisticScheme( aShadeMode, nRoundedEdges, nObjectLines ) )
+ {
+ if( lcl_isRealisticLightScheme(xDiagramProps) )
+ aScheme = ThreeDLookScheme_Realistic;
+ }
+
+ return aScheme;
+}
+
+void ThreeDHelper::setScheme( const uno::Reference< XDiagram >& xDiagram, ThreeDLookScheme aScheme )
+{
+ if( aScheme == ThreeDLookScheme_Unknown )
+ return;
+
+ drawing::ShadeMode aShadeMode;
+ sal_Int32 nRoundedEdges;
+ sal_Int32 nObjectLines;
+
+ if( aScheme == ThreeDLookScheme_Simple )
+ lcl_setSimpleScheme(aShadeMode,nRoundedEdges,nObjectLines,xDiagram);
+ else
+ lcl_setRealisticScheme(aShadeMode,nRoundedEdges,nObjectLines);
+
+ try
+ {
+ ThreeDHelper::setRoundedEdgesAndObjectLines( xDiagram, nRoundedEdges, nObjectLines );
+
+ uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ drawing::ShadeMode aOldShadeMode;
+ if( ! ( (xProp->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>=aOldShadeMode) &&
+ aOldShadeMode == aShadeMode ))
+ {
+ xProp->setPropertyValue( C2U( "D3DSceneShadeMode" ), uno::makeAny( aShadeMode ));
+ }
+ }
+
+ lcl_setLightsForScheme( xProp, aScheme );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+}
+
+//static
+void ThreeDHelper::set3DSettingsToDefault( const uno::Reference< beans::XPropertySet >& xSceneProperties )
+{
+ Reference< beans::XPropertyState > xState( xSceneProperties, uno::UNO_QUERY );
+ if(xState.is())
+ {
+ xState->setPropertyToDefault( C2U("D3DSceneDistance"));
+ xState->setPropertyToDefault( C2U("D3DSceneFocalLength"));
+ }
+ ThreeDHelper::setDefaultRotation( xSceneProperties );
+ ThreeDHelper::setDefaultIllumination( xSceneProperties );
+}
+
+//static
+void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties, bool bPieOrDonut )
+{
+ if( !xSceneProperties.is() )
+ return;
+
+ drawing::CameraGeometry aCameraGeo( ThreeDHelper::getDefaultCameraGeometry( bPieOrDonut ) );
+ xSceneProperties->setPropertyValue( C2U("D3DCameraGeometry"), uno::makeAny( aCameraGeo ));
+
+ ::basegfx::B3DHomMatrix aSceneRotation;
+ if( bPieOrDonut )
+ aSceneRotation.rotate( -F_PI/3.0, 0, 0 );
+ xSceneProperties->setPropertyValue( C2U("D3DTransformMatrix"),
+ uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aSceneRotation )));
+}
+
+//static
+void ThreeDHelper::setDefaultRotation( const uno::Reference< beans::XPropertySet >& xSceneProperties )
+{
+ bool bPieOrDonut( DiagramHelper::isPieOrDonutChart( uno::Reference< XDiagram >(xSceneProperties, uno::UNO_QUERY) ) );
+ ThreeDHelper::setDefaultRotation( xSceneProperties, bPieOrDonut );
+}
+
+//static
+void ThreeDHelper::setDefaultIllumination( const uno::Reference< beans::XPropertySet >& xSceneProperties )
+{
+ if( !xSceneProperties.is() )
+ return;
+
+ drawing::ShadeMode aShadeMode( drawing::ShadeMode_SMOOTH );
+ try
+ {
+ xSceneProperties->getPropertyValue( C2U( "D3DSceneShadeMode" ) )>>= aShadeMode;
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_1 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_3 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_4 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_5 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_6 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_7 ), uno::makeAny( sal_False ) );
+ xSceneProperties->setPropertyValue( C2U( UNO_NAME_3D_SCENE_LIGHTON_8 ), uno::makeAny( sal_False ) );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+
+ ThreeDLookScheme aScheme = (drawing::ShadeMode_FLAT==aShadeMode) ? ThreeDLookScheme_Simple : ThreeDLookScheme_Realistic;
+ lcl_setLightsForScheme( xSceneProperties, aScheme );
+}
+
+//static
+void ThreeDHelper::getRoundedEdgesAndObjectLines(
+ const uno::Reference< XDiagram > & xDiagram
+ , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
+{
+ rnRoundedEdges = -1;
+ rnObjectLines = -1;
+ try
+ {
+ bool bDifferentRoundedEdges = false;
+ bool bDifferentObjectLines = false;
+
+ drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
+
+ ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
+
+ rtl::OUString aPercentDiagonalPropertyName( C2U( "PercentDiagonal" ) );
+ rtl::OUString aBorderStylePropertyName( C2U( "BorderStyle" ) );
+
+ for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
+ {
+ uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
+ uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
+ if(!nS)
+ {
+ rnRoundedEdges = 0;
+ try
+ {
+ sal_Int16 nPercentDiagonal = 0;
+
+ xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
+ rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
+
+ if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
+ , aPercentDiagonalPropertyName, uno::makeAny(nPercentDiagonal) ) )
+ bDifferentRoundedEdges = true;
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ bDifferentRoundedEdges = true;
+ }
+ try
+ {
+ xProp->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
+
+ if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
+ , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
+ bDifferentObjectLines = true;
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ bDifferentObjectLines = true;
+ }
+ }
+ else
+ {
+ if( !bDifferentRoundedEdges )
+ {
+ sal_Int16 nPercentDiagonal = 0;
+ xProp->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
+ sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
+ if(nCurrentRoundedEdges!=rnRoundedEdges
+ || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
+ , aPercentDiagonalPropertyName, uno::makeAny( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
+ {
+ bDifferentRoundedEdges = true;
+ nCurrentRoundedEdges = -1;
+ }
+ }
+
+ if( !bDifferentObjectLines )
+ {
+ drawing::LineStyle aCurrentLineStyle;
+ xProp->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
+ if(aCurrentLineStyle!=aLineStyle
+ || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
+ , aBorderStylePropertyName, uno::makeAny(aLineStyle) ) )
+ bDifferentObjectLines = true;
+ }
+ }
+ if( bDifferentRoundedEdges && bDifferentObjectLines )
+ break;
+ }
+
+ //set rnObjectLines
+ rnObjectLines = 0;
+ if( bDifferentObjectLines )
+ rnObjectLines = -1;
+ else if( aLineStyle == drawing::LineStyle_SOLID )
+ rnObjectLines = 1;
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+}
+//static
+void ThreeDHelper::setRoundedEdgesAndObjectLines(
+ const uno::Reference< XDiagram > & xDiagram
+ , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
+{
+ if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
+ return;
+
+ drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
+ if(nObjectLines==1)
+ aLineStyle = drawing::LineStyle_SOLID;
+
+ uno::Any aALineStyle( uno::makeAny(aLineStyle));
+ uno::Any aARoundedEdges( uno::makeAny( static_cast< sal_Int16 >( nRoundedEdges )));
+
+ ::std::vector< uno::Reference< XDataSeries > > aSeriesList(
+ DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
+ sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
+ for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
+ {
+ uno::Reference< XDataSeries > xSeries( aSeriesList[nS] );
+
+ if( nRoundedEdges>=0 && nRoundedEdges<=100 )
+ DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "PercentDiagonal" ), aARoundedEdges );
+
+ if( nObjectLines==0 || nObjectLines==1 )
+ DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), aALineStyle );
+ }
+}
+
+//static
+CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ CuboidPlanePosition eRet(CuboidPlanePosition_Left);
+
+ double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
+ ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
+ if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
+ {
+ ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
+ fZAngleRad=0.0;
+ }
+ if( sin(fYAngleRad)>0.0 )
+ eRet = CuboidPlanePosition_Right;
+ return eRet;
+}
+
+//static
+CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ CuboidPlanePosition eRet(CuboidPlanePosition_Back);
+
+ double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
+ ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
+ if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
+ {
+ ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
+ fZAngleRad=0.0;
+ }
+ if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
+ eRet = CuboidPlanePosition_Front;
+ return eRet;
+}
+
+//static
+CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const Reference< beans::XPropertySet >& xSceneProperties )
+{
+ CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);
+
+ double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
+ ThreeDHelper::getRotationAngleFromDiagram( xSceneProperties, fXAngleRad, fYAngleRad, fZAngleRad );
+ if( lcl_isRightAngledAxesSetAndSupported( xSceneProperties ) )
+ {
+ ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
+ fZAngleRad=0.0;
+ }
+ if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
+ eRet = CuboidPlanePosition_Top;
+ return eRet;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/TitleHelper.cxx b/chart2/source/tools/TitleHelper.cxx
new file mode 100644
index 000000000000..828a523245ff
--- /dev/null
+++ b/chart2/source/tools/TitleHelper.cxx
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "TitleHelper.hxx"
+#include "ChartModelHelper.hxx"
+#include "macros.hxx"
+#include "AxisHelper.hxx"
+#include "DiagramHelper.hxx"
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <rtl/ustrbuf.hxx>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+
+uno::Reference< XTitled > lcl_getTitleParentFromDiagram(
+ TitleHelper::eTitleType nTitleIndex
+ , const uno::Reference< XDiagram >& xDiagram )
+{
+ uno::Reference< XTitled > xResult;
+
+ if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION ||
+ nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
+ {
+ bool bDummy = false;
+ bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
+
+ if( nTitleIndex == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION )
+ nTitleIndex = bIsVertical ? TitleHelper::X_AXIS_TITLE : TitleHelper::Y_AXIS_TITLE;
+ else
+ nTitleIndex = bIsVertical ? TitleHelper::Y_AXIS_TITLE : TitleHelper::X_AXIS_TITLE;
+ }
+
+
+ switch( nTitleIndex )
+ {
+ case TitleHelper::SUB_TITLE:
+ if( xDiagram.is())
+ xResult.set( xDiagram, uno::UNO_QUERY );
+ break;
+ case TitleHelper::X_AXIS_TITLE:
+ if( xDiagram.is())
+ xResult.set( AxisHelper::getAxis( 0, true, xDiagram ), uno::UNO_QUERY );
+ break;
+ case TitleHelper::Y_AXIS_TITLE:
+ if( xDiagram.is())
+ xResult.set( AxisHelper::getAxis( 1, true, xDiagram ), uno::UNO_QUERY );
+ break;
+ case TitleHelper::Z_AXIS_TITLE:
+ if( xDiagram.is())
+ xResult.set( AxisHelper::getAxis( 2, true, xDiagram ), uno::UNO_QUERY );
+ break;
+ case TitleHelper::SECONDARY_X_AXIS_TITLE:
+ if( xDiagram.is())
+ xResult.set( AxisHelper::getAxis( 0, false, xDiagram ), uno::UNO_QUERY );
+ break;
+ case TitleHelper::SECONDARY_Y_AXIS_TITLE:
+ if( xDiagram.is())
+ xResult.set( AxisHelper::getAxis( 1, false, xDiagram ), uno::UNO_QUERY );
+ break;
+
+ case TitleHelper::MAIN_TITLE:
+ default:
+ OSL_ENSURE( false, "Unsupported Title-Type requested" );
+ break;
+ }
+
+ return xResult;
+}
+
+uno::Reference< XTitled > lcl_getTitleParent( TitleHelper::eTitleType nTitleIndex
+ , const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< XTitled > xResult;
+ uno::Reference< XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
+ uno::Reference< XDiagram > xDiagram;
+ if( xChartDoc.is())
+ xDiagram.set( xChartDoc->getFirstDiagram());
+
+ switch( nTitleIndex )
+ {
+ case TitleHelper::MAIN_TITLE:
+ xResult.set( xModel, uno::UNO_QUERY );
+ break;
+ case TitleHelper::SUB_TITLE:
+ case TitleHelper::X_AXIS_TITLE:
+ case TitleHelper::Y_AXIS_TITLE:
+ case TitleHelper::Z_AXIS_TITLE:
+ case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
+ case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
+ case TitleHelper::SECONDARY_X_AXIS_TITLE:
+ case TitleHelper::SECONDARY_Y_AXIS_TITLE:
+ xResult.set( lcl_getTitleParentFromDiagram( nTitleIndex, xDiagram ));
+ break;
+ default:
+ OSL_ENSURE( false, "Unsupported Title-Type requested" );
+ break;
+ }
+
+ return xResult;
+}
+
+uno::Reference< XTitle > TitleHelper::getTitle( TitleHelper::eTitleType nTitleIndex
+ , const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xModel ) );
+ if( xTitled.is())
+ return xTitled->getTitleObject();
+ return NULL;
+}
+
+uno::Reference< XTitle > TitleHelper::createTitle(
+ TitleHelper::eTitleType eTitleType
+ , const rtl::OUString& rTitleText
+ , const uno::Reference< frame::XModel >& xModel
+ , const uno::Reference< uno::XComponentContext > & xContext
+ , ReferenceSizeProvider * pRefSizeProvider )
+{
+ uno::Reference< XTitle > xTitle;
+ uno::Reference< XTitled > xTitled( lcl_getTitleParent( eTitleType, xModel ) );
+
+ if( !xTitled.is() )
+ {
+ uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ) );
+ uno::Reference< chart2::XAxis > xAxis;
+ switch( eTitleType )
+ {
+ case TitleHelper::SECONDARY_X_AXIS_TITLE:
+ xAxis = AxisHelper::createAxis( 0, false, xDiagram, xContext );
+ break;
+ case TitleHelper::SECONDARY_Y_AXIS_TITLE:
+ xAxis = AxisHelper::createAxis( 1, false, xDiagram, xContext );
+ break;
+ default:
+ break;
+ }
+ uno::Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
+ xTitled = lcl_getTitleParent( eTitleType, xModel );
+ }
+ }
+
+ if(xTitled.is())
+ {
+ uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel ) );
+
+ xTitle.set( xContext->getServiceManager()->createInstanceWithContext(
+ C2U( "com.sun.star.chart2.Title" ),
+ xContext ), uno::UNO_QUERY );
+
+ if(xTitle.is())
+ {
+ // default char height (main: 13.0 == default)
+ float fDefaultCharHeightSub = 11.0;
+ float fDefaultCharHeightAxis = 9.0;
+ switch( eTitleType )
+ {
+ case TitleHelper::SUB_TITLE:
+ TitleHelper::setCompleteString(
+ rTitleText, xTitle, xContext, & fDefaultCharHeightSub );
+ break;
+ case TitleHelper::X_AXIS_TITLE:
+ case TitleHelper::Y_AXIS_TITLE:
+ case TitleHelper::Z_AXIS_TITLE:
+ case TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION:
+ case TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION:
+ case TitleHelper::SECONDARY_X_AXIS_TITLE:
+ case TitleHelper::SECONDARY_Y_AXIS_TITLE:
+ TitleHelper::setCompleteString(
+ rTitleText, xTitle, xContext, & fDefaultCharHeightAxis );
+ break;
+ default:
+ TitleHelper::setCompleteString( rTitleText, xTitle, xContext );
+ break;
+ }
+
+ // set/clear autoscale
+ if( pRefSizeProvider )
+ pRefSizeProvider->setValuesAtTitle( xTitle );
+
+ xTitled->setTitleObject( xTitle );
+
+ //default rotation 90 degree for y axis title in normal coordinatesystems or for x axis title for swapped coordinatesystems
+ if( eTitleType == TitleHelper::X_AXIS_TITLE ||
+ eTitleType == TitleHelper::Y_AXIS_TITLE ||
+ eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE ||
+ eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE )
+
+ {
+ try
+ {
+ bool bDummy = false;
+ bool bIsVertical = DiagramHelper::getVertical( xDiagram, bDummy, bDummy );
+
+ Reference< beans::XPropertySet > xTitleProps( xTitle, uno::UNO_QUERY );
+ if( xTitleProps.is() )
+ {
+ double fNewAngleDegree = 90.0;
+ if( (!bIsVertical && eTitleType == TitleHelper::Y_AXIS_TITLE)
+ || (bIsVertical && eTitleType == TitleHelper::X_AXIS_TITLE)
+ || (!bIsVertical && eTitleType == TitleHelper::SECONDARY_Y_AXIS_TITLE)
+ || (bIsVertical && eTitleType == TitleHelper::SECONDARY_X_AXIS_TITLE) )
+ xTitleProps->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree ));
+ }
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+ }
+ return xTitle;
+
+}
+
+rtl::OUString TitleHelper::getCompleteString( const uno::Reference< XTitle >& xTitle )
+{
+ rtl::OUString aRet;
+ if(!xTitle.is())
+ return aRet;
+ uno::Sequence< uno::Reference< XFormattedString > > aStringList = xTitle->getText();
+ for( sal_Int32 nN=0; nN<aStringList.getLength();nN++ )
+ aRet += aStringList[nN]->getString();
+ return aRet;
+}
+
+void TitleHelper::setCompleteString( const rtl::OUString& rNewText
+ , const uno::Reference< XTitle >& xTitle
+ , const uno::Reference< uno::XComponentContext > & xContext
+ , float * pDefaultCharHeight /* = 0 */ )
+{
+ //the format of the first old text portion will be maintained if there is any
+ if(!xTitle.is())
+ return;
+
+ rtl::OUString aNewText = rNewText;
+
+ bool bStacked = false;
+ uno::Reference< beans::XPropertySet > xTitleProperties( xTitle, uno::UNO_QUERY );
+ if( xTitleProperties.is() )
+ xTitleProperties->getPropertyValue( C2U( "StackCharacters" ) ) >>= bStacked;
+
+ if( bStacked )
+ {
+ //#i99841# remove linebreaks that were added for vertical stacking
+ rtl::OUStringBuffer aUnstackedStr;
+ rtl::OUStringBuffer aSource(rNewText);
+
+ bool bBreakIgnored = false;
+ sal_Int32 nLen = rNewText.getLength();
+ for( sal_Int32 nPos = 0; nPos < nLen; ++nPos )
+ {
+ sal_Unicode aChar = aSource.charAt( nPos );
+ if( aChar != '\n' )
+ {
+ aUnstackedStr.append( aChar );
+ bBreakIgnored = false;
+ }
+ else if( aChar == '\n' && bBreakIgnored )
+ aUnstackedStr.append( aChar );
+ else
+ bBreakIgnored = true;
+ }
+ aNewText = aUnstackedStr.makeStringAndClear();
+ }
+
+ uno::Sequence< uno::Reference< XFormattedString > > aNewStringList(1);
+
+ uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText();
+ if( aOldStringList.getLength() )
+ {
+ aNewStringList[0].set( aOldStringList[0] );
+ aNewStringList[0]->setString( aNewText );
+ }
+ else
+ {
+ uno::Reference< uno::XInterface > xI(
+ xContext->getServiceManager()->createInstanceWithContext(
+ C2U( "com.sun.star.chart2.FormattedString" ), xContext ) );
+ uno::Reference< XFormattedString > xFormattedString( xI, uno::UNO_QUERY );
+
+ if(xFormattedString.is())
+ {
+ xFormattedString->setString( aNewText );
+ aNewStringList[0].set( xFormattedString );
+ if( pDefaultCharHeight != 0 )
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProp( xFormattedString, uno::UNO_QUERY_THROW );
+
+ uno::Any aFontSize( uno::makeAny( *pDefaultCharHeight ));
+ xProp->setPropertyValue( C2U("CharHeight"), aFontSize );
+ xProp->setPropertyValue( C2U("CharHeightAsian"), aFontSize );
+ xProp->setPropertyValue( C2U("CharHeightComplex"), aFontSize );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+ }
+ xTitle->setText( aNewStringList );
+}
+
+void TitleHelper::removeTitle( TitleHelper::eTitleType nTitleIndex
+ , const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XModel >& xModel )
+{
+ uno::Reference< XTitled > xTitled( lcl_getTitleParent( nTitleIndex, xModel ) );
+ if( xTitled.is())
+ {
+ xTitled->setTitleObject(NULL);
+ }
+}
+
+bool TitleHelper::getTitleType( eTitleType& rType
+ , const ::com::sun::star::uno::Reference<
+ ::com::sun::star::chart2::XTitle >& xTitle
+ , const ::com::sun::star::uno::Reference<
+ ::com::sun::star::frame::XModel >& xModel )
+{
+ if( !xTitle.is() || !xModel.is() )
+ return false;
+
+ Reference< chart2::XTitle > xCurrentTitle;
+ for( sal_Int32 nTitleType = TITLE_BEGIN; nTitleType < NORMAL_TITLE_END; nTitleType++ )
+ {
+ xCurrentTitle = TitleHelper::getTitle( static_cast<eTitleType>(nTitleType), xModel );
+ if( xCurrentTitle == xTitle )
+ {
+ rType = static_cast<eTitleType>(nTitleType);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
+
diff --git a/chart2/source/tools/TrueGuard.cxx b/chart2/source/tools/TrueGuard.cxx
new file mode 100644
index 000000000000..6992552367ed
--- /dev/null
+++ b/chart2/source/tools/TrueGuard.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "TrueGuard.hxx"
+
+namespace chart
+{
+
+TrueGuard::TrueGuard( bool& rbTrueDuringGuardedTime )
+ : m_rbTrueDuringGuardedTime( rbTrueDuringGuardedTime )
+{
+ m_rbTrueDuringGuardedTime = true;
+}
+
+TrueGuard::~TrueGuard()
+{
+ m_rbTrueDuringGuardedTime = false;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/UncachedDataSequence.cxx b/chart2/source/tools/UncachedDataSequence.cxx
new file mode 100644
index 000000000000..52cc6b9c03b6
--- /dev/null
+++ b/chart2/source/tools/UncachedDataSequence.cxx
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "UncachedDataSequence.hxx"
+#include "macros.hxx"
+#include "PropertyHelper.hxx"
+#include "CommonFunctors.hxx"
+#include "ModifyListenerHelper.hxx"
+
+#include <algorithm>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <rtl/math.hxx>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::osl::MutexGuard;
+
+// necessary for MS compiler
+using ::comphelper::OPropertyContainer;
+using ::chart::impl::UncachedDataSequence_Base;
+
+namespace
+{
+static const OUString lcl_aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.UncachedDataSequence" ));
+
+enum
+{
+// PROP_SOURCE_IDENTIFIER,
+ PROP_NUMBERFORMAT_KEY,
+ PROP_PROPOSED_ROLE,
+ PROP_XML_RANGE
+};
+} // anonymous namespace
+
+
+// ____________________
+namespace chart
+{
+
+UncachedDataSequence::UncachedDataSequence(
+ const Reference< chart2::XInternalDataProvider > & xIntDataProv,
+ const OUString & rRangeRepresentation )
+ : OPropertyContainer( GetBroadcastHelper()),
+ UncachedDataSequence_Base( GetMutex()),
+ m_nNumberFormatKey(0),
+ m_xDataProvider( xIntDataProv ),
+ m_aSourceRepresentation( rRangeRepresentation ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ registerProperties();
+}
+
+UncachedDataSequence::UncachedDataSequence(
+ const Reference< chart2::XInternalDataProvider > & xIntDataProv,
+ const OUString & rRangeRepresentation,
+ const OUString & rRole )
+ : OPropertyContainer( GetBroadcastHelper()),
+ UncachedDataSequence_Base( GetMutex()),
+ m_nNumberFormatKey(0),
+ m_xDataProvider( xIntDataProv ),
+ m_aSourceRepresentation( rRangeRepresentation ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ registerProperties();
+ setFastPropertyValue_NoBroadcast( PROP_PROPOSED_ROLE, uno::makeAny( rRole ));
+}
+
+UncachedDataSequence::UncachedDataSequence( const UncachedDataSequence & rSource )
+ : ::comphelper::OMutexAndBroadcastHelper(),
+ OPropertyContainer( GetBroadcastHelper()),
+ ::comphelper::OPropertyArrayUsageHelper< UncachedDataSequence >(),
+ UncachedDataSequence_Base( GetMutex()),
+ m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
+ m_sRole( rSource.m_sRole ),
+ m_xDataProvider( rSource.m_xDataProvider ),
+ m_aSourceRepresentation( rSource.m_aSourceRepresentation ),
+ m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
+{
+ registerProperties();
+}
+
+UncachedDataSequence::~UncachedDataSequence()
+{}
+
+void UncachedDataSequence::registerProperties()
+{
+ registerProperty( C2U( "NumberFormatKey" ),
+ PROP_NUMBERFORMAT_KEY,
+ 0, // PropertyAttributes
+ & m_nNumberFormatKey,
+ ::getCppuType( & m_nNumberFormatKey ) );
+
+ registerProperty( C2U( "Role" ),
+ PROP_PROPOSED_ROLE,
+ 0, // PropertyAttributes
+ & m_sRole,
+ ::getCppuType( & m_sRole ) );
+
+ registerProperty( C2U( "CachedXMLRange" ),
+ PROP_XML_RANGE,
+ 0, // PropertyAttributes
+ & m_aXMLRange,
+ ::getCppuType( & m_aXMLRange ) );
+}
+
+// ================================================================================
+
+Sequence< OUString > UncachedDataSequence::getSupportedServiceNames_Static()
+{
+ Sequence< OUString > aServices( 4 );
+ aServices[ 0 ] = lcl_aServiceName;
+ aServices[ 1 ] = C2U( "com.sun.star.chart2.data.DataSequence" );
+ aServices[ 2 ] = C2U( "com.sun.star.chart2.data.NumericalDataSequence" );
+ aServices[ 3 ] = C2U( "com.sun.star.chart2.data.TextualDataSequence" );
+ return aServices;
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
+
+// ____ XPropertySet ____
+Reference< beans::XPropertySetInfo > SAL_CALL UncachedDataSequence::getPropertySetInfo()
+ throw(uno::RuntimeException)
+{
+ return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) );
+}
+
+// ____ ::comphelper::OPropertySetHelper ____
+// __________________________________________
+::cppu::IPropertyArrayHelper& UncachedDataSequence::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+// ____ ::comphelper::OPropertyArrayHelper ____
+// ____________________________________________
+::cppu::IPropertyArrayHelper* UncachedDataSequence::createArrayHelper() const
+{
+ Sequence< beans::Property > aProps;
+ // describes all properties which have been registered in the ctor
+ describeProperties( aProps );
+
+ return new ::cppu::OPropertyArrayHelper( aProps );
+}
+
+// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
+APPHELPER_XSERVICEINFO_IMPL( UncachedDataSequence, lcl_aServiceName )
+
+// ================================================================================
+
+// ________ XNumericalDataSequence ________
+Sequence< double > SAL_CALL UncachedDataSequence::getNumericalData()
+ throw (uno::RuntimeException)
+{
+ Sequence< double > aResult;
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ if( m_xDataProvider.is())
+ {
+ Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
+ aResult.realloc( aValues.getLength());
+ ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
+ aResult.getArray(), CommonFunctors::AnyToDouble());
+ }
+ return aResult;
+ // \--
+}
+
+// ________ XTextualDataSequence ________
+Sequence< OUString > SAL_CALL UncachedDataSequence::getTextualData()
+ throw (uno::RuntimeException)
+{
+ Sequence< OUString > aResult;
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ if( m_xDataProvider.is())
+ {
+ Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
+ aResult.realloc( aValues.getLength());
+ ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
+ aResult.getArray(), CommonFunctors::AnyToString());
+ }
+ return aResult;
+ // \--
+}
+
+// ________ XDataSequence ________
+Sequence< Any > SAL_CALL UncachedDataSequence::getData()
+ throw (uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ if( m_xDataProvider.is())
+ return m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation );
+ return Sequence< Any >();
+ // \--
+}
+
+OUString SAL_CALL UncachedDataSequence::getSourceRangeRepresentation()
+ throw (uno::RuntimeException)
+{
+ return getName();
+}
+
+
+Sequence< OUString > SAL_CALL UncachedDataSequence::generateLabel( chart2::data::LabelOrigin )
+ throw (uno::RuntimeException)
+{
+ // auto-generated label is an empty string
+ static const Sequence< OUString > aOneEmptyString( 1 );
+ return aOneEmptyString;
+}
+
+::sal_Int32 SAL_CALL UncachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 )
+ throw (lang::IndexOutOfBoundsException,
+ uno::RuntimeException)
+{
+ return m_nNumberFormatKey;
+}
+
+// ____ XIndexReplace ____
+void SAL_CALL UncachedDataSequence::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element )
+ throw (lang::IllegalArgumentException,
+ lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ // /--
+ MutexGuard aGuard( GetMutex() );
+ Sequence< Any > aData( getData());
+ if( Index < aData.getLength() &&
+ m_xDataProvider.is() )
+ {
+ aData[Index] = Element;
+ m_xDataProvider->setDataByRangeRepresentation( m_aSourceRepresentation, aData );
+ fireModifyEvent();
+ }
+}
+
+// ____ XIndexAccess (base of XIndexReplace) ____
+::sal_Int32 SAL_CALL UncachedDataSequence::getCount()
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Implement!" );
+ return 0;
+}
+
+uno::Any SAL_CALL UncachedDataSequence::getByIndex( ::sal_Int32 )
+ throw (lang::IndexOutOfBoundsException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ OSL_ENSURE( false, "Implement!" );
+ return uno::Any();
+}
+
+// ____ XElementAccess (base of XIndexAccess) ____
+uno::Type SAL_CALL UncachedDataSequence::getElementType()
+ throw (uno::RuntimeException)
+{
+ return ::getCppuType( reinterpret_cast< uno::Any * >(0));
+}
+
+::sal_Bool SAL_CALL UncachedDataSequence::hasElements()
+ throw (uno::RuntimeException)
+{
+ if( ! m_xDataProvider.is())
+ return sal_False;
+ return m_xDataProvider->hasDataByRangeRepresentation( m_aSourceRepresentation );
+}
+
+// ____ XNamed ____
+::rtl::OUString SAL_CALL UncachedDataSequence::getName()
+ throw (uno::RuntimeException)
+{
+ return m_aSourceRepresentation;
+}
+
+void SAL_CALL UncachedDataSequence::setName( const OUString& aName )
+ throw (uno::RuntimeException)
+{
+ m_aSourceRepresentation = aName;
+ fireModifyEvent();
+}
+
+
+
+Reference< util::XCloneable > SAL_CALL UncachedDataSequence::createClone()
+ throw (uno::RuntimeException)
+{
+ UncachedDataSequence * pNewSeq = new UncachedDataSequence( *this );
+ return Reference< util::XCloneable >( pNewSeq );
+}
+
+
+// ____ XModifiable ____
+::sal_Bool SAL_CALL UncachedDataSequence::isModified()
+ throw (uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL UncachedDataSequence::setModified( ::sal_Bool bModified )
+ throw (beans::PropertyVetoException,
+ uno::RuntimeException)
+{
+ if( bModified )
+ fireModifyEvent();
+}
+
+// ____ XModifyBroadcaster (base of XModifiable) ____
+void SAL_CALL UncachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->addModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void SAL_CALL UncachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
+ xBroadcaster->removeModifyListener( aListener );
+ }
+ catch( const uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+void UncachedDataSequence::fireModifyEvent()
+{
+ // @todo: currently never called, as data changes are not yet reported by
+ // the data provider
+ m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/UserDefinedProperties.cxx b/chart2/source/tools/UserDefinedProperties.cxx
new file mode 100644
index 000000000000..707c48c1a6cc
--- /dev/null
+++ b/chart2/source/tools/UserDefinedProperties.cxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include "UserDefinedProperties.hxx"
+#include "macros.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::beans::Property;
+
+namespace chart
+{
+
+void UserDefinedProperties::AddPropertiesToVector(
+ ::std::vector< Property > & rOutProperties )
+{
+ rOutProperties.push_back(
+ Property( C2U( "ChartUserDefinedAttributes" ),
+ PROP_XML_USERDEF_CHART,
+ ::getCppuType( reinterpret_cast< const uno::Reference< container::XNameContainer > * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+ rOutProperties.push_back(
+ Property( C2U( "TextUserDefinedAttributes" ),
+ PROP_XML_USERDEF_TEXT,
+ ::getCppuType( reinterpret_cast< const uno::Reference< container::XNameContainer > * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+ rOutProperties.push_back(
+ Property( C2U( "ParaUserDefinedAttributes" ),
+ PROP_XML_USERDEF_PARA,
+ ::getCppuType( reinterpret_cast< const uno::Reference< container::XNameContainer > * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+ // UserDefinedAttributeSupplier
+ // ----------------------------
+ rOutProperties.push_back(
+ Property( C2U( "UserDefinedAttributes" ),
+ PROP_XML_USERDEF,
+ ::getCppuType( reinterpret_cast< const uno::Reference< container::XNameContainer > * >(0)),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/WeakListenerAdapter.cxx b/chart2/source/tools/WeakListenerAdapter.cxx
new file mode 100644
index 000000000000..bbb54e20bdce
--- /dev/null
+++ b/chart2/source/tools/WeakListenerAdapter.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WeakListenerAdapter.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+WeakModifyListenerAdapter::WeakModifyListenerAdapter(
+ const uno::WeakReference< util::XModifyListener > & xListener ) :
+ WeakListenerAdapter< ::com::sun::star::util::XModifyListener >( xListener )
+{}
+
+WeakModifyListenerAdapter::~WeakModifyListenerAdapter()
+{}
+
+void SAL_CALL WeakModifyListenerAdapter::modified( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ Reference< util::XModifyListener > xModListener( getListener() );
+ if( xModListener.is())
+ xModListener->modified( aEvent );
+}
+
+// --------------------------------------------------------------------------------
+
+WeakSelectionChangeListenerAdapter::WeakSelectionChangeListenerAdapter(
+ const Reference< view::XSelectionChangeListener > & xListener ) :
+ WeakListenerAdapter< ::com::sun::star::view::XSelectionChangeListener >( xListener )
+{}
+
+WeakSelectionChangeListenerAdapter::~WeakSelectionChangeListenerAdapter()
+{}
+
+void SAL_CALL WeakSelectionChangeListenerAdapter::selectionChanged( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+ Reference< view::XSelectionChangeListener > xSelChgListener( getListener() );
+ if( xSelChgListener.is())
+ xSelChgListener->selectionChanged( aEvent );
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/WrappedDefaultProperty.cxx b/chart2/source/tools/WrappedDefaultProperty.cxx
new file mode 100644
index 000000000000..03178d204ef7
--- /dev/null
+++ b/chart2/source/tools/WrappedDefaultProperty.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WrappedDefaultProperty.hxx"
+#include "macros.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+WrappedDefaultProperty::WrappedDefaultProperty(
+ const OUString& rOuterName, const OUString& rInnerName,
+ const uno::Any& rNewOuterDefault ) :
+ WrappedProperty( rOuterName, rInnerName ),
+ m_aOuterDefaultValue( rNewOuterDefault )
+{}
+
+WrappedDefaultProperty::~WrappedDefaultProperty()
+{}
+
+void WrappedDefaultProperty::setPropertyToDefault(
+ const Reference< beans::XPropertyState >& xInnerPropertyState ) const
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ Reference< beans::XPropertySet > xInnerPropSet( xInnerPropertyState, uno::UNO_QUERY );
+ if( xInnerPropSet.is())
+ this->setPropertyValue( m_aOuterDefaultValue, xInnerPropSet );
+}
+
+uno::Any WrappedDefaultProperty::getPropertyDefault(
+ const Reference< beans::XPropertyState >& /* xInnerPropertyState */ ) const
+ throw (beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ return m_aOuterDefaultValue;
+}
+
+beans::PropertyState WrappedDefaultProperty::getPropertyState(
+ const Reference< beans::XPropertyState >& xInnerPropertyState ) const
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ beans::PropertyState aState = beans::PropertyState_DIRECT_VALUE;
+ try
+ {
+ Reference< beans::XPropertySet > xInnerProp( xInnerPropertyState, uno::UNO_QUERY_THROW );
+ uno::Any aValue = this->getPropertyValue( xInnerProp );
+ if( m_aOuterDefaultValue == this->convertInnerToOuterValue( aValue ))
+ aState = beans::PropertyState_DEFAULT_VALUE;
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ return aState;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/WrappedDirectStateProperty.cxx b/chart2/source/tools/WrappedDirectStateProperty.cxx
new file mode 100644
index 000000000000..601b6e199d59
--- /dev/null
+++ b/chart2/source/tools/WrappedDirectStateProperty.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WrappedDirectStateProperty.hxx"
+#include "macros.hxx"
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+namespace chart
+{
+
+WrappedDirectStateProperty::WrappedDirectStateProperty(
+ const OUString& rOuterName, const OUString& rInnerName ) :
+ WrappedProperty( rOuterName, rInnerName )
+{}
+
+WrappedDirectStateProperty::~WrappedDirectStateProperty()
+{}
+
+beans::PropertyState WrappedDirectStateProperty::getPropertyState(
+ const Reference< beans::XPropertyState >& /* xInnerPropertyState */ ) const
+ throw (beans::UnknownPropertyException,
+ uno::RuntimeException)
+{
+ return beans::PropertyState_DIRECT_VALUE;
+}
+
+} // namespace chart
diff --git a/chart2/source/tools/WrappedIgnoreProperty.cxx b/chart2/source/tools/WrappedIgnoreProperty.cxx
new file mode 100644
index 000000000000..aaa6c545a799
--- /dev/null
+++ b/chart2/source/tools/WrappedIgnoreProperty.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WrappedIgnoreProperty.hxx"
+#include "macros.hxx"
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+
+WrappedIgnoreProperty::WrappedIgnoreProperty( const OUString& rOuterName, const Any& rDefaultValue )
+ : WrappedProperty( rOuterName, OUString() )
+ , m_aDefaultValue( rDefaultValue )
+ , m_aCurrentValue( rDefaultValue )
+{
+}
+WrappedIgnoreProperty::~WrappedIgnoreProperty()
+{
+}
+
+void WrappedIgnoreProperty::setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& /* xInnerPropertySet */ ) const
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_aCurrentValue = rOuterValue;
+}
+
+Any WrappedIgnoreProperty::getPropertyValue( const Reference< beans::XPropertySet >& /* xInnerPropertySet */ ) const
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return m_aCurrentValue;
+}
+
+void WrappedIgnoreProperty::setPropertyToDefault( const Reference< beans::XPropertyState >& /* xInnerPropertyState */ ) const
+ throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
+{
+ m_aCurrentValue = m_aDefaultValue;
+}
+
+Any WrappedIgnoreProperty::getPropertyDefault( const Reference< beans::XPropertyState >& /* xInnerPropertyState */ ) const
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return m_aDefaultValue;
+}
+
+beans::PropertyState WrappedIgnoreProperty::getPropertyState( const Reference< beans::XPropertyState >& /* xInnerPropertyState */ ) const
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return ( m_aCurrentValue == m_aDefaultValue
+ ? beans::PropertyState_DEFAULT_VALUE
+ : beans::PropertyState_DIRECT_VALUE );
+}
+
+//static
+void WrappedIgnoreProperties::addIgnoreLineProperties( std::vector< WrappedProperty* >& rList )
+{
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "LineDash" ), uno::makeAny( drawing::LineDash() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineDashName" ), uno::makeAny( rtl::OUString() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineColor" ), uno::makeAny( sal_Int32(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineTransparence" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineWidth" ), uno::makeAny( sal_Int32(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "LineJoint" ), uno::makeAny( drawing::LineJoint_ROUND ) ) );
+}
+
+//static
+void WrappedIgnoreProperties::addIgnoreFillProperties( std::vector< WrappedProperty* >& rList )
+{
+ addIgnoreFillProperties_without_BitmapProperties( rList );
+ addIgnoreFillProperties_only_BitmapProperties( rList );
+}
+
+//static
+void WrappedIgnoreProperties::addIgnoreFillProperties_without_BitmapProperties( ::std::vector< WrappedProperty* >& rList )
+{
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillStyle" ), uno::makeAny( drawing::FillStyle_SOLID ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillColor" ), uno::makeAny( sal_Int32(-1) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillTransparence" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillTransparenceGradientName" ), uno::makeAny( ::rtl::OUString() ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillTransparenceGradient" ), uno::makeAny( awt::Gradient() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillGradientName" ), uno::makeAny( ::rtl::OUString() ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillGradient" ), uno::makeAny( awt::Gradient() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillHatchName" ), uno::makeAny( ::rtl::OUString() ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillHatch" ), uno::makeAny( drawing::Hatch() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBackground" ), uno::makeAny( sal_Bool(sal_False) ) ) );
+}
+
+//static
+void WrappedIgnoreProperties::addIgnoreFillProperties_only_BitmapProperties( ::std::vector< WrappedProperty* >& rList )
+{
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapName" ), uno::makeAny( ::rtl::OUString() ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmap" ), uno::makeAny( uno::Reference< awt::XBitmap > (0) ) ) );
+// rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapURL" ), uno::makeAny( ::rtl::OUString() ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapOffsetX" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapOffsetY" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapPositionOffsetX" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapPositionOffsetY" ), uno::makeAny( sal_Int16(0) ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapRectanglePoint" ), uno::makeAny( drawing::RectanglePoint_LEFT_TOP ) ) );
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapLogicalSize" ), uno::makeAny( sal_Bool(sal_False) ) ) );//todo correct default?
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapSizeX" ), uno::makeAny( sal_Int32(10) ) ) );//todo which default?
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapSizeY" ), uno::makeAny( sal_Int32(10) ) ) );//todo which default?
+ rList.push_back( new WrappedIgnoreProperty( C2U( "FillBitmapMode" ), uno::makeAny( drawing::BitmapMode_REPEAT ) ) );
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/WrappedProperty.cxx b/chart2/source/tools/WrappedProperty.cxx
new file mode 100644
index 000000000000..b41d8a331f11
--- /dev/null
+++ b/chart2/source/tools/WrappedProperty.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WrappedProperty.hxx"
+#include "macros.hxx"
+#include <com/sun/star/drawing/LineStyle.hpp>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+WrappedProperty::WrappedProperty( const OUString& rOuterName, const OUString& rInnerName)
+ : m_aOuterName( rOuterName )
+ , m_aInnerName( rInnerName )
+{
+}
+WrappedProperty::~WrappedProperty()
+{
+}
+
+const OUString& WrappedProperty::getOuterName() const
+{
+ return m_aOuterName;
+}
+
+//virtual
+::rtl::OUString WrappedProperty::getInnerName() const
+{
+ return m_aInnerName;
+}
+
+Any WrappedProperty::convertInnerToOuterValue( const Any& rInnerValue ) const
+{
+ return rInnerValue;
+}
+Any WrappedProperty::convertOuterToInnerValue( const Any& rOuterValue ) const
+{
+ return rOuterValue;
+}
+
+void WrappedProperty::setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if(xInnerPropertySet.is())
+ xInnerPropertySet->setPropertyValue( this->getInnerName(), this->convertOuterToInnerValue( rOuterValue ) );
+}
+
+Any WrappedProperty::getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Any aRet;
+ if( xInnerPropertySet.is() )
+ {
+ aRet = xInnerPropertySet->getPropertyValue( this->getInnerName() );
+ aRet = this->convertInnerToOuterValue( aRet );
+ }
+ return aRet;
+}
+
+void WrappedProperty::setPropertyToDefault( const Reference< beans::XPropertyState >& xInnerPropertyState ) const
+ throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
+{
+ if( xInnerPropertyState.is() && this->getInnerName().getLength() )
+ xInnerPropertyState->setPropertyToDefault(this->getInnerName());
+ else
+ {
+ Reference< beans::XPropertySet > xInnerProp( xInnerPropertyState, uno::UNO_QUERY );
+ setPropertyValue( getPropertyDefault( xInnerPropertyState ), xInnerProp );
+ }
+}
+
+Any WrappedProperty::getPropertyDefault( const Reference< beans::XPropertyState >& xInnerPropertyState ) const
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Any aRet;
+ if( xInnerPropertyState.is() )
+ {
+ aRet = xInnerPropertyState->getPropertyDefault( this->getInnerName() );
+ aRet = this->convertInnerToOuterValue( aRet );
+ }
+ return aRet;
+}
+
+beans::PropertyState WrappedProperty::getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ beans::PropertyState aState = beans::PropertyState_DIRECT_VALUE;
+ rtl::OUString aInnerName( this->getInnerName() );
+ if( xInnerPropertyState.is() && aInnerName.getLength() )
+ aState = xInnerPropertyState->getPropertyState( aInnerName );
+ else
+ {
+ try
+ {
+ Reference< beans::XPropertySet > xInnerProp( xInnerPropertyState, uno::UNO_QUERY );
+ uno::Any aValue = this->getPropertyValue( xInnerProp );
+ if( !aValue.hasValue() )
+ aState = beans::PropertyState_DEFAULT_VALUE;
+ else
+ {
+ uno::Any aDefault = this->getPropertyDefault( xInnerPropertyState );
+ if( aValue == aDefault )
+ aState = beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ return aState;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/WrappedPropertySet.cxx b/chart2/source/tools/WrappedPropertySet.cxx
new file mode 100644
index 000000000000..843aeb261a5f
--- /dev/null
+++ b/chart2/source/tools/WrappedPropertySet.cxx
@@ -0,0 +1,495 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "WrappedPropertySet.hxx"
+#include "macros.hxx"
+
+// header for define DELETEZ
+#include <tools/solar.h>
+
+#include <tools/debug.hxx>
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+
+WrappedPropertySet::WrappedPropertySet()
+ : MutexContainer()
+ , m_xInfo(0)
+ , m_pPropertyArrayHelper(0)
+ , m_pWrappedPropertyMap(0)
+{
+}
+WrappedPropertySet::~WrappedPropertySet()
+{
+ clearWrappedPropertySet();
+}
+
+Reference< beans::XPropertyState > WrappedPropertySet::getInnerPropertyState()
+{
+ return Reference< beans::XPropertyState >( getInnerPropertySet(), uno::UNO_QUERY );
+}
+
+void WrappedPropertySet::clearWrappedPropertySet()
+{
+ // /--
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ //delete all wrapped properties
+ if(m_pWrappedPropertyMap)
+ {
+ for( tWrappedPropertyMap::iterator aIt = m_pWrappedPropertyMap->begin()
+ ; aIt!= m_pWrappedPropertyMap->end(); aIt++ )
+ {
+ const WrappedProperty* pWrappedProperty = (*aIt).second;
+ DELETEZ(pWrappedProperty);
+ }
+ }
+
+ DELETEZ(m_pPropertyArrayHelper);
+ DELETEZ(m_pWrappedPropertyMap);
+
+ m_xInfo = NULL;
+ // \--
+}
+
+//XPropertySet
+Reference< beans::XPropertySetInfo > SAL_CALL WrappedPropertySet::getPropertySetInfo( )
+ throw (uno::RuntimeException)
+{
+ if( !m_xInfo.is() )
+ {
+ // /--
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( !m_xInfo.is() )
+ {
+ m_xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
+ }
+ // \--
+ }
+ return m_xInfo;
+}
+
+void SAL_CALL WrappedPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( nHandle );
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( pWrappedProperty )
+ pWrappedProperty->setPropertyValue( rValue, xInnerPropertySet );
+ else if( xInnerPropertySet.is() )
+ xInnerPropertySet->setPropertyValue( rPropertyName, rValue );
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ERROR("found no inner property set to map to");
+#endif
+ }
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ throw ex;
+ }
+ catch( beans::PropertyVetoException& ex )
+ {
+ throw ex;
+ }
+ catch( lang::IllegalArgumentException& ex )
+ {
+ throw ex;
+ }
+ catch( lang::WrappedTargetException& ex )
+ {
+ throw ex;
+ }
+ catch( uno::RuntimeException& ex )
+ {
+ throw ex;
+ }
+ catch( uno::Exception& ex )
+ {
+ OSL_ENSURE(false,"invalid exception caught in WrappedPropertySet::setPropertyValue");
+ lang::WrappedTargetException aWrappedException;
+ aWrappedException.TargetException = uno::makeAny( ex );
+ throw aWrappedException;
+ }
+}
+Any SAL_CALL WrappedPropertySet::getPropertyValue( const OUString& rPropertyName )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Any aRet;
+
+ try
+ {
+ sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( nHandle );
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( pWrappedProperty )
+ aRet = pWrappedProperty->getPropertyValue( xInnerPropertySet );
+ else if( xInnerPropertySet.is() )
+ aRet = xInnerPropertySet->getPropertyValue( rPropertyName );
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ERROR("found no inner property set to map to");
+#endif
+ }
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ throw ex;
+ }
+ catch( lang::WrappedTargetException& ex )
+ {
+ throw ex;
+ }
+ catch( uno::RuntimeException& ex )
+ {
+ throw ex;
+ }
+ catch( uno::Exception& ex )
+ {
+ OSL_ENSURE(false,"invalid exception caught in WrappedPropertySet::setPropertyValue");
+ lang::WrappedTargetException aWrappedException;
+ aWrappedException.TargetException = uno::makeAny( ex );
+ throw aWrappedException;
+ }
+
+ return aRet;
+}
+
+void SAL_CALL WrappedPropertySet::addPropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& xListener )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( xInnerPropertySet.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ xInnerPropertySet->addPropertyChangeListener( pWrappedProperty->getInnerName(), xListener );
+ else
+ xInnerPropertySet->addPropertyChangeListener( rPropertyName, xListener );
+ }
+// m_aBoundListenerContainer.addInterface( (sal_Int32)nHandle, xListener );
+}
+void SAL_CALL WrappedPropertySet::removePropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& aListener )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( xInnerPropertySet.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ xInnerPropertySet->removePropertyChangeListener( pWrappedProperty->getInnerName(), aListener );
+ else
+ xInnerPropertySet->removePropertyChangeListener( rPropertyName, aListener );
+ }
+}
+void SAL_CALL WrappedPropertySet::addVetoableChangeListener( const OUString& rPropertyName, const Reference< beans::XVetoableChangeListener >& aListener )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( xInnerPropertySet.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ xInnerPropertySet->addVetoableChangeListener( pWrappedProperty->getInnerName(), aListener );
+ else
+ xInnerPropertySet->addVetoableChangeListener( rPropertyName, aListener );
+ }
+}
+void SAL_CALL WrappedPropertySet::removeVetoableChangeListener( const OUString& rPropertyName, const Reference< beans::XVetoableChangeListener >& aListener )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Reference< beans::XPropertySet > xInnerPropertySet( this->getInnerPropertySet() );
+ if( xInnerPropertySet.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ xInnerPropertySet->removeVetoableChangeListener( pWrappedProperty->getInnerName(), aListener );
+ else
+ xInnerPropertySet->removeVetoableChangeListener( rPropertyName, aListener );
+ }
+}
+
+//XMultiPropertySet
+void SAL_CALL WrappedPropertySet::setPropertyValues( const Sequence< OUString >& rNameSeq, const Sequence< Any >& rValueSeq )
+ throw (beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ bool bUnknownProperty = false;
+ sal_Int32 nMinCount = std::min( rValueSeq.getLength(), rNameSeq.getLength() );
+ for(sal_Int32 nN=0; nN<nMinCount; nN++)
+ {
+ ::rtl::OUString aPropertyName( rNameSeq[nN] );
+ try
+ {
+ this->setPropertyValue( aPropertyName, rValueSeq[nN] );
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ bUnknownProperty = true;
+ }
+ }
+ //todo: store unknown properties elsewhere
+// if( bUnknownProperty )
+// throw beans::UnknownPropertyException();
+}
+Sequence< Any > SAL_CALL WrappedPropertySet::getPropertyValues( const Sequence< OUString >& rNameSeq )
+ throw (uno::RuntimeException)
+{
+ Sequence< Any > aRetSeq;
+ if( rNameSeq.getLength() )
+ {
+ aRetSeq.realloc( rNameSeq.getLength() );
+ for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++)
+ {
+ try
+ {
+ ::rtl::OUString aPropertyName( rNameSeq[nN] );
+ aRetSeq[nN] = this->getPropertyValue( aPropertyName );
+ }
+ catch( beans::UnknownPropertyException& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ catch( lang::WrappedTargetException& ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+ }
+ }
+ return aRetSeq;
+}
+void SAL_CALL WrappedPropertySet::addPropertiesChangeListener( const Sequence< OUString >& /* rNameSeq */, const Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE(false,"not implemented yet");
+ //todo
+}
+void SAL_CALL WrappedPropertySet::removePropertiesChangeListener( const Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE(false,"not implemented yet");
+ //todo
+}
+void SAL_CALL WrappedPropertySet::firePropertiesChangeEvent( const Sequence< OUString >& /* rNameSeq */, const Reference< beans::XPropertiesChangeListener >& /* xListener */ )
+ throw (uno::RuntimeException)
+{
+ OSL_ENSURE(false,"not implemented yet");
+ //todo
+}
+
+//XPropertyState
+beans::PropertyState SAL_CALL WrappedPropertySet::getPropertyState( const OUString& rPropertyName )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ beans::PropertyState aState( beans::PropertyState_DIRECT_VALUE );
+
+ Reference< beans::XPropertyState > xInnerPropertyState( this->getInnerPropertyState() );
+ if( xInnerPropertyState.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ aState = pWrappedProperty->getPropertyState( xInnerPropertyState );
+ else
+ aState = xInnerPropertyState->getPropertyState( rPropertyName );
+ }
+ return aState;
+}
+
+const WrappedProperty* WrappedPropertySet::getWrappedProperty( const ::rtl::OUString& rOuterName )
+{
+ sal_Int32 nHandle = getInfoHelper().getHandleByName( rOuterName );
+ return getWrappedProperty( nHandle );
+}
+
+const WrappedProperty* WrappedPropertySet::getWrappedProperty( sal_Int32 nHandle )
+{
+ tWrappedPropertyMap::const_iterator aFound( getWrappedPropertyMap().find( nHandle ) );
+ if( aFound != getWrappedPropertyMap().end() )
+ return (*aFound).second;
+ return 0;
+}
+
+Sequence< beans::PropertyState > SAL_CALL WrappedPropertySet::getPropertyStates( const Sequence< OUString >& rNameSeq )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ Sequence< beans::PropertyState > aRetSeq;
+ if( rNameSeq.getLength() )
+ {
+ aRetSeq.realloc( rNameSeq.getLength() );
+ for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++)
+ {
+ ::rtl::OUString aPropertyName( rNameSeq[nN] );
+ aRetSeq[nN] = this->getPropertyState( aPropertyName );
+ }
+ }
+ return aRetSeq;
+}
+
+void SAL_CALL WrappedPropertySet::setPropertyToDefault( const OUString& rPropertyName )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ Reference< beans::XPropertyState > xInnerPropertyState( this->getInnerPropertyState() );
+ if( xInnerPropertyState.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ pWrappedProperty->setPropertyToDefault( xInnerPropertyState );
+ else
+ xInnerPropertyState->setPropertyToDefault( rPropertyName );
+ }
+}
+Any SAL_CALL WrappedPropertySet::getPropertyDefault( const OUString& rPropertyName )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Any aRet;
+ Reference< beans::XPropertyState > xInnerPropertyState( this->getInnerPropertyState() );
+ if( xInnerPropertyState.is() )
+ {
+ const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
+ if( pWrappedProperty )
+ aRet = pWrappedProperty->getPropertyDefault(xInnerPropertyState);
+ else
+ aRet = xInnerPropertyState->getPropertyDefault( rPropertyName );
+ }
+ return aRet;
+}
+
+//XMultiPropertyStates
+void SAL_CALL WrappedPropertySet::setAllPropertiesToDefault( )
+ throw (uno::RuntimeException)
+{
+ const Sequence< beans::Property >& rPropSeq = getPropertySequence();
+ for(sal_Int32 nN=0; nN<rPropSeq.getLength(); nN++)
+ {
+ ::rtl::OUString aPropertyName( rPropSeq[nN].Name );
+ this->setPropertyToDefault( aPropertyName );
+ }
+}
+void SAL_CALL WrappedPropertySet::setPropertiesToDefault( const Sequence< OUString >& rNameSeq )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++)
+ {
+ ::rtl::OUString aPropertyName( rNameSeq[nN] );
+ this->setPropertyToDefault( aPropertyName );
+ }
+}
+Sequence< Any > SAL_CALL WrappedPropertySet::getPropertyDefaults( const Sequence< OUString >& rNameSeq )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ Sequence< Any > aRetSeq;
+ if( rNameSeq.getLength() )
+ {
+ aRetSeq.realloc( rNameSeq.getLength() );
+ for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++)
+ {
+ ::rtl::OUString aPropertyName( rNameSeq[nN] );
+ aRetSeq[nN] = this->getPropertyDefault( aPropertyName );
+ }
+ }
+ return aRetSeq;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+::cppu::IPropertyArrayHelper& WrappedPropertySet::getInfoHelper()
+{
+ if(!m_pPropertyArrayHelper)
+ {
+ // /--
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if(!m_pPropertyArrayHelper)
+ {
+ sal_Bool bSorted = sal_True;
+ m_pPropertyArrayHelper = new ::cppu::OPropertyArrayHelper( getPropertySequence(), bSorted );
+ }
+ // \--
+ }
+ return *m_pPropertyArrayHelper;
+}
+
+//-----------------------------------------------------------------------------
+
+tWrappedPropertyMap& WrappedPropertySet::getWrappedPropertyMap()
+{
+ if(!m_pWrappedPropertyMap)
+ {
+ // /--
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if(!m_pWrappedPropertyMap)
+ {
+ std::vector< WrappedProperty* > aPropList( createWrappedProperties() );
+ m_pWrappedPropertyMap = new tWrappedPropertyMap();
+
+ for( std::vector< WrappedProperty* >::const_iterator aIt = aPropList.begin(); aIt!=aPropList.end(); ++aIt )
+ {
+ WrappedProperty* pProperty = *aIt;
+ if(pProperty)
+ {
+ sal_Int32 nHandle = getInfoHelper().getHandleByName( pProperty->getOuterName() );
+
+ if( nHandle == -1 )
+ {
+ OSL_ENSURE( false, "missing property in property list" );
+ delete pProperty;//we are owner or the created WrappedProperties
+ }
+ else if( m_pWrappedPropertyMap->find( nHandle ) != m_pWrappedPropertyMap->end() )
+ {
+ //duplicate Wrapped property
+ OSL_ENSURE( false, "duplicate Wrapped property" );
+ delete pProperty;//we are owner or the created WrappedProperties
+ }
+ else
+ (*m_pWrappedPropertyMap)[ nHandle ] = pProperty;
+ }
+ }
+ }
+ // \--
+ }
+ return *m_pWrappedPropertyMap;
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/tools/XMLRangeHelper.cxx b/chart2/source/tools/XMLRangeHelper.cxx
new file mode 100644
index 000000000000..c5d345db0124
--- /dev/null
+++ b/chart2/source/tools/XMLRangeHelper.cxx
@@ -0,0 +1,418 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+
+#include "XMLRangeHelper.hxx"
+#include <unotools/charclass.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+#include <functional>
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ================================================================================
+
+namespace
+{
+/** unary function that escapes backslashes and single quotes in a sal_Unicode
+ array (which you can get from an OUString with getStr()) and puts the result
+ into the OUStringBuffer given in the CTOR
+ */
+class lcl_Escape : public ::std::unary_function< sal_Unicode, void >
+{
+public:
+ lcl_Escape( ::rtl::OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
+ void operator() ( sal_Unicode aChar )
+ {
+ static const sal_Unicode m_aQuote( '\'' );
+ static const sal_Unicode m_aBackslash( '\\' );
+
+ if( aChar == m_aQuote ||
+ aChar == m_aBackslash )
+ m_aResultBuffer.append( m_aBackslash );
+ m_aResultBuffer.append( aChar );
+ }
+
+private:
+ ::rtl::OUStringBuffer & m_aResultBuffer;
+};
+
+// ----------------------------------------
+
+/** unary function that removes backslash escapes in a sal_Unicode array (which
+ you can get from an OUString with getStr()) and puts the result into the
+ OUStringBuffer given in the CTOR
+ */
+class lcl_UnEscape : public ::std::unary_function< sal_Unicode, void >
+{
+public:
+ lcl_UnEscape( ::rtl::OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
+ void operator() ( sal_Unicode aChar )
+ {
+ static const sal_Unicode m_aBackslash( '\\' );
+
+ if( aChar != m_aBackslash )
+ m_aResultBuffer.append( aChar );
+ }
+
+private:
+ ::rtl::OUStringBuffer & m_aResultBuffer;
+};
+
+// ----------------------------------------
+
+OUStringBuffer lcl_getXMLStringForCell( const ::chart::XMLRangeHelper::Cell & rCell )
+{
+ ::rtl::OUStringBuffer aBuffer;
+ if( rCell.empty())
+ return aBuffer;
+
+ sal_Int32 nCol = rCell.nColumn;
+ aBuffer.append( (sal_Unicode)'.' );
+ if( ! rCell.bRelativeColumn )
+ aBuffer.append( (sal_Unicode)'$' );
+
+ // get A, B, C, ..., AA, AB, ... representation of column number
+ if( nCol < 26 )
+ aBuffer.append( (sal_Unicode)('A' + nCol) );
+ else if( nCol < 702 )
+ {
+ aBuffer.append( (sal_Unicode)('A' + nCol / 26 - 1 ));
+ aBuffer.append( (sal_Unicode)('A' + nCol % 26) );
+ }
+ else // works for nCol <= 18,278
+ {
+ aBuffer.append( (sal_Unicode)('A' + nCol / 702 - 1 ));
+ aBuffer.append( (sal_Unicode)('A' + (nCol % 702) / 26 ));
+ aBuffer.append( (sal_Unicode)('A' + nCol % 26) );
+ }
+
+ // write row number as number
+ if( ! rCell.bRelativeRow )
+ aBuffer.append( (sal_Unicode)'$' );
+ aBuffer.append( rCell.nRow + (sal_Int32)1 );
+
+ return aBuffer;
+}
+
+void lcl_getSingleCellAddressFromXMLString(
+ const ::rtl::OUString& rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ ::chart::XMLRangeHelper::Cell & rOutCell )
+{
+ // expect "\$?[a-zA-Z]+\$?[1-9][0-9]*"
+ static const sal_Unicode aDollar( '$' );
+ static const sal_Unicode aLetterA( 'A' );
+
+ ::rtl::OUString aCellStr = rXMLString.copy( nStartPos, nEndPos - nStartPos + 1 ).toAsciiUpperCase();
+ const sal_Unicode* pStrArray = aCellStr.getStr();
+ sal_Int32 nLength = aCellStr.getLength();
+ sal_Int32 i = nLength - 1, nColumn = 0;
+
+ // parse number for row
+ while( CharClass::isAsciiDigit( pStrArray[ i ] ) && i >= 0 )
+ i--;
+ rOutCell.nRow = (aCellStr.copy( i + 1 )).toInt32() - 1;
+ // a dollar in XML means absolute (whereas in UI it means relative)
+ if( pStrArray[ i ] == aDollar )
+ {
+ i--;
+ rOutCell.bRelativeRow = false;
+ }
+ else
+ rOutCell.bRelativeRow = true;
+
+ // parse rest for column
+ sal_Int32 nPower = 1;
+ while( CharClass::isAsciiAlpha( pStrArray[ i ] ))
+ {
+ nColumn += (pStrArray[ i ] - aLetterA + 1) * nPower;
+ i--;
+ nPower *= 26;
+ }
+ rOutCell.nColumn = nColumn - 1;
+
+ rOutCell.bRelativeColumn = true;
+ if( i >= 0 &&
+ pStrArray[ i ] == aDollar )
+ rOutCell.bRelativeColumn = false;
+ rOutCell.bIsEmpty = false;
+}
+
+bool lcl_getCellAddressFromXMLString(
+ const ::rtl::OUString& rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ ::chart::XMLRangeHelper::Cell & rOutCell,
+ ::rtl::OUString& rOutTableName )
+{
+ static const sal_Unicode aDot( '.' );
+ static const sal_Unicode aQuote( '\'' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nNextDelimiterPos = nStartPos;
+
+ sal_Int32 nDelimiterPos = nStartPos;
+ bool bInQuotation = false;
+ // parse table name
+ while( nDelimiterPos < nEndPos &&
+ ( bInQuotation || rXMLString[ nDelimiterPos ] != aDot ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nDelimiterPos ] == aBackslash )
+ ++nDelimiterPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nDelimiterPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nDelimiterPos;
+ }
+
+ if( nDelimiterPos == -1 )
+ return false;
+
+ if( nDelimiterPos > nStartPos && nDelimiterPos < nEndPos )
+ {
+ // there is a table name before the address
+
+ ::rtl::OUStringBuffer aTableNameBuffer;
+ const sal_Unicode * pTableName = rXMLString.getStr();
+
+ // remove escapes from table name
+ ::std::for_each( pTableName + nStartPos,
+ pTableName + nDelimiterPos,
+ lcl_UnEscape( aTableNameBuffer ));
+
+ // unquote quoted table name
+ const sal_Unicode * pBuf = aTableNameBuffer.getStr();
+ if( pBuf[ 0 ] == aQuote &&
+ pBuf[ aTableNameBuffer.getLength() - 1 ] == aQuote )
+ {
+ ::rtl::OUString aName = aTableNameBuffer.makeStringAndClear();
+ rOutTableName = aName.copy( 1, aName.getLength() - 2 );
+ }
+ else
+ rOutTableName = aTableNameBuffer.makeStringAndClear();
+ }
+ else
+ nDelimiterPos = nStartPos;
+
+ for( sal_Int32 i = 0;
+ nNextDelimiterPos < nEndPos;
+ nDelimiterPos = nNextDelimiterPos, i++ )
+ {
+ nNextDelimiterPos = rXMLString.indexOf( aDot, nDelimiterPos + 1 );
+ if( nNextDelimiterPos == -1 ||
+ nNextDelimiterPos > nEndPos )
+ nNextDelimiterPos = nEndPos + 1;
+
+ if( i==0 )
+ // only take first cell
+ lcl_getSingleCellAddressFromXMLString(
+ rXMLString, nDelimiterPos + 1, nNextDelimiterPos - 1, rOutCell );
+ }
+
+ return true;
+}
+
+bool lcl_getCellRangeAddressFromXMLString(
+ const ::rtl::OUString& rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ ::chart::XMLRangeHelper::CellRange & rOutRange )
+{
+ bool bResult = true;
+ static const sal_Unicode aColon( ':' );
+ static const sal_Unicode aQuote( '\'' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nDelimiterPos = nStartPos;
+ bool bInQuotation = false;
+ // parse table name
+ while( nDelimiterPos < nEndPos &&
+ ( bInQuotation || rXMLString[ nDelimiterPos ] != aColon ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nDelimiterPos ] == aBackslash )
+ ++nDelimiterPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nDelimiterPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nDelimiterPos;
+ }
+
+ if( nDelimiterPos == nEndPos )
+ {
+ // only one cell
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nEndPos,
+ rOutRange.aUpperLeft,
+ rOutRange.aTableName );
+ if( !rOutRange.aTableName.getLength() )
+ bResult = false;
+ }
+ else
+ {
+ // range (separated by a colon)
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nDelimiterPos - 1,
+ rOutRange.aUpperLeft,
+ rOutRange.aTableName );
+ if( !rOutRange.aTableName.getLength() )
+ bResult = false;
+
+ ::rtl::OUString sTableSecondName;
+ if( bResult )
+ {
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nDelimiterPos + 1, nEndPos,
+ rOutRange.aLowerRight,
+ sTableSecondName );
+ }
+ if( bResult &&
+ sTableSecondName.getLength() &&
+ ! sTableSecondName.equals( rOutRange.aTableName ))
+ bResult = false;
+ }
+
+ return bResult;
+}
+
+} // anonymous namespace
+
+// ================================================================================
+
+namespace chart
+{
+namespace XMLRangeHelper
+{
+
+CellRange getCellRangeFromXMLString( const OUString & rXMLString )
+{
+ static const sal_Unicode aSpace( ' ' );
+ static const sal_Unicode aQuote( '\'' );
+// static const sal_Unicode aDoubleQuote( '\"' );
+ static const sal_Unicode aDollar( '$' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nStartPos = 0;
+ sal_Int32 nEndPos = nStartPos;
+ const sal_Int32 nLength = rXMLString.getLength();
+
+ // reset
+ CellRange aResult;
+
+ // iterate over different ranges
+ for( sal_Int32 i = 0;
+ nEndPos < nLength;
+ nStartPos = ++nEndPos, i++ )
+ {
+ // find start point of next range
+
+ // ignore leading '$'
+ if( rXMLString[ nEndPos ] == aDollar)
+ nEndPos++;
+
+ bool bInQuotation = false;
+ // parse range
+ while( nEndPos < nLength &&
+ ( bInQuotation || rXMLString[ nEndPos ] != aSpace ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nEndPos ] == aBackslash )
+ ++nEndPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nEndPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nEndPos;
+ }
+
+ if( ! lcl_getCellRangeAddressFromXMLString(
+ rXMLString,
+ nStartPos, nEndPos - 1,
+ aResult ))
+ {
+ // if an error occured, bail out
+ return CellRange();
+ }
+ }
+
+ return aResult;
+}
+
+OUString getXMLStringFromCellRange( const CellRange & rRange )
+{
+ static const sal_Unicode aSpace( ' ' );
+ static const sal_Unicode aQuote( '\'' );
+
+ ::rtl::OUStringBuffer aBuffer;
+
+ if( (rRange.aTableName).getLength())
+ {
+ bool bNeedsEscaping = ( rRange.aTableName.indexOf( aQuote ) > -1 );
+ bool bNeedsQuoting = bNeedsEscaping || ( rRange.aTableName.indexOf( aSpace ) > -1 );
+
+ // quote table name if it contains spaces or quotes
+ if( bNeedsQuoting )
+ {
+ // leading quote
+ aBuffer.append( aQuote );
+
+ // escape existing quotes
+ if( bNeedsEscaping )
+ {
+ const sal_Unicode * pTableNameBeg = rRange.aTableName.getStr();
+
+ // append the quoted string at the buffer
+ ::std::for_each( pTableNameBeg,
+ pTableNameBeg + rRange.aTableName.getLength(),
+ lcl_Escape( aBuffer ) );
+ }
+ else
+ aBuffer.append( rRange.aTableName );
+
+ // final quote
+ aBuffer.append( aQuote );
+ }
+ else
+ aBuffer.append( rRange.aTableName );
+ }
+ aBuffer.append( lcl_getXMLStringForCell( rRange.aUpperLeft ));
+
+ if( ! rRange.aLowerRight.empty())
+ {
+ // we have a range (not a single cell)
+ aBuffer.append( sal_Unicode( ':' ));
+ aBuffer.append( lcl_getXMLStringForCell( rRange.aLowerRight ));
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+} // namespace XMLRangeHelper
+} // namespace chart
diff --git a/chart2/source/tools/_serviceregistration_tools.cxx b/chart2/source/tools/_serviceregistration_tools.cxx
new file mode 100644
index 000000000000..387b87dfab5a
--- /dev/null
+++ b/chart2/source/tools/_serviceregistration_tools.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_chart2.hxx"
+#include <cppuhelper/implementationentry.hxx>
+#include "LabeledDataSequence.hxx"
+#include "CachedDataSequence.hxx"
+#include "DataSource.hxx"
+#include "ConfigColorScheme.hxx"
+#include "Scaling.hxx"
+#include "ErrorBar.hxx"
+#include "RegressionCurveModel.hxx"
+#include "RegressionEquation.hxx"
+#include "InternalDataProvider.hxx"
+#include "charttoolsdllapi.hxx"
+
+static struct ::cppu::ImplementationEntry g_entries_chart2_tools[] =
+{
+ {
+ ::chart::LabeledDataSequence::create
+ , ::chart::LabeledDataSequence::getImplementationName_Static
+ , ::chart::LabeledDataSequence::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::CachedDataSequence::create
+ , ::chart::CachedDataSequence::getImplementationName_Static
+ , ::chart::CachedDataSequence::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::DataSource::create
+ , ::chart::DataSource::getImplementationName_Static
+ , ::chart::DataSource::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::ConfigColorScheme::create
+ , ::chart::ConfigColorScheme::getImplementationName_Static
+ , ::chart::ConfigColorScheme::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+
+ ,{
+ ::chart::LogarithmicScaling::create
+ , ::chart::LogarithmicScaling::getImplementationName_Static
+ , ::chart::LogarithmicScaling::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::ExponentialScaling::create
+ , ::chart::ExponentialScaling::getImplementationName_Static
+ , ::chart::ExponentialScaling::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::LinearScaling::create
+ , ::chart::LinearScaling::getImplementationName_Static
+ , ::chart::LinearScaling::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::PowerScaling::create
+ , ::chart::PowerScaling::getImplementationName_Static
+ , ::chart::PowerScaling::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::ErrorBar::create
+ , ::chart::ErrorBar::getImplementationName_Static
+ , ::chart::ErrorBar::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::MeanValueRegressionCurve::create
+ , ::chart::MeanValueRegressionCurve::getImplementationName_Static
+ , ::chart::MeanValueRegressionCurve::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::LinearRegressionCurve::create
+ , ::chart::LinearRegressionCurve::getImplementationName_Static
+ , ::chart::LinearRegressionCurve::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::LogarithmicRegressionCurve::create
+ , ::chart::LogarithmicRegressionCurve::getImplementationName_Static
+ , ::chart::LogarithmicRegressionCurve::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::ExponentialRegressionCurve::create
+ , ::chart::ExponentialRegressionCurve::getImplementationName_Static
+ , ::chart::ExponentialRegressionCurve::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::PotentialRegressionCurve::create
+ , ::chart::PotentialRegressionCurve::getImplementationName_Static
+ , ::chart::PotentialRegressionCurve::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::RegressionEquation::create
+ , ::chart::RegressionEquation::getImplementationName_Static
+ , ::chart::RegressionEquation::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{
+ ::chart::InternalDataProvider::create
+ , ::chart::InternalDataProvider::getImplementationName_Static
+ , ::chart::InternalDataProvider::getSupportedServiceNames_Static
+ , ::cppu::createSingleComponentFactory
+ , 0
+ , 0
+ }
+ ,{ 0, 0, 0, 0, 0, 0 }
+};
+
+// component exports
+extern "C"
+{
+//==================================================================================================
+OOO_DLLPUBLIC_CHARTTOOLS void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+OOO_DLLPUBLIC_CHARTTOOLS sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_writeInfoHelper(
+ pServiceManager, pRegistryKey, g_entries_chart2_tools );
+}
+//==================================================================================================
+OOO_DLLPUBLIC_CHARTTOOLS void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey , g_entries_chart2_tools );
+}
+}
+//=========================================================================
diff --git a/chart2/source/tools/exports.flt b/chart2/source/tools/exports.flt
new file mode 100644
index 000000000000..376659ce91b7
--- /dev/null
+++ b/chart2/source/tools/exports.flt
@@ -0,0 +1,3 @@
+_real@
+_TI1
+_TI2
diff --git a/chart2/source/tools/makefile.mk b/chart2/source/tools/makefile.mk
new file mode 100644
index 000000000000..2f990af7adb0
--- /dev/null
+++ b/chart2/source/tools/makefile.mk
@@ -0,0 +1,189 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ= ..$/..
+PRJNAME= chart2
+TARGET= charttools
+
+PRJINC= $(PRJ)$/source
+
+USE_DEFFILE= TRUE
+ENABLE_EXCEPTIONS= TRUE
+VISIBILITY_HIDDEN= TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE: $(PRJ)$/util$/makefile.pmk
+
+CDEFS += -DOOO_DLLIMPLEMENTATION_CHARTTOOLS
+
+# --- export library -------------------------------------------------
+
+#You can use several library macros of this form to build libraries that
+#do not consist of all object files in a directory or to merge different libraries.
+#LIB1TARGET= $(SLB)$/_$(TARGET).lib
+
+#Specifies object files to bind into linked libraries.
+SLOFILES= \
+ $(SLO)$/ErrorBar.obj \
+ $(SLO)$/TrueGuard.obj \
+ $(SLO)$/LifeTime.obj \
+ $(SLO)$/MediaDescriptorHelper.obj \
+ $(SLO)$/ConfigColorScheme.obj \
+ $(SLO)$/ColorPerPointHelper.obj \
+ $(SLO)$/ObjectIdentifier.obj \
+ $(SLO)$/CachedDataSequence.obj \
+ $(SLO)$/CommonConverters.obj \
+ $(SLO)$/DataSeriesHelper.obj \
+ $(SLO)$/DataSource.obj \
+ $(SLO)$/DataSourceHelper.obj \
+ $(SLO)$/DiagramHelper.obj \
+ $(SLO)$/ExponentialRegressionCurveCalculator.obj \
+ $(SLO)$/ImplOPropertySet.obj \
+ $(SLO)$/InternalData.obj \
+ $(SLO)$/InternalDataProvider.obj \
+ $(SLO)$/LabeledDataSequence.obj \
+ $(SLO)$/LinearRegressionCurveCalculator.obj \
+ $(SLO)$/LogarithmicRegressionCurveCalculator.obj \
+ $(SLO)$/MeanValueRegressionCurveCalculator.obj \
+ $(SLO)$/OPropertySet.obj \
+ $(SLO)$/WrappedPropertySet.obj \
+ $(SLO)$/WrappedProperty.obj \
+ $(SLO)$/WrappedIgnoreProperty.obj \
+ $(SLO)$/WrappedDefaultProperty.obj \
+ $(SLO)$/WrappedDirectStateProperty.obj \
+ $(SLO)$/PotentialRegressionCurveCalculator.obj \
+ $(SLO)$/RegressionCurveHelper.obj \
+ $(SLO)$/RegressionCurveModel.obj \
+ $(SLO)$/RelativeSizeHelper.obj \
+ $(SLO)$/RelativePositionHelper.obj \
+ $(SLO)$/Scaling.obj \
+ $(SLO)$/SceneProperties.obj \
+ $(SLO)$/ThreeDHelper.obj \
+ $(SLO)$/StatisticsHelper.obj \
+ $(SLO)$/ChartModelHelper.obj \
+ $(SLO)$/ChartViewHelper.obj \
+ $(SLO)$/ChartTypeHelper.obj \
+ $(SLO)$/AxisHelper.obj \
+ $(SLO)$/MutexContainer.obj \
+ $(SLO)$/PropertyHelper.obj \
+ $(SLO)$/FormattedStringHelper.obj \
+ $(SLO)$/TitleHelper.obj \
+ $(SLO)$/LegendHelper.obj \
+ $(SLO)$/CharacterProperties.obj \
+ $(SLO)$/LineProperties.obj \
+ $(SLO)$/FillProperties.obj \
+ $(SLO)$/UserDefinedProperties.obj \
+ $(SLO)$/NameContainer.obj \
+ $(SLO)$/ChartDebugTrace.obj \
+ $(SLO)$/_serviceregistration_tools.obj \
+ $(SLO)$/UncachedDataSequence.obj \
+ $(SLO)$/XMLRangeHelper.obj \
+ $(SLO)$/ModifyListenerHelper.obj \
+ $(SLO)$/ModifyListenerCallBack.obj \
+ $(SLO)$/BaseGFXHelper.obj \
+ $(SLO)$/ControllerLockGuard.obj \
+ $(SLO)$/WeakListenerAdapter.obj \
+ $(SLO)$/ResId.obj \
+ $(SLO)$/RessourceManager.obj \
+ $(SLO)$/RangeHighlighter.obj \
+ $(SLO)$/ReferenceSizeProvider.obj \
+ $(SLO)$/ExplicitCategoriesProvider.obj \
+ $(SLO)$/RegressionCurveCalculator.obj \
+ $(SLO)$/RegressionEquation.obj
+
+DISABLED_SLOFILES= \
+ $(SLO)$/NamedFillProperties.obj \
+ $(SLO)$/NamedLineProperties.obj \
+ $(SLO)$/NamedProperties.obj
+
+#--------
+
+#Indicates the filename of the shared library.
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+
+#indicates dependencies:
+SHL1DEPN=
+#Specifies an import library to create. For Win32 only.
+SHL1IMPLIB= i$(TARGET)
+
+#Specifies libraries from the same module to put into the shared library.
+#was created above
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+
+#Links import libraries.
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(SVLLIB) \
+ $(VCLLIB) \
+ $(I18NISOLANGLIB) \
+ $(BASEGFXLIB) \
+ $(UNOTOOLSLIB)
+
+# $(SVLIB) \
+# $(SVTOOLLIB) \
+# $(SVXLIB) \
+# $(TKLIB) \
+# $(SFXLIB)
+
+#--------exports
+
+#specifies the exported symbols for Windows only:
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+#Specifies the library name to parse for symbols. For Win32 only.
+DEFLIB1NAME= $(TARGET)
+
+#A file of symbols to export.
+#DEF1EXPORTFILE= $(PRJ)$/source$/inc$/exports.dxp
+
+#--------definition file
+
+#name of the definition file:
+DEF1NAME= $(SHL1TARGET)
+
+# indicates definition file dependencies
+DEF1DEPN= $(MISC)$/$(SHL1TARGET).flt
+
+#A comment on the definition file.
+DEF1DES= Chart Tools
+
+# --- Targets -----------------------------------------------------------------
+
+.INCLUDE: target.mk
+
+# --- Filter -----------------------------------------------------------
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk \
+ exports.flt
+ $(TYPE) exports.flt > $@
+