/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "vbachart.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/chart/XAxisXSupplier.hpp>
#include <com/sun/star/chart/XAxisYSupplier.hpp>
#include <com/sun/star/chart/XAxisZSupplier.hpp>
#include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
#include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
#include <com/sun/star/chart/XChartDataArray.hpp>
#include <com/sun/star/chart/ChartSymbolType.hpp>
#include <com/sun/star/chart/ChartSolidType.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <ooo/vba/excel/XlChartType.hpp>
#include <ooo/vba/excel/XlRowCol.hpp>
#include <ooo/vba/excel/XlAxisType.hpp>
#include <ooo/vba/excel/XlAxisGroup.hpp>
#include <basic/sberrors.hxx>
#include "vbachartobject.hxx"
#include "vbarange.hxx"
#include "vbacharttitle.hxx"
#include "vbaaxes.hxx"
#include <document.hxx>
#include <utility>
using namespace ::com::sun::star;
using namespace ::ooo::vba;
using namespace ::ooo::vba::excel::XlChartType;
using namespace ::ooo::vba::excel::XlRowCol;
using namespace ::ooo::vba::excel::XlAxisType;
using namespace ::ooo::vba::excel::XlAxisGroup;
constexpr OUStringLiteral CHART_NAME(u"Name");
// #TODO move this constant to vbaseries.[ch]xx ( when it exists )
constexpr OUStringLiteral DEFAULTSERIESPREFIX(u"Series");
constexpr OUString DATAROWSOURCE(u"DataRowSource"_ustr);
constexpr OUString UPDOWN(u"UpDown"_ustr);
constexpr OUString VOLUME(u"Volume"_ustr);
constexpr OUString LINES(u"Lines"_ustr);
constexpr OUString SPLINETYPE(u"SplineType"_ustr);
constexpr OUString SYMBOLTYPE(u"SymbolType"_ustr);
constexpr OUString DEEP(u"Deep"_ustr);
constexpr OUString SOLIDTYPE(u"SolidType"_ustr);
constexpr OUString VERTICAL(u"Vertical"_ustr);
constexpr OUString PERCENT(u"Percent"_ustr);
constexpr OUString STACKED(u"Stacked"_ustr);
constexpr OUString DIM3D(u"Dim3D"_ustr);
constexpr OUString HASMAINTITLE(u"HasMainTitle"_ustr);
constexpr OUString HASLEGEND(u"HasLegend"_ustr);
ScVbaChart::ScVbaChart( const css::uno::Reference< ov::XHelperInterface >& _xParent, const css::uno::Reference< css::uno::XComponentContext >& _xContext, const css::uno::Reference< css::lang::XComponent >& _xChartComponent, css::uno::Reference< css::table::XTableChart > _xTableChart ) : ChartImpl_BASE( _xParent, _xContext ), mxTableChart(std::move( _xTableChart ))
{
mxChartDocument.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
// #TODO is it possible that the XPropertySet interface is not set
// code in setPlotBy seems to indicate that this is possible? but
// additionally there is no check in most of the places where it is used
// ( and therefore could possibly be NULL )
// I'm going to let it throw for the moment ( npower )
mxDiagramPropertySet.set( mxChartDocument->getDiagram(), uno::UNO_QUERY_THROW );
mxChartPropertySet.set( _xChartComponent, uno::UNO_QUERY_THROW ) ;
}
OUString SAL_CALL
ScVbaChart::getName()
{
OUString sName;
uno::Reference< beans::XPropertySet > xProps( mxChartDocument, uno::UNO_QUERY_THROW );
try
{
xProps->getPropertyValue( CHART_NAME ) >>= sName;
}
catch( const uno::Exception & ) // swallow exceptions
{
}
return sName;
}
uno::Any SAL_CALL
ScVbaChart::SeriesCollection(const uno::Any&)
{
return uno::Any();
}
::sal_Int32 SAL_CALL
ScVbaChart::getChartType()
{
sal_Int32 nChartType = -1;
try
{
OUString sDiagramType = mxChartDocument->getDiagram()->getDiagramType();
if ( sDiagramType == "com.sun.star.chart.AreaDiagram" )
{
if (is3D())
{
nChartType = getStackedType(xl3DAreaStacked, xl3DAreaStacked100, xl3DArea);
}
else
{
nChartType = getStackedType(xlAreaStacked, xlAreaStacked100, xlArea);
}
}
else if ( sDiagramType == "com.sun.star.chart.PieDiagram" )
{
if (is3D())
nChartType = xl3DPie;
else
nChartType = xlPie; /*TODO XlChartType xlPieExploded, XlChartType xlPieOfPie */
}
else if ( sDiagramType == "com.sun.star.chart.BarDiagram" )
{
sal_Int32 nSolidType = chart::ChartSolidType::RECTANGULAR_SOLID;
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
{ //in 2D diagrams 'SolidType' may not be set
if (is3D())
mxDiagramPropertySet->getPropertyValue(SOLIDTYPE) >>= nSolidType;
}
switch (nSolidType)
{
case chart::ChartSolidType::CONE:
nChartType = getSolidType(xlConeCol, xlConeColStacked, xlConeColStacked100, xlConeColClustered, xlConeBarStacked, xlConeBarStacked100, xlConeBarClustered);
break;
case chart::ChartSolidType::CYLINDER:
nChartType = getSolidType(xlCylinderCol, xlCylinderColStacked, xlCylinderColStacked100, xlCylinderColClustered, xlCylinderBarStacked, xlCylinderBarStacked100, xlCylinderBarClustered);
break;
case chart::ChartSolidType::PYRAMID:
nChartType = getSolidType(xlPyramidCol, xlPyramidColStacked, xlPyramidColStacked100, xlPyramidColClustered, xlPyramidBarStacked, xlPyramidBarStacked100, xlPyramidBarClustered);
break;
default: // RECTANGULAR_SOLID
if (is3D())
{
nChartType = getSolidType(xl3DColumn, xl3DColumnStacked, xl3DColumnStacked100, xl3DColumnClustered, xl3DBarStacked, xl3DBarStacked100, xl3DBarClustered);
}
else
{
nChartType = getSolidType(xlColumnClustered, xlColumnStacked, xlColumnStacked100, xlColumnClustered, xlBarStacked, xlBarStacked100, xlBarClustered);
}
break;
}
}
else if ( sDiagramType == "com.sun.star.chart.StockDiagram" )
{
bool bVolume = false;
mxDiagramPropertySet->getPropertyValue(VOLUME) >>= bVolume;
if (bVolume)
{
nChartType = getStockUpDownValue(xlStockVOHLC, xlStockVHLC);
}
else
{
nChartType = getStockUpDownValue(xlStockOHLC, xlStockHLC);
}
}
else if ( sDiagramType == "com.sun.star.chart.XYDiagram" )
{
bool bHasLines = false;
mxDiagramPropertySet->getPropertyValue(LINES) >>= bHasLines;
sal_Int32 nSplineType = 0;
mxDiagramPropertySet->getPropertyValue(SPLINETYPE) >>= nSplineType;
if (nSplineType == 1)
{
nChartType = getMarkerType(xlXYScatterSmooth, xlXYScatterSmoothNoMarkers);
}
else if (bHasLines)
{
nChartType = getMarkerType(xlXYScatterLines, xlXYScatterLinesNoMarkers);
}
else
{
nChartType = xlXYScatter;
}
}
else if ( sDiagramType == "com.sun.star.chart.LineDiagram" )
{
if (is3D())
{
nChartType = xl3DLine;
}
else if (hasMarkers())
{
nChartType = getStackedType(xlLineMarkersStacked, xlLineMarkersStacked100, xlLineMarkers);
}
else
{
nChartType = getStackedType(xlLineStacked, xlLineStacked100, xlLine);
}
}
else if ( sDiagramType == "com.sun.star.chart.DonutDiagram" )
{
nChartType = xlDoughnut; // TODO DoughnutExploded ??
}
else if ( sDiagramType == "com.sun.star.chart.NetDiagram" )
{
nChartType = getMarkerType(xlRadarMarkers, xlRadar);
}
}
catch ( const uno::Exception& )
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
return nChartType;
}
void SAL_CALL
ScVbaChart::setChartType( ::sal_Int32 _nChartType )
{
try
{
switch (_nChartType)
{
case xlColumnClustered:
case xlColumnStacked:
case xlColumnStacked100:
case xl3DColumnClustered:
case xl3DColumnStacked:
case xl3DColumnStacked100:
case xl3DColumn:
case xlBarClustered:
case xlBarStacked:
case xlBarStacked100:
case xl3DBarClustered:
case xl3DBarStacked:
case xl3DBarStacked100:
case xlConeColClustered:
case xlConeColStacked:
case xlConeColStacked100:
case xlConeBarClustered:
case xlConeBarStacked:
case xlConeBarStacked100:
case xlConeCol:
case xlPyramidColClustered:
case xlPyramidColStacked:
case xlPyramidColStacked100:
case xlPyramidBarClustered:
case xlPyramidBarStacked:
case xlPyramidBarStacked100:
case xlPyramidCol:
case xlCylinderColClustered:
case xlCylinderColStacked:
case xlCylinderColStacked100:
case xlCylinderBarClustered:
case xlCylinderBarStacked:
case xlCylinderBarStacked100:
case xlCylinderCol:
case xlSurface: // not possible
case xlSurfaceWireframe:
case xlSurfaceTopView:
case xlSurfaceTopViewWireframe:
setDiagram( u"com.sun.star.chart.BarDiagram"_ustr);
break;
case xlLine:
case xl3DLine:
case xlLineStacked:
case xlLineStacked100:
case xlLineMarkers:
case xlLineMarkersStacked:
case xlLineMarkersStacked100:
setDiagram( u"com.sun.star.chart.LineDiagram"_ustr);
break;
case xl3DArea:
case xlArea:
case xlAreaStacked:
case xlAreaStacked100:
case xl3DAreaStacked:
case xl3DAreaStacked100:
setDiagram( u"com.sun.star.chart.AreaDiagram"_ustr );
break;
case xlDoughnut:
case xlDoughnutExploded:
setDiagram( u"com.sun.star.chart.DonutDiagram"_ustr );
break;
case xlStockHLC:
case xlStockOHLC:
case xlStockVHLC:
case xlStockVOHLC:
setDiagram( u"com.sun.star.chart.StockDiagram"_ustr);
mxDiagramPropertySet->setPropertyValue( UPDOWN, uno::Any((_nChartType == xlStockOHLC) || (_nChartType == xlStockVOHLC)));
mxDiagramPropertySet->setPropertyValue( VOLUME, uno::Any((_nChartType == xlStockVHLC) || (_nChartType == xlStockVOHLC)));
break;
case xlPieOfPie: // not possible
case xlPieExploded: // SegmentOffset on ChartDataPointProperties -> get from XDiagram //How does Excel do this?
case xl3DPieExploded:
case xl3DPie:
case xlPie:
case xlBarOfPie: // not possible (Zoom pie)
setDiagram( u"com.sun.star.chart.PieDiagram"_ustr);
break;
case xlRadar:
case xlRadarMarkers:
case xlRadarFilled:
setDiagram( u"com.sun.star.chart.NetDiagram"_ustr);
break;
case xlXYScatter:
case xlBubble: // not possible
case xlBubble3DEffect: // not possible
case xlXYScatterLines:
case xlXYScatterLinesNoMarkers:
case xlXYScatterSmooth:
case xlXYScatterSmoothNoMarkers:
setDiagram( u"com.sun.star.chart.XYDiagram"_ustr);
switch(_nChartType)
{
case xlXYScatter:
case xlBubble: // not possible
case xlBubble3DEffect: // not possible
mxDiagramPropertySet->setPropertyValue(LINES, uno::Any( false ));
break;
case xlXYScatterLines:
case xlXYScatterLinesNoMarkers:
mxDiagramPropertySet->setPropertyValue(LINES, uno::Any( true ));
break;
case xlXYScatterSmooth:
case xlXYScatterSmoothNoMarkers:
mxDiagramPropertySet->setPropertyValue(SPLINETYPE, uno::Any( sal_Int32(1)));
break;
default:
break;
}
break;
default:
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_CONVERSION), OUString() );
}
switch (_nChartType)
{
case xlLineMarkers:
case xlLineMarkersStacked:
case xlLineMarkersStacked100:
case xlRadarMarkers:
case xlXYScatterLines:
case xlXYScatterSmooth:
case xlXYScatter:
case xlBubble: // not possible
case xlBubble3DEffect: // not possible
mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::Any( chart::ChartSymbolType::AUTO));
break;
default:
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SYMBOLTYPE))
{
mxDiagramPropertySet->setPropertyValue(SYMBOLTYPE, uno::Any(chart::ChartSymbolType::NONE));
}
break;
}
switch (_nChartType)
{
case xlConeCol:
case xlPyramidCol:
case xlCylinderCol:
case xl3DColumn:
case xlSurface: // not possible
case xlSurfaceWireframe:
case xlSurfaceTopView:
case xlSurfaceTopViewWireframe:
mxDiagramPropertySet->setPropertyValue(DEEP,uno::Any( true ));
break;
default:
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DEEP))
{
mxDiagramPropertySet->setPropertyValue(DEEP, uno::Any( false));
}
break;
}
switch (_nChartType)
{
case xlConeColClustered:
case xlConeColStacked:
case xlConeColStacked100:
case xlConeBarClustered:
case xlConeBarStacked:
case xlConeBarStacked100:
case xlConeCol:
mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::CONE));
break;
case xlPyramidColClustered:
case xlPyramidColStacked:
case xlPyramidColStacked100:
case xlPyramidBarClustered:
case xlPyramidBarStacked:
case xlPyramidBarStacked100:
case xlPyramidCol:
mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::PYRAMID));
break;
case xlCylinderColClustered:
case xlCylinderColStacked:
case xlCylinderColStacked100:
case xlCylinderBarClustered:
case xlCylinderBarStacked:
case xlCylinderBarStacked100:
case xlCylinderCol:
mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::CYLINDER));
break;
default:
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(SOLIDTYPE))
{
mxDiagramPropertySet->setPropertyValue(SOLIDTYPE, uno::Any(chart::ChartSolidType::RECTANGULAR_SOLID));
}
break;
}
switch ( _nChartType)
{
case xlConeCol:
case xlConeColClustered:
case xlConeColStacked:
case xlConeColStacked100:
case xlPyramidColClustered:
case xlPyramidColStacked:
case xlPyramidColStacked100:
case xlCylinderColClustered:
case xlCylinderColStacked:
case xlCylinderColStacked100:
case xlColumnClustered:
case xlColumnStacked:
case xlColumnStacked100:
case xl3DColumnClustered:
case xl3DColumnStacked:
case xl3DColumnStacked100:
case xlSurface: // not possible
case xlSurfaceWireframe:
case xlSurfaceTopView:
case xlSurfaceTopViewWireframe:
mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::Any( true));
break;
default:
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(VERTICAL))
{
mxDiagramPropertySet->setPropertyValue(VERTICAL, uno::Any(false));
}
break;
}
switch (_nChartType)
{
case xlColumnStacked:
case xl3DColumnStacked:
case xlBarStacked:
case xl3DBarStacked:
case xlLineStacked:
case xlLineMarkersStacked:
case xlAreaStacked:
case xl3DAreaStacked:
case xlCylinderColStacked:
case xlCylinderBarStacked:
case xlConeColStacked:
case xlConeBarStacked:
case xlPyramidColStacked:
case xlPyramidBarStacked:
mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( false ));
mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( true ));
break;
case xlPyramidColStacked100:
case xlPyramidBarStacked100:
case xlConeColStacked100:
case xlConeBarStacked100:
case xlCylinderBarStacked100:
case xlCylinderColStacked100:
case xl3DAreaStacked100:
case xlLineMarkersStacked100:
case xlAreaStacked100:
case xlLineStacked100:
case xl3DBarStacked100:
case xlBarStacked100:
case xl3DColumnStacked100:
case xlColumnStacked100:
mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( true));
mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( true ));
break;
default:
mxDiagramPropertySet->setPropertyValue(PERCENT, uno::Any( false));
mxDiagramPropertySet->setPropertyValue(STACKED, uno::Any( false));
break;
}
switch (_nChartType)
{
case xl3DArea:
case xl3DAreaStacked:
case xl3DAreaStacked100:
case xl3DBarClustered:
case xl3DBarStacked:
case xl3DBarStacked100:
case xl3DColumn:
case xl3DColumnClustered:
case xl3DColumnStacked:
case xl3DColumnStacked100:
case xl3DLine:
case xl3DPie:
case xl3DPieExploded:
case xlConeColClustered:
case xlConeColStacked:
case xlConeColStacked100:
case xlConeBarClustered:
case xlConeBarStacked:
case xlConeBarStacked100:
case xlConeCol:
case xlPyramidColClustered:
case xlPyramidColStacked:
case xlPyramidColStacked100:
case xlPyramidBarClustered:
case xlPyramidBarStacked:
case xlPyramidBarStacked100:
case xlPyramidCol:
case xlCylinderColClustered:
case xlCylinderColStacked:
case xlCylinderColStacked100:
case xlCylinderBarClustered:
case xlCylinderBarStacked:
case xlCylinderBarStacked100:
case xlCylinderCol:
mxDiagramPropertySet->setPropertyValue(DIM3D, uno::Any( true));
break;
default:
if (mxDiagramPropertySet->getPropertySetInfo()->hasPropertyByName(DIM3D))
{
mxDiagramPropertySet->setPropertyValue(DIM3D, uno::Any( false));
}
break;
}
}
catch ( const uno::Exception& )
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
void SAL_CALL
ScVbaChart::Activate()
{
// #TODO how are Chart sheets handled ( I know we don't even consider
// them in the worksheets/sheets collections ), but...???
// note: in vba for excel the parent of a Chart sheet is a workbook,
// e.g. 'ThisWorkbook'
uno::Reference< XHelperInterface > xParent( getParent() );
ScVbaChartObject* pChartObj = static_cast< ScVbaChartObject* >( xParent.get() );
if ( !pChartObj )
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), u"no ChartObject as parent"_ustr );
pChartObj->Activate();
}
void SAL_CALL
ScVbaChart::setSourceData( const css::uno::Reference< ::ooo::vba::excel::XRange >& _xCalcRange, const css::uno::Any& _aPlotBy )
{
try
{
table::CellRangeAddress aSingleRangeAddress;
uno::Reference< sheet::XCellRangeAddressable > xAddressable( _xCalcRange->getCellRange(), uno::UNO_QUERY_THROW );
aSingleRangeAddress = xAddressable->getRangeAddress();
mxTableChart->setRanges({ aSingleRangeAddress } );
bool bsetRowHeaders = false;
bool bsetColumnHeaders = false;
ScVbaRange* pRange = static_cast< ScVbaRange* >( _xCalcRange.get() );
if ( pRange )
{
ScDocument& rDoc = pRange->getScDocument();
bsetRowHeaders = rDoc.HasRowHeader( static_cast< SCCOL >( aSingleRangeAddress.StartColumn ), static_cast< SCROW >( aSingleRangeAddress.StartRow ), static_cast< SCCOL >( aSingleRangeAddress.EndColumn ), static_cast< SCROW >( aSingleRangeAddress.EndRow ), static_cast< SCTAB >( aSingleRangeAddress.Sheet ) );
bsetColumnHeaders = rDoc.HasColHeader( static_cast< SCCOL >( aSingleRangeAddress.StartColumn ), static_cast< SCROW >( aSingleRangeAddress.StartRow ), static_cast< SCCOL >( aSingleRangeAddress.EndColumn ), static_cast< SCROW >( aSingleRangeAddress.EndRow ), static_cast< SCTAB >( aSingleRangeAddress.Sheet ));
}
mxTableChart->setHasRowHeaders(bsetRowHeaders);
mxTableChart->setHasColumnHeaders(bsetColumnHeaders);
if ((!bsetColumnHeaders) || (!bsetRowHeaders))
{
uno::Reference< chart::XChartDataArray > xChartDataArray( mxChartDocument->getData(), uno::UNO_QUERY_THROW );
if (!bsetColumnHeaders)
{
xChartDataArray->setColumnDescriptions( getDefaultSeriesDescriptions(xChartDataArray->getColumnDescriptions().getLength() ));
}
if (!bsetRowHeaders)
{
xChartDataArray->setRowDescriptions(getDefaultSeriesDescriptions(xChartDataArray->getRowDescriptions().getLength() ));
}
}
if ( _aPlotBy.hasValue() )
{
sal_Int32 nVal = 0;
_aPlotBy >>= nVal;
setPlotBy( nVal );
}
else
{
sal_Int32 nRows = aSingleRangeAddress.EndRow - aSingleRangeAddress.StartRow;
sal_Int32 nCols = aSingleRangeAddress.EndColumn - aSingleRangeAddress.StartColumn;
// AutoDetect emulation
if ( nRows > nCols )
setPlotBy( xlColumns );
else if ( nRows <= nCols )
setPlotBy( xlRows );
}
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
uno::Sequence< OUString >
ScVbaChart::getDefaultSeriesDescriptions( sal_Int32 _nCount )
{
uno::Sequence< OUString > sDescriptions ( _nCount );
std::generate_n(sDescriptions.getArray(), _nCount,
[i = 1]() mutable -> OUString { return DEFAULTSERIESPREFIX + OUString::number(i++); });
return sDescriptions;
}
void
ScVbaChart::setDefaultChartType()
{
setChartType( xlColumnClustered );
}
void
ScVbaChart::setPlotBy( ::sal_Int32 _nPlotBy )
{
try
{
if ( !mxDiagramPropertySet.is() )
setDefaultChartType();
switch (_nPlotBy)
{
case xlRows:
mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::Any( chart::ChartDataRowSource_ROWS ) );
break;
case xlColumns:
mxDiagramPropertySet->setPropertyValue( DATAROWSOURCE, uno::Any( chart::ChartDataRowSource_COLUMNS) );
break;
default:
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
::sal_Int32 SAL_CALL
ScVbaChart::getPlotBy( )
{
try
{
chart::ChartDataRowSource aChartDataRowSource;
mxDiagramPropertySet->getPropertyValue(DATAROWSOURCE) >>= aChartDataRowSource;
if (aChartDataRowSource == chart::ChartDataRowSource_COLUMNS)
{
return xlColumns;
}
else
{
return xlRows;
}
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
void
ScVbaChart::setDiagram( const OUString& _sDiagramType )
{
try
{
uno::Reference< lang::XMultiServiceFactory > xMSF( mxChartDocument, uno::UNO_QUERY_THROW );
uno::Reference< chart::XDiagram > xDiagram( xMSF->createInstance( _sDiagramType ), uno::UNO_QUERY_THROW );
mxChartDocument->setDiagram( xDiagram );
mxDiagramPropertySet.set( xDiagram, uno::UNO_QUERY_THROW );
}
catch ( const uno::Exception& )
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
// #TODO find out why we have Location/getLocation? there is afaik no
// Location property, just a Location function for the Chart object
sal_Int32 SAL_CALL
ScVbaChart::Location()
{
return getLocation();
}
sal_Int32 SAL_CALL
ScVbaChart::getLocation()
{
return -1;
}
void SAL_CALL
ScVbaChart::setLocation( ::sal_Int32 /*where*/, const css::uno::Any& /*Name*/ )
{
// Helper api just stubs out the code <shrug>
// #TODO come back and make sense out of this
// String sheetName = null;
//
// if ((name != null) && name instanceof String) {
// sheetName = (String) name;
// }
// XSpreadsheetDocument xShDoc = (XSpreadsheetDocument) UnoRuntime.queryInterface( XSpreadsheetDocument.class,getXModel() );
// com.sun.star.sheet.XSpreadsheets xSheets = xShDoc.Sheets();
//
// switch (where) {
// case ClLocationType.clLocationAsObject_value: //{
//
// if (sheetName == null) {
// DebugHelper.writeInfo("Can't embed in Chart without knowing SheetName");
// return;
// }
//
// try {
// Any any = (Any) xSheets.getByName(sheetName);
// chartSheet = (XSpreadsheet) any.getObject();
//
// // chartSheet = (XSpreadsheet) xSheets.getByName( sheetName );
// } catch (NoSuchElementException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
//
// return;
// } catch (WrappedTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
//
// return;
// } catch (java.lang.Exception e) {
// e.printStackTrace();
// }
//
// XTableChartsSupplier xTCS = (XTableChartsSupplier) UnoRuntime.queryInterface( XTableChartsSupplier.class, chartSheet);
// XTableCharts xTableCharts = xTCS.getCharts();
// XIndexAccess xIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xTableCharts);
// int numCharts = xIA.getCount();
// chartName = "Chart " + (numCharts + 1);
//
// //}
// break;
//
// case ClLocationType.clLocationAsNewSheet_value:
// case ClLocationType.clLocationAutomatic_value:default: //{
// chartName = "Chart 1"; // Since it's a new sheet, it's the first on it...
//
// XIndexAccess xSheetIA = (XIndexAccess) UnoRuntime.queryInterface( XIndexAccess.class, xSheets);
//
// short newSheetNum = (short) (xSheetIA.getCount() + 1);
//
// if (sheetName == null){
// sheetName = "ChartSheet " + newSheetNum; // Why not?
// }
// // DPK TODO : Probably should use Sheets to create this!
// xSheets.insertNewByName(sheetName, newSheetNum);
//
// try {
// chartSheet =
// (XSpreadsheet) xSheets.getByName(sheetName);
// } catch (NoSuchElementException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
//
// return;
// } catch (WrappedTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
//
// return;
// }
//
// //}
// break;
// }
//
// // Last thing should be a call to createChartForReal(), one of them
// // should succeed.
// createChartForReal();
}
sal_Bool SAL_CALL
ScVbaChart::getHasTitle( )
{
bool bHasTitle = false;
try
{
mxChartPropertySet->getPropertyValue(HASMAINTITLE) >>= bHasTitle;
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
return bHasTitle;
}
void SAL_CALL
ScVbaChart::setHasTitle( sal_Bool bTitle )
{
try
{
mxChartPropertySet->setPropertyValue(HASMAINTITLE, uno::Any( bTitle ));
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
sal_Bool SAL_CALL
ScVbaChart::getHasLegend( )
{
bool bHasLegend = false;
try
{
mxChartPropertySet->getPropertyValue(HASLEGEND) >>= bHasLegend;
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
return bHasLegend;
}
void SAL_CALL
ScVbaChart::setHasLegend( sal_Bool bLegend )
{
try
{
mxChartPropertySet->setPropertyValue(HASLEGEND, uno::Any(bLegend));
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
uno::Reference< excel::XChartTitle > SAL_CALL
ScVbaChart::getChartTitle( )
{
uno::Reference< drawing::XShape > xTitleShape = mxChartDocument->getTitle();
// #TODO check parent
return new ScVbaChartTitle(this, mxContext, xTitleShape);
}
uno::Any SAL_CALL
ScVbaChart::Axes( const uno::Any& Type, const uno::Any& AxisGroup )
{
// mmm chart probably is the parent, #TODO check parent
uno::Reference< excel::XAxes > xAxes = new ScVbaAxes( this, mxContext, this );
if ( !Type.hasValue() )
return uno::Any( xAxes );
return xAxes->Item( Type, AxisGroup );
}
bool
ScVbaChart::is3D()
{
// #TODO perhaps provide limited Debughelper functionality
bool is3d = false;
mxDiagramPropertySet->getPropertyValue(DIM3D) >>= is3d;
return is3d;
}
sal_Int32
ScVbaChart::getStackedType( sal_Int32 _nStacked, sal_Int32 _n100PercentStacked, sal_Int32 _nUnStacked )
{
// #TODO perhaps provide limited Debughelper functionality
if (isStacked())
{
if (is100PercentStacked())
return _n100PercentStacked;
else
return _nStacked;
}
else
return _nUnStacked;
}
bool
ScVbaChart::isStacked()
{
// #TODO perhaps provide limited Debughelper functionality
bool bStacked = false;
mxDiagramPropertySet->getPropertyValue(STACKED) >>= bStacked;
return bStacked;
}
bool
ScVbaChart::is100PercentStacked()
{
// #TODO perhaps provide limited Debughelper functionality
bool b100Percent = false;
mxDiagramPropertySet->getPropertyValue(PERCENT) >>= b100Percent;
return b100Percent;
}
sal_Int32
ScVbaChart::getSolidType(sal_Int32 _nDeep, sal_Int32 _nVertiStacked, sal_Int32 _nVerti100PercentStacked, sal_Int32 _nVertiUnStacked, sal_Int32 _nHoriStacked, sal_Int32 _nHori100PercentStacked, sal_Int32 _nHoriUnStacked)
{
try
{
bool bIsVertical = true;
mxDiagramPropertySet->getPropertyValue(VERTICAL) >>= bIsVertical;
bool bIsDeep = false;
mxDiagramPropertySet->getPropertyValue(DEEP) >>= bIsDeep;
if (bIsDeep)
{
return _nDeep;
}
else
{
if (bIsVertical)
{
return getStackedType(_nVertiStacked, _nVerti100PercentStacked, _nVertiUnStacked);
}
else
{
return getStackedType(_nHoriStacked, _nHori100PercentStacked, _nHoriUnStacked);
}
}
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
sal_Int32
ScVbaChart::getStockUpDownValue(sal_Int32 _nUpDown, sal_Int32 _nNotUpDown)
{
try
{
bool bUpDown = false;
mxDiagramPropertySet->getPropertyValue(UPDOWN) >>= bUpDown;
if (bUpDown)
{
return _nUpDown;
}
else
{
return _nNotUpDown;
}
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
}
bool
ScVbaChart::hasMarkers()
{
bool bHasMarkers = false;
try
{
sal_Int32 nSymbol=0;
mxDiagramPropertySet->getPropertyValue(SYMBOLTYPE) >>= nSymbol;
bHasMarkers = nSymbol != chart::ChartSymbolType::NONE;
}
catch (const uno::Exception&)
{
throw script::BasicErrorException( OUString(), uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_BASIC_METHOD_FAILED), OUString() );
}
return bHasMarkers;
}
sal_Int32
ScVbaChart::getMarkerType(sal_Int32 _nWithMarkers, sal_Int32 _nWithoutMarkers)
{
if (hasMarkers())
return _nWithMarkers;
return _nWithoutMarkers;
}
void
ScVbaChart::assignDiagramAttributes()
{
xAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
xAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
xAxisZSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
xTwoAxisXSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
xTwoAxisYSupplier.set( mxDiagramPropertySet, uno::UNO_QUERY_THROW );
}
uno::Reference< beans::XPropertySet >
ScVbaChart::getAxisPropertySet(sal_Int32 _nAxisType, sal_Int32 _nAxisGroup)
{
assignDiagramAttributes();
uno::Reference< beans::XPropertySet > xAxisProps;
switch(_nAxisType)
{
case xlCategory:
if (_nAxisGroup == xlPrimary)
{
xAxisProps = xAxisXSupplier->getXAxis();
}
else if (_nAxisGroup == xlSecondary)
{
xAxisProps = xTwoAxisXSupplier->getSecondaryXAxis();
}
break;
case xlSeriesAxis:
xAxisProps = xAxisZSupplier->getZAxis();
break;
case xlValue:
if (_nAxisGroup == xlPrimary)
xAxisProps = xAxisYSupplier->getYAxis();
else if (_nAxisGroup == xlSecondary)
xAxisProps = xTwoAxisYSupplier->getSecondaryYAxis();
break;
default:
return xAxisProps;
}
return xAxisProps;
}
OUString
ScVbaChart::getServiceImplName()
{
return u"ScVbaChart"_ustr;
}
uno::Sequence< OUString >
ScVbaChart::getServiceNames()
{
static uno::Sequence< OUString > const aServiceNames
{
u"ooo.vba.excel.Chart"_ustr
};
return aServiceNames;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V547 Expression 'nSplineType == 1' is always false.
↑ V547 Expression 'nSymbol != chart::ChartSymbolType::NONE' is always true.
↑ V614 Uninitialized variable 'aChartDataRowSource' used.
↑ V547 Expression 'bVolume' is always false.
↑ V547 Expression 'bHasLines' is always false.
↑ V547 Expression 'bIsDeep' is always false.
↑ V547 Expression 'bIsVertical' is always true.
↑ V547 Expression 'bUpDown' is always false.
↑ V785 Constant expression in switch statement.