summaryrefslogtreecommitdiffstats
path: root/chart2/source/tools/ObjectIdentifier.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/tools/ObjectIdentifier.cxx')
-rw-r--r--chart2/source/tools/ObjectIdentifier.cxx1405
1 files changed, 1405 insertions, 0 deletions
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx
new file mode 100644
index 0000000000..6e7631c8a9
--- /dev/null
+++ b/chart2/source/tools/ObjectIdentifier.cxx
@@ -0,0 +1,1405 @@
+/* -*- 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 <cstddef>
+#include <map>
+
+#include <ObjectIdentifier.hxx>
+#include <TitleHelper.hxx>
+#include <ChartModel.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartType.hxx>
+#include <GridProperties.hxx>
+#include <Axis.hxx>
+#include <AxisHelper.hxx>
+#include <servicenames_charttypes.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <unonames.hxx>
+#include <BaseCoordinateSystem.hxx>
+#include <DataSeries.hxx>
+#include <RegressionCurveModel.hxx>
+
+#include <com/sun/star/chart2/XAxis.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <utility>
+
+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;
+
+constexpr OUString m_aMultiClick = u"MultiClick"_ustr;
+constexpr OUString m_aDragMethodEquals = u"DragMethod="_ustr;
+constexpr OUString m_aDragParameterEquals = u"DragParameter="_ustr;
+constexpr OUString m_aProtocol = u"CID/"_ustr;
+constexpr OUString m_aPieSegmentDragMethodServiceName(u"PieSegmentDragging"_ustr);
+
+namespace
+{
+
+OUString lcl_createClassificationStringForType( ObjectType eObjectType
+ , std::u16string_view rDragMethodServiceName
+ , std::u16string_view 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.empty() )
+ {
+ if( !aRet.isEmpty() )
+ aRet.append(":");
+ aRet.append( OUString::Concat(m_aDragMethodEquals) + rDragMethodServiceName );
+
+ if( !rDragParameterString.empty() )
+ {
+ if( !aRet.isEmpty() )
+ aRet.append(":");
+ aRet.append( OUString::Concat(m_aDragParameterEquals) + 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;
+}
+
+rtl::Reference<ChartType> lcl_getFirstStockChartType( const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
+ if(!xDiagram.is())
+ return nullptr;
+
+ //iterate through all coordinate systems
+
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysList( xDiagram->getBaseCoordinateSystems() );
+ for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysList )
+ {
+ //iterate through all chart types in the current coordinate system
+ for( rtl::Reference< ChartType > const & xChartType : coords->getChartTypes2() )
+ {
+ OUString aChartType = xChartType->getChartType();
+ if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
+ return xChartType;
+ }
+ }
+ return nullptr;
+}
+
+std::u16string_view lcl_getIndexStringAfterString( std::u16string_view rString, std::u16string_view rSearchString )
+{
+ size_t nIndexStart = rString.rfind( rSearchString );
+ if( nIndexStart == std::u16string_view::npos )
+ return std::u16string_view();
+ nIndexStart += rSearchString.size();
+ size_t nIndexEnd = rString.size();
+ size_t nNextColon = rString.find( ':', nIndexStart );
+ if( nNextColon != std::u16string_view::npos )
+ nIndexEnd = nNextColon;
+ return rString.substr(nIndexStart,nIndexEnd-nIndexStart);
+}
+
+sal_Int32 lcl_StringToIndex( std::u16string_view rIndexString )
+{
+ sal_Int32 nRet = -1;
+ if( !rIndexString.empty() )
+ {
+ nRet = o3tl::toInt32(rIndexString);
+ if( nRet < -1 )
+ nRet = -1;
+ }
+ return nRet;
+}
+
+void lcl_parseCooSysIndices( sal_Int32& rnDiagram, sal_Int32& rnCooSys, std::u16string_view rString )
+{
+ rnDiagram = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u"D=" ) );
+ rnCooSys = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u"CS=" ) );
+}
+
+void lcl_parseAxisIndices( sal_Int32& rnDimensionIndex, sal_Int32& rnAxisIndex, std::u16string_view rString )
+{
+ std::u16string_view aAxisIndexString = lcl_getIndexStringAfterString( rString, u":Axis=" );
+ sal_Int32 nCharacterIndex=0;
+ rnDimensionIndex = lcl_StringToIndex( o3tl::getToken(aAxisIndexString, 0, ',', nCharacterIndex ) );
+ rnAxisIndex = lcl_StringToIndex( o3tl::getToken(aAxisIndexString, 0, ',', nCharacterIndex ) );
+}
+
+void lcl_parseGridIndices( sal_Int32& rnSubGridIndex, std::u16string_view rString )
+{
+ rnSubGridIndex = -1;
+ rnSubGridIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u":SubGrid=" ) );
+}
+
+void lcl_parseSeriesIndices( sal_Int32& rnChartTypeIndex, sal_Int32& rnSeriesIndex, sal_Int32& rnPointIndex, std::u16string_view rString )
+{
+ rnChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u"CT=" ) );
+ rnSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u"Series=" ) );
+ rnPointIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, u"Point=" ) );
+}
+
+void lcl_getDiagramAndCooSys( std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel
+ , rtl::Reference< Diagram >& xDiagram
+ , rtl::Reference< BaseCoordinateSystem >& xCooSys )
+{
+ sal_Int32 nDiagramIndex = -1;
+ sal_Int32 nCooSysIndex = -1;
+ lcl_parseCooSysIndices( nDiagramIndex, nCooSysIndex, rObjectCID );
+ xDiagram = xChartModel->getFirstChartDiagram();//todo use nDiagramIndex when more than one diagram is possible in future
+ if( !xDiagram.is() )
+ return;
+
+ if( nCooSysIndex > -1 )
+ {
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysList( xDiagram->getBaseCoordinateSystems() );
+ if( o3tl::make_unsigned(nCooSysIndex) < aCooSysList.size() )
+ xCooSys = aCooSysList[nCooSysIndex];
+ }
+}
+
+} //anonymous namespace
+
+ObjectIdentifier::ObjectIdentifier()
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( OUString aObjectCID )
+ :m_aObjectCID(std::move( aObjectCID ))
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const Reference< drawing::XShape >& rxShape )
+ : m_xAdditionalShape( rxShape )
+{
+}
+
+ObjectIdentifier::ObjectIdentifier( const Any& rAny )
+{
+ 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 rtl::Reference< ::chart::Title >& xTitle
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ TitleHelper::eTitleType aTitleType;
+ OUString aRet;
+ const std::u16string_view aObjectID;
+ const std::u16string_view aDragMethodServiceName;
+ const std::u16string_view aDragParameterString;
+ if( TitleHelper::getTitleType( aTitleType, xTitle, xChartModel ) )
+ {
+ enum ObjectType eObjectType = OBJECTTYPE_TITLE;
+ OUString aParentParticle = lcl_getTitleParentParticle( aTitleType );
+ aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
+ eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
+ }
+ return aRet;
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifierForObject(
+ const Reference< uno::XInterface >& xObject
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ enum ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
+ const std::u16string_view aObjectID;
+ OUString aParentParticle;
+ const std::u16string_view aDragMethodServiceName;
+ const std::u16string_view aDragParameterString;
+
+ try
+ {
+ //title
+ if( ::chart::Title* pTitle = dynamic_cast<::chart::Title*>(xObject.get()) )
+ return createClassifiedIdentifierForObject(rtl::Reference<Title>(pTitle), xChartModel);
+
+ uno::Reference<chart2::XDataTable> xDataTable(xObject, uno::UNO_QUERY);
+ if (xDataTable.is())
+ {
+ return createClassifiedIdentifierForParticle(createParticleForDataTable(xChartModel));
+ }
+
+ //axis
+ rtl::Reference< Axis > xAxis = dynamic_cast<Axis*>( xObject.get() );
+ if( xAxis.is() )
+ {
+ rtl::Reference<Diagram> xDiagram = xChartModel->getFirstChartDiagram();
+ rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, xDiagram ) );
+ 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::createClassifiedIdentifierForObject(
+ const rtl::Reference< Legend >& xLegend
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ try
+ {
+ if( xLegend.is() )
+ {
+ return createClassifiedIdentifierForParticle( createParticleForLegend( xChartModel ) );
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ OSL_FAIL("give object could not be identified in createClassifiedIdentifierForObject");
+
+ return OUString();
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifierForObject(
+ const rtl::Reference<::chart::Axis>& xAxis
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ try
+ {
+ //axis
+ if( xAxis.is() )
+ {
+ rtl::Reference<Diagram> xDiagram = xChartModel->getFirstChartDiagram();
+ rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, xDiagram ) );
+ 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 );
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ OSL_FAIL("give object could not be identified in createClassifiedIdentifierForObject");
+
+ return OUString();
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifierForParticle(
+ std::u16string_view rParticle )
+{
+ return ObjectIdentifier::createClassifiedIdentifierForParticles( rParticle, u"" );
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifierForParticles(
+ std::u16string_view rParentParticle
+ , std::u16string_view rChildParticle
+ , std::u16string_view rDragMethodServiceName
+ , std::u16string_view rDragParameterString )
+{
+ ObjectType eObjectType( ObjectIdentifier::getObjectType( rChildParticle ) );
+ if( eObjectType == OBJECTTYPE_UNKNOWN )
+ eObjectType = ObjectIdentifier::getObjectType( rParentParticle );
+
+ OUStringBuffer aRet( m_aProtocol +
+ lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
+ if(aRet.getLength() > m_aProtocol.getLength())
+ aRet.append("/");
+
+ if(!rParentParticle.empty())
+ {
+ aRet.append(rParentParticle);
+ if( !rChildParticle.empty() )
+ 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 rtl::Reference< BaseCoordinateSystem >& xCooSys
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
+ if( xDiagram.is() )
+ {
+ std::size_t nCooSysIndex = 0;
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysList( xDiagram->getBaseCoordinateSystems() );
+ for( ; nCooSysIndex < aCooSysList.size(); ++nCooSysIndex )
+ {
+ if( xCooSys == aCooSysList[nCooSysIndex] )
+ {
+ aRet = ObjectIdentifier::createParticleForDiagram() + ":CS=" + OUString::number( nCooSysIndex );
+ break;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+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 rtl::Reference<::chart::ChartModel>& 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 )
+{
+ return
+ "D=" + OUString::number( nDiagramIndex ) +
+ ":CS=" + OUString::number( nCooSysIndex ) +
+ ":CT=" + OUString::number( nChartTypeIndex ) +
+ ":" + getStringForType( OBJECTTYPE_DATA_SERIES ) + "=" +
+ OUString::number( nSeriesIndex );
+}
+
+
+OUString ObjectIdentifier::createParticleForLegend(
+ const rtl::Reference<::chart::ChartModel>& )
+{
+ //todo: if more than one diagram is implemented, find the correct diagram which is owner of the given legend
+
+ return ObjectIdentifier::createParticleForDiagram() + ":" + getStringForType( OBJECTTYPE_LEGEND ) + "=";
+}
+
+OUString ObjectIdentifier::createParticleForDataTable(const rtl::Reference<::chart::ChartModel>& /* xChartModel */)
+{
+ return ObjectIdentifier::createParticleForDiagram() + ":" + getStringForType(OBJECTTYPE_DATA_TABLE) + "=";
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifier(
+ enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_SERIES
+ , std::u16string_view rParticleID )//e.g. SeriesID
+{
+ return createClassifiedIdentifierWithParent(
+ eObjectType, rParticleID, u"" );
+}
+
+OUString ObjectIdentifier::createClassifiedIdentifierWithParent(
+ enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_POINT or OBJECTTYPE_GRID
+ , std::u16string_view rParticleID //e.g. Point Index or SubGrid Index
+ , std::u16string_view rParentPartical //e.g. "Series=SeriesID" or "Grid=GridId"
+ , std::u16string_view rDragMethodServiceName
+ , std::u16string_view rDragParameterString
+ )
+ //, bool bIsMultiClickObject ) //e.g. true
+{
+ //e.g. "MultiClick/Series=2:Point=34"
+
+ OUStringBuffer aRet( m_aProtocol +
+ lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
+ if(aRet.getLength() > m_aProtocol.getLength())
+ aRet.append("/");
+ aRet.append(rParentPartical);
+ if(!rParentPartical.empty())
+ aRet.append(":");
+
+ aRet.append(getStringForType( eObjectType ) + "=" + 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(
+ std::u16string_view rDragParameterString
+ , sal_Int32& rOffsetPercent
+ , awt::Point& rMinimumPosition
+ , awt::Point& rMaximumPosition )
+{
+ sal_Int32 nCharacterIndex = 0;
+
+ std::u16string_view aValueString( o3tl::getToken(rDragParameterString, 0, ',', nCharacterIndex ) );
+ rOffsetPercent = o3tl::toInt32(aValueString);
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = o3tl::getToken(rDragParameterString, 0, ',', nCharacterIndex );
+ rMinimumPosition.X = o3tl::toInt32(aValueString);
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = o3tl::getToken(rDragParameterString, 0, ',', nCharacterIndex );
+ rMinimumPosition.Y = o3tl::toInt32(aValueString);
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = o3tl::getToken(rDragParameterString, 0, ',', nCharacterIndex );
+ rMaximumPosition.X = o3tl::toInt32(aValueString);
+ if( nCharacterIndex < 0 )
+ return false;
+
+ aValueString = o3tl::getToken(rDragParameterString, 0, ',', nCharacterIndex );
+ rMaximumPosition.Y = o3tl::toInt32(aValueString);
+ return nCharacterIndex >= 0;
+}
+
+std::u16string_view ObjectIdentifier::getDragMethodServiceName( std::u16string_view rCID )
+{
+ std::u16string_view aRet;
+
+ size_t nIndexStart = rCID.find( m_aDragMethodEquals );
+ if( nIndexStart != std::u16string_view::npos )
+ {
+ nIndexStart = rCID.find( '=', nIndexStart );
+ if( nIndexStart != std::u16string_view::npos )
+ {
+ nIndexStart++;
+ size_t nNextSlash = rCID.find( '/', nIndexStart );
+ if( nNextSlash != std::u16string_view::npos )
+ {
+ sal_Int32 nIndexEnd = nNextSlash;
+ size_t nNextColon = rCID.find( ':', nIndexStart );
+ if( nNextColon == std::u16string_view::npos || nNextColon < nNextSlash )
+ nIndexEnd = nNextColon;
+ aRet = rCID.substr(nIndexStart,nIndexEnd-nIndexStart);
+ }
+ }
+ }
+ return aRet;
+}
+
+std::u16string_view ObjectIdentifier::getDragParameterString( std::u16string_view rCID )
+{
+ std::u16string_view aRet;
+
+ size_t nIndexStart = rCID.find( m_aDragParameterEquals );
+ if( nIndexStart != std::u16string_view::npos )
+ {
+ nIndexStart = rCID.find( '=', nIndexStart );
+ if( nIndexStart != std::u16string_view::npos )
+ {
+ nIndexStart++;
+ size_t nNextSlash = rCID.find( '/', nIndexStart );
+ if( nNextSlash != std::u16string_view::npos )
+ {
+ sal_Int32 nIndexEnd = nNextSlash;
+ size_t nNextColon = rCID.find( ':', nIndexStart );
+ if( nNextColon == std::u16string_view::npos || nNextColon < nNextSlash )
+ nIndexEnd = nNextColon;
+ aRet = rCID.substr(nIndexStart,nIndexEnd-nIndexStart);
+ }
+ }
+ }
+ return aRet;
+}
+
+bool ObjectIdentifier::isDragableObject( std::u16string_view 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:
+ std::u16string_view aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) );
+ bReturn = !aDragMethodServiceName.empty();
+ 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( std::u16string_view 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( std::u16string_view 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 = o3tl::starts_with(rClassifiedIdentifier.substr( m_aProtocol.getLength() ), m_aMultiClick);
+ return bRet;
+}
+
+bool ObjectIdentifier::areSiblings( std::u16string_view rCID1, std::u16string_view rCID2 )
+{
+ bool bRet=false;
+ size_t nLastSign1 = rCID1.rfind( '=' );
+ size_t nLastSign2 = rCID2.rfind( '=' );
+ if( nLastSign1 == rCID1.find( '=' ) )//CID cannot be sibling if only one "=" occurs
+ bRet=false;
+ else if( nLastSign2 == rCID2.find( '=' ) )//CID cannot be sibling if only one "=" occurs
+ bRet=false;
+ else if( ObjectIdentifier::areIdenticalObjects( rCID1, rCID2 ) )
+ bRet=false;
+ else
+ {
+ std::u16string_view aParent1( ObjectIdentifier::getFullParentParticle( rCID1 ) );
+ if( !aParent1.empty() )
+ {
+ std::u16string_view 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( std::u16string_view rCID1, std::u16string_view rCID2 )
+{
+ if( rCID1 == rCID2 )
+ return true;
+ //draggable pie or donut segments need special treatment, as their CIDs do change with offset
+ {
+ if( rCID1.find( m_aPieSegmentDragMethodServiceName ) == std::u16string_view::npos
+ || rCID2.find( m_aPieSegmentDragMethodServiceName ) == std::u16string_view::npos )
+ 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;
+ case OBJECTTYPE_DATA_TABLE:
+ aRet="DataTable";
+ break;
+ default: //OBJECTTYPE_UNKNOWN
+ ;
+ }
+ return aRet;
+}
+
+ObjectType ObjectIdentifier::getObjectType( std::u16string_view aCID )
+{
+ ObjectType eRet;
+ size_t nLastSign = aCID.rfind( ':' );//last sign before the type string
+ if(nLastSign == std::u16string_view::npos)
+ nLastSign = aCID.rfind( '/' );
+ if(nLastSign == std::u16string_view::npos)
+ {
+ size_t nEndIndex = aCID.rfind( '=' );
+ if(nEndIndex == std::u16string_view::npos)
+ return OBJECTTYPE_UNKNOWN;
+ nLastSign = 0;
+ }
+ if( nLastSign>0 )
+ nLastSign++;
+
+ aCID = aCID.substr(nLastSign);
+ if( o3tl::starts_with(aCID, u"Page") )
+ eRet = OBJECTTYPE_PAGE;
+ else if( o3tl::starts_with(aCID, u"Title") )
+ eRet = OBJECTTYPE_TITLE;
+ else if( o3tl::starts_with(aCID, u"LegendEntry") )
+ eRet = OBJECTTYPE_LEGEND_ENTRY;
+ else if( o3tl::starts_with(aCID, u"Legend") )
+ eRet = OBJECTTYPE_LEGEND;
+ else if( o3tl::starts_with(aCID, u"DiagramWall") )
+ eRet = OBJECTTYPE_DIAGRAM_WALL;
+ else if( o3tl::starts_with(aCID, u"DiagramFloor") )
+ eRet = OBJECTTYPE_DIAGRAM_FLOOR;
+ else if( o3tl::starts_with(aCID, u"D=") )
+ eRet = OBJECTTYPE_DIAGRAM;
+ else if( o3tl::starts_with(aCID, u"AxisUnitLabel") )
+ eRet = OBJECTTYPE_AXIS_UNITLABEL;
+ else if( o3tl::starts_with(aCID, u"Axis") )
+ eRet = OBJECTTYPE_AXIS;
+ else if( o3tl::starts_with(aCID, u"Grid") )
+ eRet = OBJECTTYPE_GRID;
+ else if( o3tl::starts_with(aCID, u"SubGrid") )
+ eRet = OBJECTTYPE_SUBGRID;
+ else if( o3tl::starts_with(aCID, u"Series") )
+ eRet = OBJECTTYPE_DATA_SERIES;
+ else if( o3tl::starts_with(aCID, u"Point") )
+ eRet = OBJECTTYPE_DATA_POINT;
+ else if( o3tl::starts_with(aCID, u"DataLabels") )
+ eRet = OBJECTTYPE_DATA_LABELS;
+ else if( o3tl::starts_with(aCID, u"DataLabel") )
+ eRet = OBJECTTYPE_DATA_LABEL;
+ else if( o3tl::starts_with(aCID, u"ErrorsX") )
+ eRet = OBJECTTYPE_DATA_ERRORS_X;
+ else if( o3tl::starts_with(aCID, u"ErrorsY") )
+ eRet = OBJECTTYPE_DATA_ERRORS_Y;
+ else if( o3tl::starts_with(aCID, u"ErrorsZ") )
+ eRet = OBJECTTYPE_DATA_ERRORS_Z;
+ else if( o3tl::starts_with(aCID, u"Curve") )
+ eRet = OBJECTTYPE_DATA_CURVE;
+ else if( o3tl::starts_with(aCID, u"Equation") )
+ eRet = OBJECTTYPE_DATA_CURVE_EQUATION;
+ else if( o3tl::starts_with(aCID, u"Average") )
+ eRet = OBJECTTYPE_DATA_AVERAGE_LINE;
+ else if( o3tl::starts_with(aCID, u"StockRange") )
+ eRet = OBJECTTYPE_DATA_STOCK_RANGE;
+ else if( o3tl::starts_with(aCID, u"StockLoss") )
+ eRet = OBJECTTYPE_DATA_STOCK_LOSS;
+ else if( o3tl::starts_with(aCID, u"StockGain") )
+ eRet = OBJECTTYPE_DATA_STOCK_GAIN;
+ else if( o3tl::starts_with(aCID, u"DataTable") )
+ eRet = OBJECTTYPE_DATA_TABLE;
+ 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(
+ std::u16string_view 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(
+ std::u16string_view rSeriesParticle
+ , sal_Int32 nCurveIndex )
+{
+ OUString aParticleID( OUString::number( nCurveIndex ) );
+ return createClassifiedIdentifierWithParent( OBJECTTYPE_DATA_CURVE_EQUATION, aParticleID, rSeriesParticle );
+}
+
+OUString ObjectIdentifier::addChildParticle( std::u16string_view rParticle, std::u16string_view rChildParticle )
+{
+ OUStringBuffer aRet(rParticle);
+
+ if( !aRet.isEmpty() && !rChildParticle.empty() )
+ aRet.append(":");
+ if( !rChildParticle.empty() )
+ aRet.append(rChildParticle);
+
+ return aRet.makeStringAndClear();
+}
+
+OUString ObjectIdentifier::createChildParticleWithIndex( ObjectType eObjectType, sal_Int32 nIndex )
+{
+ OUStringBuffer aRet( getStringForType( eObjectType ) );
+ if( !aRet.isEmpty() )
+ {
+ aRet.append("=" + OUString::number(nIndex));
+ }
+ return aRet.makeStringAndClear();
+}
+
+sal_Int32 ObjectIdentifier::getIndexFromParticleOrCID( std::u16string_view rParticleOrCID )
+{
+ const std::u16string_view aIndexString = lcl_getIndexStringAfterString( rParticleOrCID, u"=" );
+ return lcl_StringToIndex( o3tl::getToken(aIndexString, 0, ',' ) );
+}
+
+OUString ObjectIdentifier::createSeriesSubObjectStub( ObjectType eSubObjectType
+ , std::u16string_view rSeriesParticle
+ , std::u16string_view rDragMethodServiceName
+ , std::u16string_view rDragParameterString )
+{
+ OUString aChildParticle = getStringForType( eSubObjectType ) + "=";
+
+ return createClassifiedIdentifierForParticles(
+ rSeriesParticle, aChildParticle
+ , rDragMethodServiceName, rDragParameterString );
+}
+
+OUString ObjectIdentifier::createPointCID( std::u16string_view rPointCID_Stub, sal_Int32 nIndex )
+{
+ return rPointCID_Stub + OUString::number( nIndex );
+}
+
+std::u16string_view ObjectIdentifier::getParticleID( std::u16string_view rCID )
+{
+ std::u16string_view aRet;
+ size_t nLast = rCID.rfind('=');
+ if(nLast != std::u16string_view::npos)
+ aRet = rCID.substr(++nLast);
+ return aRet;
+}
+
+std::u16string_view ObjectIdentifier::getFullParentParticle( std::u16string_view rCID )
+{
+ std::u16string_view aRet;
+
+ size_t nStartPos = rCID.rfind('/');
+ if( nStartPos != std::u16string_view::npos )
+ {
+ nStartPos++;
+ size_t nEndPos = rCID.rfind(':');
+ if( nEndPos != std::u16string_view::npos && nStartPos < nEndPos )
+ {
+ aRet = rCID.substr(nStartPos,nEndPos-nStartPos);
+ }
+ }
+
+ return aRet;
+}
+
+OUString ObjectIdentifier::getObjectID( std::u16string_view rCID )
+{
+ OUString aRet;
+
+ size_t nStartPos = rCID.rfind('/');
+ if( nStartPos != std::u16string_view::npos )
+ {
+ nStartPos++;
+ size_t nEndPos = rCID.size();
+ aRet = rCID.substr(nStartPos,nEndPos-nStartPos);
+ }
+
+ return aRet;
+}
+
+bool ObjectIdentifier::isCID( std::u16string_view rName )
+{
+ return !rName.empty() && o3tl::starts_with( rName, m_aProtocol );
+}
+
+Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet(
+ std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ //return the model object that is indicated by rObjectCID
+ if(rObjectCID.empty())
+ return nullptr;
+ if(!xChartModel.is())
+ return nullptr;
+
+ Reference< beans::XPropertySet > xObjectProperties;
+ try
+ {
+ ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
+ std::u16string_view aParticleID = ObjectIdentifier::getParticleID( rObjectCID );
+
+ rtl::Reference< Diagram > xDiagram;
+ rtl::Reference< BaseCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ switch(eObjectType)
+ {
+ case OBJECTTYPE_PAGE:
+ {
+ xObjectProperties.set( xChartModel->getPageBackground() );
+ }
+ break;
+ case OBJECTTYPE_TITLE:
+ {
+ TitleHelper::eTitleType aTitleType = getTitleTypeForCID( rObjectCID );
+ rtl::Reference< Title > xTitle( TitleHelper::getTitle( aTitleType, xChartModel ) );
+ xObjectProperties = xTitle;
+ }
+ break;
+ case OBJECTTYPE_LEGEND:
+ {
+ if( xDiagram.is() )
+ xObjectProperties.set( xDiagram->getLegend(), uno::UNO_QUERY );
+ }
+ break;
+ case OBJECTTYPE_LEGEND_ENTRY:
+ break;
+ case OBJECTTYPE_DIAGRAM:
+ {
+ xObjectProperties = xDiagram;
+ }
+ 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 );
+
+ rtl::Reference< Axis > xAxis =
+ AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys );
+ if( xAxis.is() )
+ xObjectProperties = xAxis;
+ }
+ 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 = AxisHelper::getGridProperties( xCooSys , nDimensionIndex, nAxisIndex, nSubGridIndex );
+ }
+ break;
+ case OBJECTTYPE_DATA_LABELS:
+ case OBJECTTYPE_DATA_SERIES:
+ {
+ rtl::Reference< DataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel ) );
+ if( xSeries.is() )
+ xObjectProperties = xSeries;
+
+ break;
+ }
+ case OBJECTTYPE_DATA_LABEL:
+ case OBJECTTYPE_DATA_POINT:
+ {
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel );
+ if(xSeries.is())
+ {
+ sal_Int32 nIndex = o3tl::toInt32(aParticleID);
+ xObjectProperties = xSeries->getDataPointByIndex( nIndex );
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_ERRORS_X:
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ {
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel );
+ if(xSeries.is())
+ {
+ Reference< beans::XPropertySet > xErrorBarProp;
+ 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";
+
+ xSeries->getPropertyValue( errorBar ) >>= xErrorBarProp;
+ xObjectProperties = xErrorBarProp;
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ case OBJECTTYPE_DATA_CURVE:
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ {
+ rtl::Reference< DataSeries > xRegressionContainer = ObjectIdentifier::getDataSeriesForCID(
+ rObjectCID, xChartModel );
+ if(xRegressionContainer.is())
+ {
+ sal_Int32 nIndex = o3tl::toInt32(aParticleID);
+ const std::vector< rtl::Reference< RegressionCurveModel > > & aCurveList =
+ xRegressionContainer->getRegressionCurves2();
+ if( nIndex >= 0 && o3tl::make_unsigned(nIndex) < aCurveList.size() )
+ {
+ if( eObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
+ xObjectProperties = aCurveList[nIndex]->getEquationProperties();
+ else
+ xObjectProperties = aCurveList[nIndex];
+ }
+ }
+ break;
+ }
+ case OBJECTTYPE_DATA_STOCK_RANGE:
+ break;
+ case OBJECTTYPE_DATA_STOCK_LOSS:
+ {
+ rtl::Reference<ChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
+ if(xChartType.is())
+ xChartType->getPropertyValue( "BlackDay" ) >>= xObjectProperties;
+ }
+ break;
+ case OBJECTTYPE_DATA_STOCK_GAIN:
+ {
+ rtl::Reference<ChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
+ if(xChartType.is())
+ xChartType->getPropertyValue( "WhiteDay" ) >>= xObjectProperties;
+ }
+ break;
+ case OBJECTTYPE_DATA_TABLE:
+ {
+ if (xDiagram.is())
+ xObjectProperties.set(xDiagram->getDataTable(), uno::UNO_QUERY);
+ }
+ break;
+ break;
+ default: //OBJECTTYPE_UNKNOWN
+ break;
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return xObjectProperties;
+}
+
+rtl::Reference< Axis > ObjectIdentifier::getAxisForCID(
+ std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< Diagram > xDiagram;
+ rtl::Reference< BaseCoordinateSystem > 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 );
+}
+
+rtl::Reference< DataSeries > ObjectIdentifier::getDataSeriesForCID(
+ std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< Diagram > xDiagram;
+ rtl::Reference< BaseCoordinateSystem > 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 );
+
+ rtl::Reference< DataSeries > xSeries;
+ if (xDiagram)
+ {
+ rtl::Reference< ChartType > xDataSeriesContainer( xDiagram->getChartTypeByIndex( nChartTypeIndex ) );
+ if( xDataSeriesContainer.is() )
+ {
+ const std::vector< rtl::Reference< DataSeries > > & aDataSeriesSeq( xDataSeriesContainer->getDataSeries2() );
+ if( nSeriesIndex >= 0 && o3tl::make_unsigned(nSeriesIndex) < aDataSeriesSeq.size() )
+ xSeries = aDataSeriesSeq[nSeriesIndex];
+ }
+ }
+ return xSeries;
+}
+
+rtl::Reference< Diagram > ObjectIdentifier::getDiagramForCID(
+ std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< Diagram > xDiagram;
+ rtl::Reference< BaseCoordinateSystem > xCooSys;
+ lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
+
+ return xDiagram;
+}
+
+TitleHelper::eTitleType ObjectIdentifier::getTitleTypeForCID( std::u16string_view rCID )
+{
+ TitleHelper::eTitleType eRet( TitleHelper::MAIN_TITLE );
+
+ std::u16string_view 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( std::u16string_view 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( std::u16string_view rObjectCID, bool bForward )
+{
+ sal_Int32 nDiagramIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, u"CID/D=" ) );
+ sal_Int32 nCooSysIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, u"CS=" ) );
+ sal_Int32 nChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, u"CT=" ) );
+ sal_Int32 nSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, u"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: */