diff options
Diffstat (limited to 'chart2/source/tools/ObjectIdentifier.cxx')
-rw-r--r-- | chart2/source/tools/ObjectIdentifier.cxx | 1502 |
1 files changed, 1502 insertions, 0 deletions
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx new file mode 100644 index 000000000..be592b952 --- /dev/null +++ b/chart2/source/tools/ObjectIdentifier.cxx @@ -0,0 +1,1502 @@ +/* -*- 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 <sal/config.h> + +#include <map> + +#include <ObjectIdentifier.hxx> +#include <TitleHelper.hxx> +#include <ChartModel.hxx> +#include <ChartModelHelper.hxx> +#include <AxisHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DiagramHelper.hxx> +#include <unonames.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> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/drawing/XShape.hpp> + +#include <rtl/ustrbuf.hxx> +#include <tools/diagnose_ex.h> + +namespace com::sun::star::drawing { class XShape; } + +namespace chart +{ +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Any; + +static const char m_aMultiClick[] = "MultiClick"; +static const char m_aDragMethodEquals[] = "DragMethod="; +static const char m_aDragParameterEquals[] = "DragParameter="; +static const char m_aProtocol[] = "CID/"; +static const OUString m_aPieSegmentDragMethodServiceName("PieSegmentDragging"); + +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; + break; + default: + break;//empty string + } + if( !rDragMethodServiceName.isEmpty() ) + { + if( !aRet.isEmpty() ) + aRet.append(":"); + aRet.append( m_aDragMethodEquals ); + aRet.append( rDragMethodServiceName ); + + if( !rDragParameterString.isEmpty() ) + { + if( !aRet.isEmpty() ) + aRet.append(":"); + aRet.append( m_aDragParameterEquals ); + aRet.append( rDragParameterString ); + } + } + return aRet.makeStringAndClear(); +} + +typedef std::map< TitleHelper::eTitleType, OUString > tTitleMap; +const tTitleMap& lcl_getTitleMap() +{ + //maps the title type to the ParentParticle for that title + static tTitleMap s_aTitleMap{ + {TitleHelper::MAIN_TITLE, ""}, + {TitleHelper::SUB_TITLE, "D=0"}, + {TitleHelper::X_AXIS_TITLE, "D=0:CS=0:Axis=0,0"}, + {TitleHelper::Y_AXIS_TITLE, "D=0:CS=0:Axis=1,0"}, + {TitleHelper::Z_AXIS_TITLE, "D=0:CS=0:Axis=2,0"}, + {TitleHelper::SECONDARY_X_AXIS_TITLE, "D=0:CS=0:Axis=0,1"}, + {TitleHelper::SECONDARY_Y_AXIS_TITLE, "D=0:CS=0:Axis=1,1"}}; + return s_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 nullptr; + + //iterate through all coordinate systems + Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY ); + if( !xCooSysContainer.is()) + return nullptr; + + const uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); + for( Reference< XCoordinateSystem > const & coords : aCooSysList ) + { + //iterate through all chart types in the current coordinate system + Reference< XChartTypeContainer > xChartTypeContainer( coords, uno::UNO_QUERY ); + if( !xChartTypeContainer.is() ) + continue; + + const uno::Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() ); + for( Reference< XChartType > const & xChartType : aChartTypeList ) + { + if(!xChartType.is()) + continue; + OUString aChartType = xChartType->getChartType(); + if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) ) + return xChartType; + } + } + return nullptr; +} + +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.isEmpty() ) + { + 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, "D=" ) ); + rnCooSys = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "CS=" ) ); +} + +void lcl_parseAxisIndices( sal_Int32& rnDimensionIndex, sal_Int32& rnAxisIndex, const OUString& rString ) +{ + OUString aAxisIndexString = lcl_getIndexStringAfterString( rString, ":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, ":SubGrid=" ) ); +} + +void lcl_parseSeriesIndices( sal_Int32& rnChartTypeIndex, sal_Int32& rnSeriesIndex, sal_Int32& rnPointIndex, const OUString& rString ) +{ + rnChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "CT=" ) ); + rnSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "Series=" ) ); + rnPointIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "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() ) +{ +} + +ObjectIdentifier::ObjectIdentifier( const OUString& rObjectCID ) + :m_aObjectCID( rObjectCID ) +{ +} + +ObjectIdentifier::ObjectIdentifier( const Reference< drawing::XShape >& rxShape ) + :m_aObjectCID( OUString() ) + ,m_xAdditionalShape( rxShape ) +{ +} + +ObjectIdentifier::ObjectIdentifier( const Any& rAny ) + :m_aObjectCID( OUString() ) +{ + const uno::Type& rType = rAny.getValueType(); + if ( rType == cppu::UnoType<OUString>::get() ) + { + rAny >>= m_aObjectCID; + } + else if ( rType == cppu::UnoType< drawing::XShape >::get() ) + { + rAny >>= m_xAdditionalShape; + } +} + +bool ObjectIdentifier::operator==( const ObjectIdentifier& rOID ) const +{ + return areIdenticalObjects( m_aObjectCID, rOID.m_aObjectCID ) && + ( m_xAdditionalShape == rOID.m_xAdditionalShape ); +} + +bool ObjectIdentifier::operator!=( const ObjectIdentifier& rOID ) const +{ + return !operator==( rOID ); +} + +bool ObjectIdentifier::operator<( const ObjectIdentifier& rOID ) const +{ + bool bReturn = false; + if ( !(m_aObjectCID.isEmpty() || rOID.m_aObjectCID.isEmpty()) ) + { + bReturn = ( m_aObjectCID.compareTo( rOID.m_aObjectCID ) < 0 ); + } + else if ( !m_aObjectCID.isEmpty() ) + { + bReturn = true; + } + else if ( !rOID.m_aObjectCID.isEmpty() ) + { + bReturn = false; + } + else if ( m_xAdditionalShape.is() && rOID.m_xAdditionalShape.is() ) + { + bReturn = ( m_xAdditionalShape < rOID.m_xAdditionalShape ); + } + return bReturn; +} + +OUString ObjectIdentifier::createClassifiedIdentifierForObject( + const Reference< uno::XInterface >& xObject + , ChartModel& rModel) +{ + 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, rModel ) ) + { + 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, rModel.getFirstDiagram() ) ); + OUString aCooSysParticle( createParticleForCoordinateSystem( xCooSys, rModel ) ); + sal_Int32 nDimensionIndex=-1; + sal_Int32 nAxisIndex=-1; + AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ); + OUString aAxisParticle( createParticleForAxis( nDimensionIndex, nAxisIndex ) ); + return createClassifiedIdentifierForParticles( aCooSysParticle, aAxisParticle ); + } + + //legend + Reference< XLegend > xLegend( xObject, uno::UNO_QUERY ); + if( xLegend.is() ) + { + return createClassifiedIdentifierForParticle( createParticleForLegend( rModel ) ); + } + + //diagram + Reference< XDiagram > xDiagram( xObject, uno::UNO_QUERY ); + if( xDiagram.is() ) + { + return createClassifiedIdentifierForParticle( createParticleForDiagram() ); + } + + //todo + //XDataSeries + //CooSys + //charttype + //datapoint? + //Gridproperties + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + if( eObjectType != OBJECTTYPE_UNKNOWN ) + { + aRet = ObjectIdentifier::createClassifiedIdentifierWithParent( + eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString ); + } + else + { + OSL_FAIL("give object could not be identified in createClassifiedIdentifierForObject"); + } + + return aRet; +} + +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 ) ) ); + OUString aCooSysParticle( createParticleForCoordinateSystem( xCooSys, xChartModel ) ); + sal_Int32 nDimensionIndex=-1; + sal_Int32 nAxisIndex=-1; + AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ); + OUString aAxisParticle( createParticleForAxis( nDimensionIndex, nAxisIndex ) ); + return createClassifiedIdentifierForParticles( aCooSysParticle, aAxisParticle ); + } + + //legend + Reference< XLegend > xLegend( xObject, uno::UNO_QUERY ); + if( xLegend.is() ) + { + return createClassifiedIdentifierForParticle( createParticleForLegend( xChartModel ) ); + } + + //diagram + Reference< XDiagram > xDiagram( xObject, uno::UNO_QUERY ); + if( xDiagram.is() ) + { + return createClassifiedIdentifierForParticle( createParticleForDiagram() ); + } + + //todo + //XDataSeries + //CooSys + //charttype + //datapoint? + //Gridproperties + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + if( eObjectType != OBJECTTYPE_UNKNOWN ) + { + aRet = ObjectIdentifier::createClassifiedIdentifierWithParent( + eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString ); + } + else + { + OSL_FAIL("give object could not be identified in createClassifiedIdentifierForObject"); + } + + return aRet; +} + +OUString ObjectIdentifier::createClassifiedIdentifierForParticle( + const OUString& rParticle ) +{ + return ObjectIdentifier::createClassifiedIdentifierForParticles( rParticle, OUString() ); +} + +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() > static_cast<sal_Int32>(strlen(m_aProtocol))) + aRet.append("/"); + + if(!rParentParticle.isEmpty()) + { + aRet.append(rParentParticle); + if( !rChildParticle.isEmpty() ) + aRet.append(":"); + } + aRet.append(rChildParticle); + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createParticleForDiagram() +{ + //TODO: if more than one diagram is implemented, add the correct diagram index here + return "D=0"; +} + +OUString ObjectIdentifier::createParticleForCoordinateSystem( + const Reference< XCoordinateSystem >& xCooSys + , ChartModel& rModel ) +{ + OUStringBuffer aRet; + + Reference< XDiagram > xDiagram( rModel.getFirstDiagram() ); + 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(); + aRet.append(":CS="); + aRet.append( OUString::number( nCooSysIndex ) ); + break; + } + } + } + + return aRet.makeStringAndClear(); +} + +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(); + aRet.append(":CS="); + aRet.append( OUString::number( nCooSysIndex ) ); + break; + } + } + } + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createParticleForAxis( + sal_Int32 nDimensionIndex + , sal_Int32 nAxisIndex ) +{ + return "Axis=" + + OUString::number( nDimensionIndex ) + + "," + + OUString::number( nAxisIndex ); +} + +OUString ObjectIdentifier::createParticleForGrid( + sal_Int32 nDimensionIndex + , sal_Int32 nAxisIndex ) +{ + OUString aRet = "Axis=" + OUString::number( nDimensionIndex ) + + "," + OUString::number( nAxisIndex ) + ":Grid=0"; + + return aRet; +} + +OUString ObjectIdentifier::createClassifiedIdentifierForGrid( + const Reference< XAxis >& xAxis + , const Reference< frame::XModel >& xChartModel + , sal_Int32 nSubGridIndex ) +{ + //-1: main grid, 0: first subgrid etc + + OUString aAxisCID( createClassifiedIdentifierForObject( xAxis, xChartModel ) ); + OUString aGridCID( addChildParticle( aAxisCID + , createChildParticleWithIndex( OBJECTTYPE_GRID, 0 ) ) ); + if( nSubGridIndex >= 0 ) + { + aGridCID = addChildParticle( aGridCID + , createChildParticleWithIndex( OBJECTTYPE_SUBGRID, 0 ) ); + } + return aGridCID; +} + +OUString ObjectIdentifier::createParticleForSeries( + sal_Int32 nDiagramIndex, sal_Int32 nCooSysIndex + , sal_Int32 nChartTypeIndex, sal_Int32 nSeriesIndex ) +{ + OUStringBuffer aRet; + + aRet.append("D="); + aRet.append( OUString::number( nDiagramIndex ) ); + aRet.append(":CS="); + aRet.append( OUString::number( nCooSysIndex ) ); + aRet.append(":CT="); + aRet.append( OUString::number( nChartTypeIndex ) ); + aRet.append(":"); + aRet.append(getStringForType( OBJECTTYPE_DATA_SERIES )); + aRet.append("="); + aRet.append( OUString::number( nSeriesIndex ) ); + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createParticleForLegend( ChartModel& ) +{ + OUStringBuffer aRet; + + //todo: if more than one diagram is implemented, find the correct diagram which is owner of the given legend + + aRet.append( ObjectIdentifier::createParticleForDiagram() ); + aRet.append(":"); + aRet.append(getStringForType( OBJECTTYPE_LEGEND )); + aRet.append("="); + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createParticleForLegend( + const Reference< frame::XModel >& ) +{ + OUStringBuffer aRet; + + //todo: if more than one diagram is implemented, find the correct diagram which is owner of the given legend + + aRet.append( ObjectIdentifier::createParticleForDiagram() ); + aRet.append(":"); + aRet.append(getStringForType( OBJECTTYPE_LEGEND )); + aRet.append("="); + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createClassifiedIdentifier( + enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_SERIES + , const OUString& rParticleID )//e.g. SeriesID +{ + return createClassifiedIdentifierWithParent( + eObjectType, rParticleID, OUString() ); +} + +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() > static_cast<sal_Int32>(strlen(m_aProtocol))) + aRet.append("/"); + aRet.append(rParentPartical); + if(!rParentPartical.isEmpty()) + aRet.append(":"); + + aRet.append(getStringForType( eObjectType )); + aRet.append("="); + aRet.append(rParticleID); + + return aRet.makeStringAndClear(); +} + +const OUString& ObjectIdentifier::getPieSegmentDragMethodServiceName() +{ + return m_aPieSegmentDragMethodServiceName; +} + +OUString ObjectIdentifier::createPieSegmentDragParameterString( + sal_Int32 nOffsetPercent + , const awt::Point& rMinimumPosition + , const awt::Point& rMaximumPosition ) +{ + OUString aRet = OUString::number( nOffsetPercent ) + + "," + OUString::number( rMinimumPosition.X ) + + "," + OUString::number( rMinimumPosition.Y ) + + "," + OUString::number( rMaximumPosition.X ) + + "," + OUString::number( rMaximumPosition.Y ); + return aRet; +} + +bool ObjectIdentifier::parsePieSegmentDragParameterString( + const OUString& rDragParameterString + , sal_Int32& rOffsetPercent + , awt::Point& rMinimumPosition + , awt::Point& rMaximumPosition ) +{ + 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(); + return nCharacterIndex >= 0; +} + +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; +} + +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; +} + +bool ObjectIdentifier::isDragableObject( const OUString& rClassifiedIdentifier ) +{ + bool bReturn = false; + ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier ); + switch( eObjectType ) + { + case OBJECTTYPE_TITLE: + case OBJECTTYPE_LEGEND: + case OBJECTTYPE_DIAGRAM: + case OBJECTTYPE_DATA_LABEL: + case OBJECTTYPE_DATA_CURVE_EQUATION: + //case OBJECTTYPE_DIAGRAM_WALL: + bReturn = true; + break; + default: + OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) ); + bReturn = !aDragMethodServiceName.isEmpty(); + break; + } + return bReturn; +} + +bool ObjectIdentifier::isDragableObject() const +{ + bool bReturn = false; + if ( isAutoGeneratedObject() ) + { + bReturn = isDragableObject( m_aObjectCID ); + } + else if ( isAdditionalShape() ) + { + bReturn = true; + } + return bReturn; +} + +bool ObjectIdentifier::isRotateableObject( const OUString& rClassifiedIdentifier ) +{ + bool bReturn = false; + ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier ); + switch( eObjectType ) + { + case OBJECTTYPE_DIAGRAM: + //case OBJECTTYPE_DIAGRAM_WALL: + bReturn = true; + break; + default: + bReturn = false; + break; + } + return bReturn; +} + +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 = rClassifiedIdentifier.match( m_aMultiClick, strlen(m_aProtocol) ); + 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.isEmpty() ) + { + OUString aParent2( ObjectIdentifier::getFullParentParticle( rCID2 ) ); + bRet=aParent1 == aParent2; + } + //legend entries are special: + if(!bRet) + { + if( getObjectType(rCID1) == OBJECTTYPE_LEGEND_ENTRY + && getObjectType(rCID2) == OBJECTTYPE_LEGEND_ENTRY ) + bRet = true; + } + } + return bRet; +} + +bool ObjectIdentifier::areIdenticalObjects( const OUString& rCID1, const OUString& rCID2 ) +{ + if( rCID1 == 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.isEmpty() && aID1 == aID2 ) + return true; + } + return false; +} + +OUString ObjectIdentifier::getStringForType( ObjectType eObjectType ) +{ + OUString aRet; + switch( eObjectType ) + { + case OBJECTTYPE_PAGE: + aRet="Page"; + break; + case OBJECTTYPE_TITLE: + aRet="Title"; + break; + case OBJECTTYPE_LEGEND: + aRet="Legend"; + break; + case OBJECTTYPE_LEGEND_ENTRY: + aRet="LegendEntry"; + break; + case OBJECTTYPE_DIAGRAM: + aRet="D"; + break; + case OBJECTTYPE_DIAGRAM_WALL: + aRet="DiagramWall"; + break; + case OBJECTTYPE_DIAGRAM_FLOOR: + aRet="DiagramFloor"; + break; + case OBJECTTYPE_AXIS: + aRet="Axis"; + break; + case OBJECTTYPE_AXIS_UNITLABEL: + aRet="AxisUnitLabel"; + break; + case OBJECTTYPE_GRID: + aRet="Grid"; + break; + case OBJECTTYPE_SUBGRID: + aRet="SubGrid"; + break; + case OBJECTTYPE_DATA_SERIES: + aRet="Series"; + break; + case OBJECTTYPE_DATA_POINT: + aRet="Point"; + break; + case OBJECTTYPE_DATA_LABELS: + aRet="DataLabels"; + break; + case OBJECTTYPE_DATA_LABEL: + aRet="DataLabel"; + break; + case OBJECTTYPE_DATA_ERRORS_X: + aRet="ErrorsX"; + break; + case OBJECTTYPE_DATA_ERRORS_Y: + aRet="ErrorsY"; + break; + case OBJECTTYPE_DATA_ERRORS_Z: + aRet="ErrorsZ"; + break; + case OBJECTTYPE_DATA_CURVE: + aRet="Curve"; + break; + case OBJECTTYPE_DATA_CURVE_EQUATION: + aRet="Equation"; + break; + case OBJECTTYPE_DATA_AVERAGE_LINE: + aRet="Average"; + break; + case OBJECTTYPE_DATA_STOCK_RANGE: + aRet="StockRange"; + break; + case OBJECTTYPE_DATA_STOCK_LOSS: + aRet="StockLoss"; + break; + case OBJECTTYPE_DATA_STOCK_GAIN: + aRet="StockGain"; + break; + default: //OBJECTTYPE_UNKNOWN + ; + } + return aRet; +} + +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("Page",nLastSign) ) + eRet = OBJECTTYPE_PAGE; + else if( rCID.match("Title",nLastSign) ) + eRet = OBJECTTYPE_TITLE; + else if( rCID.match("LegendEntry",nLastSign) ) + eRet = OBJECTTYPE_LEGEND_ENTRY; + else if( rCID.match("Legend",nLastSign) ) + eRet = OBJECTTYPE_LEGEND; + else if( rCID.match("DiagramWall",nLastSign) ) + eRet = OBJECTTYPE_DIAGRAM_WALL; + else if( rCID.match("DiagramFloor",nLastSign) ) + eRet = OBJECTTYPE_DIAGRAM_FLOOR; + else if( rCID.match("D=",nLastSign) ) + eRet = OBJECTTYPE_DIAGRAM; + else if( rCID.match("AxisUnitLabel",nLastSign) ) + eRet = OBJECTTYPE_AXIS_UNITLABEL; + else if( rCID.match("Axis",nLastSign) ) + eRet = OBJECTTYPE_AXIS; + else if( rCID.match("Grid",nLastSign) ) + eRet = OBJECTTYPE_GRID; + else if( rCID.match("SubGrid",nLastSign) ) + eRet = OBJECTTYPE_SUBGRID; + else if( rCID.match("Series",nLastSign) ) + eRet = OBJECTTYPE_DATA_SERIES; + else if( rCID.match("Point",nLastSign) ) + eRet = OBJECTTYPE_DATA_POINT; + else if( rCID.match("DataLabels",nLastSign) ) + eRet = OBJECTTYPE_DATA_LABELS; + else if( rCID.match("DataLabel",nLastSign) ) + eRet = OBJECTTYPE_DATA_LABEL; + else if( rCID.match("ErrorsX",nLastSign) ) + eRet = OBJECTTYPE_DATA_ERRORS_X; + else if( rCID.match("ErrorsY",nLastSign) ) + eRet = OBJECTTYPE_DATA_ERRORS_Y; + else if( rCID.match("ErrorsZ",nLastSign) ) + eRet = OBJECTTYPE_DATA_ERRORS_Z; + else if( rCID.match("Curve",nLastSign) ) + eRet = OBJECTTYPE_DATA_CURVE; + else if( rCID.match("Equation",nLastSign) ) + eRet = OBJECTTYPE_DATA_CURVE_EQUATION; + else if( rCID.match("Average",nLastSign) ) + eRet = OBJECTTYPE_DATA_AVERAGE_LINE; + else if( rCID.match("StockRange",nLastSign) ) + eRet = OBJECTTYPE_DATA_STOCK_RANGE; + else if( rCID.match("StockLoss",nLastSign) ) + eRet = OBJECTTYPE_DATA_STOCK_LOSS; + else if( rCID.match("StockGain",nLastSign) ) + eRet = OBJECTTYPE_DATA_STOCK_GAIN; + else + eRet = OBJECTTYPE_UNKNOWN; + + return eRet; +} + +ObjectType ObjectIdentifier::getObjectType() const +{ + ObjectType eObjectType( OBJECTTYPE_UNKNOWN ); + if ( isAutoGeneratedObject() ) + { + eObjectType = getObjectType( m_aObjectCID ); + } + else if ( isAdditionalShape() ) + { + eObjectType = OBJECTTYPE_SHAPE; + } + return eObjectType; +} + +OUString ObjectIdentifier::createDataCurveCID( + const OUString& rSeriesParticle + , sal_Int32 nCurveIndex + , bool bAverageLine ) +{ + OUString aParticleID( OUString::number( nCurveIndex ) ); + ObjectType eType = bAverageLine ? OBJECTTYPE_DATA_AVERAGE_LINE : OBJECTTYPE_DATA_CURVE; + return createClassifiedIdentifierWithParent( eType, aParticleID, rSeriesParticle ); +} + +OUString ObjectIdentifier::createDataCurveEquationCID( + const OUString& rSeriesParticle + , sal_Int32 nCurveIndex ) +{ + OUString aParticleID( OUString::number( nCurveIndex ) ); + return createClassifiedIdentifierWithParent( OBJECTTYPE_DATA_CURVE_EQUATION, aParticleID, rSeriesParticle ); +} + +OUString ObjectIdentifier::addChildParticle( const OUString& rParticle, const OUString& rChildParticle ) +{ + OUStringBuffer aRet(rParticle); + + if( !aRet.isEmpty() && !rChildParticle.isEmpty() ) + aRet.append(":"); + if( !rChildParticle.isEmpty() ) + aRet.append(rChildParticle); + + return aRet.makeStringAndClear(); +} + +OUString ObjectIdentifier::createChildParticleWithIndex( ObjectType eObjectType, sal_Int32 nIndex ) +{ + OUStringBuffer aRet( getStringForType( eObjectType ) ); + if( !aRet.isEmpty() ) + { + aRet.append("="); + aRet.append(OUString::number(nIndex)); + } + return aRet.makeStringAndClear(); +} + +sal_Int32 ObjectIdentifier::getIndexFromParticleOrCID( const OUString& rParticleOrCID ) +{ + const OUString aIndexString = lcl_getIndexStringAfterString( rParticleOrCID, "=" ); + return lcl_StringToIndex( aIndexString.getToken( 0, ',' ) ); +} + +OUString ObjectIdentifier::createSeriesSubObjectStub( ObjectType eSubObjectType + , const OUString& rSeriesParticle + , const OUString& rDragMethodServiceName + , const OUString& rDragParameterString ) +{ + OUString aChildParticle = getStringForType( eSubObjectType ) + "="; + + return createClassifiedIdentifierForParticles( + rSeriesParticle, aChildParticle + , rDragMethodServiceName, rDragParameterString ); +} + +OUString ObjectIdentifier::createPointCID( const OUString& rPointCID_Stub, sal_Int32 nIndex ) +{ + return rPointCID_Stub + OUString::number( nIndex ); +} + +OUString ObjectIdentifier::getParticleID( const OUString& rCID ) +{ + OUString aRet; + sal_Int32 nLast = rCID.lastIndexOf('='); + if(nLast>=0) + aRet = rCID.copy(++nLast); + return aRet; +} + +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; +} + +OUString ObjectIdentifier::getObjectID( const 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; +} + +bool ObjectIdentifier::isCID( const OUString& rName ) +{ + return !rName.isEmpty() && 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 )); +} + +Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet( + const OUString& rObjectCID + , const Reference< frame::XModel >& xChartModel ) +{ + //return the model object that is indicated by rObjectCID + if(rObjectCID.isEmpty()) + return nullptr; + if(!xChartModel.is()) + return nullptr; + + Reference< beans::XPropertySet > xObjectProperties; + 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.set( 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_X: + case OBJECTTYPE_DATA_ERRORS_Y: + case OBJECTTYPE_DATA_ERRORS_Z: + { + 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() ) + { + OUString errorBar; + + if ( eObjectType == OBJECTTYPE_DATA_ERRORS_X) + errorBar = CHART_UNONAME_ERRORBAR_X; + else if (eObjectType == OBJECTTYPE_DATA_ERRORS_Y) + errorBar = CHART_UNONAME_ERRORBAR_Y; + else + errorBar = "ErrorBarZ"; + + xSeriesProp->getPropertyValue( errorBar ) >>= xErrorBarProp; + xObjectProperties = xErrorBarProp; + } + } + 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( "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( "WhiteDay" ) >>= xObjectProperties; + } + break; + default: //OBJECTTYPE_UNKNOWN + break; + } + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + return xObjectProperties; +} + +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 ); +} + +Reference< XDataSeries > ObjectIdentifier::getDataSeriesForCID( + const OUString& rObjectCID + , const Reference< frame::XModel >& xChartModel ) +{ + Reference< XDataSeries > xSeries; + + 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; +} + +Reference< XDiagram > ObjectIdentifier::getDiagramForCID( + const 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 = std::find_if(rMap.begin(), rMap.end(), + [&aParentParticle](tTitleMap::const_reference rEntry) { return aParentParticle == rEntry.second; }); + if (aIt != rMap.end()) + eRet = (*aIt).first; + + return eRet; +} + +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 ); +} + +OUString ObjectIdentifier::getMovedSeriesCID( const OUString& rObjectCID, bool bForward ) +{ + sal_Int32 nDiagramIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CID/D=" ) ); + sal_Int32 nCooSysIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CS=" ) ); + sal_Int32 nChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CT=" ) ); + sal_Int32 nSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "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.isEmpty() ); +} + +bool ObjectIdentifier::isAdditionalShape() const +{ + return m_xAdditionalShape.is(); +} + +Any ObjectIdentifier::getAny() const +{ + Any aAny; + if ( isAutoGeneratedObject() ) + { + aAny <<= getObjectCID(); + } + else if ( isAdditionalShape() ) + { + aAny <<= getAdditionalShape(); + } + return aAny; +} + +} //namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |