1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ObjectHierarchy.hxx"
21 #include "ObjectIdentifier.hxx"
22 #include "ChartModelHelper.hxx"
23 #include "DiagramHelper.hxx"
24 #include "RegressionCurveHelper.hxx"
25 #include "AxisHelper.hxx"
26 #include "chartview/ExplicitValueProvider.hxx"
28 #include "LineProperties.hxx"
29 #include "ChartTypeHelper.hxx"
30 #include "DataSeriesHelper.hxx"
31 #include "LegendHelper.hxx"
32 #include "chartview/DrawModelWrapper.hxx"
33 #include <unonames.hxx>
38 #include <com/sun/star/chart2/XTitled.hpp>
39 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
40 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
41 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42 #include <com/sun/star/chart/ErrorBarStyle.hpp>
44 #include <com/sun/star/container/XIndexAccess.hpp>
45 #include <com/sun/star/awt/Key.hpp>
46 #include <com/sun/star/awt/KeyModifier.hpp>
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::chart2
;
51 using ::com::sun::star::uno::Reference
;
52 using ::com::sun::star::uno::Sequence
;
57 struct lcl_ObjectToOID
: public ::std::unary_function
< Reference
< uno::XInterface
>, ::chart::ObjectIdentifier
>
59 explicit lcl_ObjectToOID( const Reference
< chart2::XChartDocument
> & xChartDoc
) :
60 m_xModel( xChartDoc
, uno::UNO_QUERY
)
63 ::chart::ObjectIdentifier
operator() ( const Reference
< uno::XInterface
> & xObj
)
65 return ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj
, m_xModel
) );
69 Reference
< frame::XModel
> m_xModel
;
72 void lcl_getChildOIDs(
73 ::chart::ObjectHierarchy::tChildContainer
& rOutChildren
,
74 const Reference
< container::XIndexAccess
>& xShapes
)
78 sal_Int32 nCount
= xShapes
->getCount();
79 for( sal_Int32 i
=0; i
<nCount
; ++i
)
81 Reference
< beans::XPropertySet
> xShapeProp( xShapes
->getByIndex( i
), uno::UNO_QUERY
);
84 Reference
< beans::XPropertySetInfo
> xInfo( xShapeProp
->getPropertySetInfo());
87 xInfo
->hasPropertyByName( "Name") &&
88 (xShapeProp
->getPropertyValue( "Name") >>= aName
) &&
90 ::chart::ObjectIdentifier::isCID( aName
))
92 rOutChildren
.push_back( ::chart::ObjectIdentifier( aName
) );
94 Reference
< container::XIndexAccess
> xNewShapes( xShapeProp
, uno::UNO_QUERY
);
96 lcl_getChildOIDs( rOutChildren
, xNewShapes
);
102 void lcl_addAxisTitle( const Reference
< XAxis
>& xAxis
, ::chart::ObjectHierarchy::tChildContainer
& rContainer
, const Reference
< frame::XModel
>& xChartModel
)
104 Reference
< XTitled
> xAxisTitled( xAxis
, uno::UNO_QUERY
);
105 if( xAxisTitled
.is())
107 Reference
< XTitle
> xAxisTitle( xAxisTitled
->getTitleObject());
109 rContainer
.push_back(
110 ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle
, xChartModel
) ) );
114 } // anonymous namespace
122 class ImplObjectHierarchy
125 explicit ImplObjectHierarchy(
126 const Reference
< XChartDocument
>& xChartDocument
,
127 ExplicitValueProvider
* pExplicitValueProvider
,
128 bool bFlattenDiagram
, bool bOrderingForElementSelector
);
130 bool hasChildren( const ObjectHierarchy::tOID
& rParent
);
131 ObjectHierarchy::tChildContainer
getChildren( const ObjectHierarchy::tOID
& rParent
);
132 ObjectHierarchy::tChildContainer
getSiblings( const ObjectHierarchy::tOID
& rNode
);
134 ObjectHierarchy::tOID
getParent( const ObjectHierarchy::tOID
& rOID
);
137 void createTree( const Reference
< XChartDocument
> & xChartDocument
);
139 ObjectHierarchy::tChildContainer
& rContainer
,
140 const Reference
< XChartDocument
> & xChartDoc
,
141 const Reference
< XDiagram
> & xDiagram
);
142 void createDiagramTree(
143 ObjectHierarchy::tChildContainer
& rContainer
,
144 const Reference
< XChartDocument
>& xChartDoc
,
145 const Reference
< XDiagram
>& xDiagram
);
146 void createDataSeriesTree(
147 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
148 const Reference
< XDiagram
> & xDiagram
);
149 static void createWallAndFloor(
150 ObjectHierarchy::tChildContainer
& rContainer
,
151 const Reference
< XDiagram
> & xDiagram
);
152 void createLegendTree(
153 ObjectHierarchy::tChildContainer
& rContainer
,
154 const Reference
< XChartDocument
> & xChartDoc
,
155 const Reference
< XDiagram
> & xDiagram
);
156 void createAdditionalShapesTree( ObjectHierarchy::tChildContainer
& rContainer
);
158 ObjectHierarchy::tOID
getParentImpl(
159 const ObjectHierarchy::tOID
& rParentOID
,
160 const ObjectHierarchy::tOID
& rOID
);
162 typedef ::std::map
< ObjectHierarchy::tOID
, ObjectHierarchy::tChildContainer
>
164 tChildMap m_aChildMap
;
165 ExplicitValueProvider
* m_pExplicitValueProvider
;
166 bool m_bFlattenDiagram
;
167 bool m_bOrderingForElementSelector
;
170 ImplObjectHierarchy::ImplObjectHierarchy(
171 const Reference
< XChartDocument
>& xChartDocument
,
172 ExplicitValueProvider
* pExplicitValueProvider
,
173 bool bFlattenDiagram
,
174 bool bOrderingForElementSelector
) :
175 m_pExplicitValueProvider( pExplicitValueProvider
),
176 m_bFlattenDiagram( bFlattenDiagram
),
177 m_bOrderingForElementSelector( bOrderingForElementSelector
)
179 createTree( xChartDocument
);
180 // don't remember this helper to avoid access after lifetime
181 m_pExplicitValueProvider
= 0;
184 void ImplObjectHierarchy::createTree( const Reference
< XChartDocument
>& xChartDocument
)
186 m_aChildMap
= tChildMap();//clear tree
188 if( !xChartDocument
.is() )
191 //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
192 Reference
< frame::XModel
> xModel( xChartDocument
, uno::UNO_QUERY
);
193 Reference
< XDiagram
> xDiagram( ChartModelHelper::findDiagram( xChartDocument
) );
194 ObjectHierarchy::tOID aDiaOID
;
196 aDiaOID
= ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
, xModel
) );
197 ObjectHierarchy::tChildContainer aTopLevelContainer
;
202 if( m_bOrderingForElementSelector
)
204 aTopLevelContainer
.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) ) );
207 aTopLevelContainer
.push_back( aDiaOID
);
208 createWallAndFloor( aTopLevelContainer
, xDiagram
);
209 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
214 Reference
< XTitled
> xDocTitled( xChartDocument
, uno::UNO_QUERY
);
217 Reference
< XTitle
> xMainTitle( xDocTitled
->getTitleObject());
219 aTopLevelContainer
.push_back(
220 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle
, xModel
) ) );
225 // Sub Title. Note: This is interpreted of being top level
226 Reference
< XTitled
> xDiaTitled( xDiagram
, uno::UNO_QUERY
);
229 Reference
< XTitle
> xSubTitle( xDiaTitled
->getTitleObject());
231 aTopLevelContainer
.push_back(
232 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle
, xModel
) ) );
235 if( !m_bOrderingForElementSelector
)
237 // Axis Titles. Note: These are interpreted of being top level
238 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
239 for( sal_Int32 i
=0; i
<aAxes
.getLength(); ++i
)
240 lcl_addAxisTitle( aAxes
[i
], aTopLevelContainer
, xModel
);
243 aTopLevelContainer
.push_back( aDiaOID
);
246 if( m_bFlattenDiagram
)
247 createDiagramTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
250 ObjectHierarchy::tChildContainer aSubContainer
;
251 createDiagramTree( aSubContainer
, xChartDocument
, xDiagram
);
252 if( !aSubContainer
.empty() )
253 m_aChildMap
[ aDiaOID
] = aSubContainer
;
256 if( !m_bOrderingForElementSelector
)
257 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
260 // #i12587# support for shapes in chart
261 if ( !m_bOrderingForElementSelector
)
263 createAdditionalShapesTree( aTopLevelContainer
);
267 if( !m_bOrderingForElementSelector
)
268 aTopLevelContainer
.push_back(
269 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) ) );
271 if( ! aTopLevelContainer
.empty())
272 m_aChildMap
[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer
;
275 void ImplObjectHierarchy::createLegendTree(
276 ObjectHierarchy::tChildContainer
& rContainer
,
277 const Reference
< XChartDocument
> & xChartDoc
,
278 const Reference
< XDiagram
> & xDiagram
)
280 if( xDiagram
.is() && LegendHelper::hasLegend( xDiagram
) )
282 ObjectHierarchy::tOID
aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
->getLegend(), Reference
< frame::XModel
>( xChartDoc
, uno::UNO_QUERY
) ) ) );
283 rContainer
.push_back( aLegendOID
);
285 // iterate over child shapes of legend and search for matching CIDs
286 if( m_pExplicitValueProvider
)
288 Reference
< container::XIndexAccess
> xLegendShapeContainer(
289 m_pExplicitValueProvider
->getShapeForCID( aLegendOID
.getObjectCID() ), uno::UNO_QUERY
);
290 ObjectHierarchy::tChildContainer aLegendEntryOIDs
;
291 lcl_getChildOIDs( aLegendEntryOIDs
, xLegendShapeContainer
);
293 m_aChildMap
[ aLegendOID
] = aLegendEntryOIDs
;
298 void ImplObjectHierarchy::createAxesTree(
299 ObjectHierarchy::tChildContainer
& rContainer
,
300 const Reference
< XChartDocument
> & xChartDoc
,
301 const Reference
< XDiagram
> & xDiagram
)
303 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
304 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
305 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
306 bool bSupportsAxesGrids
= ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimensionCount
, 0 );
307 if( bSupportsAxesGrids
)
309 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ true ) );
310 if( !m_bOrderingForElementSelector
)
311 ::std::transform( aAxes
.getConstArray(), aAxes
.getConstArray() + aAxes
.getLength(),
312 ::std::back_inserter( rContainer
),
313 lcl_ObjectToOID( xChartDoc
));
315 // get all axes, also invisible ones
316 aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ false );
318 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
319 for( sal_Int32 nA
=0; nA
<aAxes
.getLength(); ++nA
)
321 Reference
< XAxis
> xAxis( aAxes
[nA
] );
325 sal_Int32 nCooSysIndex
= 0;
326 sal_Int32 nDimensionIndex
= 0;
327 sal_Int32 nAxisIndex
= 0;
328 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
329 if( nAxisIndex
>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimensionCount
, nDimensionIndex
) )
332 if( m_bOrderingForElementSelector
)
335 if( AxisHelper::isAxisVisible( xAxis
) )
336 rContainer
.push_back(
337 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis
, xChartModel
) ) );
340 lcl_addAxisTitle( aAxes
[nA
], rContainer
, xChartModel
);
343 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
344 if( AxisHelper::isGridVisible( xGridProperties
) )
347 rContainer
.push_back(
348 ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
) ) ) );
351 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );;
352 sal_Int32 nSubGrid
= 0;
353 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
355 Reference
< beans::XPropertySet
> xSubGridProperties( aSubGrids
[nSubGrid
] );
356 if( AxisHelper::isGridVisible( xSubGridProperties
) )
359 rContainer
.push_back(
360 ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
, nSubGrid
) ) ) );
367 void ImplObjectHierarchy::createWallAndFloor(
368 ObjectHierarchy::tChildContainer
& rContainer
,
369 const Reference
< XDiagram
> & xDiagram
)
371 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
372 bool bIsThreeD
= ( nDimensionCount
== 3 );
373 bool bHasWall
= DiagramHelper::isSupportingFloorAndWall( xDiagram
);
374 if( bHasWall
&& bIsThreeD
)
376 rContainer
.push_back(
377 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, OUString() ) ) );
379 Reference
< beans::XPropertySet
> xFloor( xDiagram
->getFloor());
381 rContainer
.push_back(
382 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, OUString() ) ) );
387 void ImplObjectHierarchy::createDiagramTree(
388 ObjectHierarchy::tChildContainer
& rContainer
,
389 const Reference
< XChartDocument
> & xChartDoc
,
390 const Reference
< XDiagram
> & xDiagram
)
392 if( !m_bOrderingForElementSelector
)
394 createDataSeriesTree( rContainer
, xDiagram
);
395 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
396 createWallAndFloor( rContainer
, xDiagram
);
400 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
401 createDataSeriesTree( rContainer
, xDiagram
);
405 void ImplObjectHierarchy::createDataSeriesTree(
406 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
407 const Reference
< XDiagram
> & xDiagram
)
409 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
413 sal_Int32 nDiagramIndex
= 0;
414 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
415 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
416 xCooSysCnt
->getCoordinateSystems());
417 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
419 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
420 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
421 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypeSeq
.getLength(); ++nCTIdx
)
423 Reference
< XChartType
> xChartType( aChartTypeSeq
[nCTIdx
] );
424 Reference
< XDataSeriesContainer
> xDSCnt( xChartType
, uno::UNO_QUERY_THROW
);
425 Sequence
< Reference
< XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries() );
426 const sal_Int32 nNumberOfSeries
=
427 ChartTypeHelper::getNumberOfDisplayedSeries( xChartType
, aSeriesSeq
.getLength());
429 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<nNumberOfSeries
; ++nSeriesIdx
)
431 OUString
aSeriesParticle(
432 ObjectIdentifier::createParticleForSeries(
433 nDiagramIndex
, nCooSysIdx
, nCTIdx
, nSeriesIdx
));
434 ObjectHierarchy::tOID
aSeriesOID(
435 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle
) ) );
436 rOutDiagramSubContainer
.push_back( aSeriesOID
);
438 ObjectHierarchy::tChildContainer aSeriesSubContainer
;
440 Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
443 if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries
) )
445 OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS
) );
446 aChildParticle
+=("=");
447 aSeriesSubContainer
.push_back(
448 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle
, aChildParticle
) ) );
452 if( ChartTypeHelper::isSupportingStatisticProperties( xChartType
, nDimensionCount
) )
454 Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
457 Sequence
< Reference
< chart2::XRegressionCurve
> > aCurves( xCurveCnt
->getRegressionCurves());
458 for( sal_Int32 nCurveIdx
=0; nCurveIdx
<aCurves
.getLength(); ++nCurveIdx
)
460 bool bIsAverageLine
= RegressionCurveHelper::isMeanValueLine( aCurves
[nCurveIdx
] );
461 aSeriesSubContainer
.push_back(
462 ObjectIdentifier( ObjectIdentifier::createDataCurveCID( aSeriesParticle
, nCurveIdx
, bIsAverageLine
) ) );
463 if( RegressionCurveHelper::hasEquation( aCurves
[nCurveIdx
] ) )
465 aSeriesSubContainer
.push_back(
466 ObjectIdentifier( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle
, nCurveIdx
) ) );
469 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
470 Reference
< beans::XPropertySet
> xErrorBarProp
;
471 if( xSeriesProp
.is() &&
472 (xSeriesProp
->getPropertyValue( CHART_UNONAME_ERRORBAR_Y
) >>= xErrorBarProp
) &&
475 sal_Int32 nStyle
= ::com::sun::star::chart::ErrorBarStyle::NONE
;
476 if( ( xErrorBarProp
->getPropertyValue( "ErrorBarStyle") >>= nStyle
) &&
477 ( nStyle
!= ::com::sun::star::chart::ErrorBarStyle::NONE
) )
479 aSeriesSubContainer
.push_back(
480 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
481 OBJECTTYPE_DATA_ERRORS_Y
, OUString(), aSeriesParticle
) ) );
485 if( xSeriesProp
.is() &&
486 (xSeriesProp
->getPropertyValue(CHART_UNONAME_ERRORBAR_X
) >>= xErrorBarProp
) &&
489 sal_Int32 nStyle
= ::com::sun::star::chart::ErrorBarStyle::NONE
;
490 if( ( xErrorBarProp
->getPropertyValue( "ErrorBarStyle") >>= nStyle
) &&
491 ( nStyle
!= ::com::sun::star::chart::ErrorBarStyle::NONE
) )
493 aSeriesSubContainer
.push_back(
494 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
495 OBJECTTYPE_DATA_ERRORS_X
, OUString(), aSeriesParticle
) ) );
502 // iterate over child shapes of legend and search for matching CIDs
503 if( m_pExplicitValueProvider
)
505 Reference
< container::XIndexAccess
> xSeriesShapeContainer(
506 m_pExplicitValueProvider
->getShapeForCID( aSeriesOID
.getObjectCID() ), uno::UNO_QUERY
);
507 lcl_getChildOIDs( aSeriesSubContainer
, xSeriesShapeContainer
);
510 if( ! aSeriesSubContainer
.empty())
511 m_aChildMap
[ aSeriesOID
] = aSeriesSubContainer
;
516 catch( const uno::Exception
& ex
)
518 ASSERT_EXCEPTION( ex
);
522 void ImplObjectHierarchy::createAdditionalShapesTree( ObjectHierarchy::tChildContainer
& rContainer
)
526 if ( m_pExplicitValueProvider
)
528 Reference
< drawing::XDrawPage
> xDrawPage( m_pExplicitValueProvider
->getDrawModelWrapper()->getMainDrawPage() );
529 Reference
< drawing::XShapes
> xDrawPageShapes( xDrawPage
, uno::UNO_QUERY_THROW
);
530 Reference
< drawing::XShapes
> xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage
) );
531 sal_Int32 nCount
= xDrawPageShapes
->getCount();
532 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
534 Reference
< drawing::XShape
> xShape
;
535 if ( xDrawPageShapes
->getByIndex( i
) >>= xShape
)
537 if ( xShape
.is() && xShape
!= xChartRoot
)
539 rContainer
.push_back( ObjectIdentifier( xShape
) );
545 catch ( const uno::Exception
& ex
)
547 ASSERT_EXCEPTION( ex
);
551 bool ImplObjectHierarchy::hasChildren( const ObjectHierarchy::tOID
& rParent
)
553 if ( rParent
.isValid() )
555 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
556 if( aIt
!= m_aChildMap
.end())
557 return ! (aIt
->second
.empty());
562 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID
& rParent
)
564 if ( rParent
.isValid() )
566 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
567 if( aIt
!= m_aChildMap
.end())
570 return ObjectHierarchy::tChildContainer();
573 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getSiblings( const ObjectHierarchy::tOID
& rNode
)
575 if ( rNode
.isValid() && !ObjectHierarchy::isRootNode( rNode
) )
577 for( tChildMap::const_iterator
aIt( m_aChildMap
.begin());
578 aIt
!= m_aChildMap
.end(); ++aIt
)
580 ObjectHierarchy::tChildContainer::const_iterator
aElemIt(
581 ::std::find( aIt
->second
.begin(), aIt
->second
.end(), rNode
));
582 if( aElemIt
!= aIt
->second
.end())
586 return ObjectHierarchy::tChildContainer();
589 ObjectHierarchy::tOID
ImplObjectHierarchy::getParentImpl(
590 const ObjectHierarchy::tOID
& rParentOID
,
591 const ObjectHierarchy::tOID
& rOID
)
594 ObjectHierarchy::tChildContainer
aChildren( getChildren( rParentOID
));
595 ObjectHierarchy::tChildContainer::const_iterator
aIt(
596 ::std::find( aChildren
.begin(), aChildren
.end(), rOID
));
598 if( aIt
!= aChildren
.end())
601 for( aIt
= aChildren
.begin(); aIt
!= aChildren
.end(); ++aIt
)
604 ObjectHierarchy::tOID
aTempParent( getParentImpl( *aIt
, rOID
));
605 if ( aTempParent
.isValid() )
613 return ObjectHierarchy::tOID();
616 ObjectHierarchy::tOID
ImplObjectHierarchy::getParent(
617 const ObjectHierarchy::tOID
& rOID
)
619 return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID
);
624 ObjectHierarchy::ObjectHierarchy(
625 const Reference
< XChartDocument
> & xChartDocument
,
626 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */,
627 bool bFlattenDiagram
/* = false */,
628 bool bOrderingForElementSelector
/* = false */) :
629 m_apImpl( new impl::ImplObjectHierarchy( xChartDocument
, pExplicitValueProvider
, bFlattenDiagram
, bOrderingForElementSelector
))
632 ObjectHierarchy::~ObjectHierarchy()
635 ObjectHierarchy::tOID
ObjectHierarchy::getRootNodeOID()
637 return ObjectIdentifier( "ROOT" );
640 bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID
& rOID
)
642 return ( rOID
== ObjectHierarchy::getRootNodeOID() );
645 ObjectHierarchy::tChildContainer
ObjectHierarchy::getTopLevelChildren() const
647 return m_apImpl
->getChildren( ObjectHierarchy::getRootNodeOID());
650 bool ObjectHierarchy::hasChildren( const tOID
& rParent
) const
652 return m_apImpl
->hasChildren( rParent
);
655 ObjectHierarchy::tChildContainer
ObjectHierarchy::getChildren(
656 const ObjectHierarchy::tOID
& rParent
) const
658 if ( rParent
.isValid() )
659 return m_apImpl
->getChildren( rParent
);
661 return ObjectHierarchy::tChildContainer();
664 ObjectHierarchy::tChildContainer
ObjectHierarchy::getSiblings(
665 const ObjectHierarchy::tOID
& rNode
) const
667 if ( rNode
.isValid() && !isRootNode( rNode
) )
668 return m_apImpl
->getSiblings( rNode
);
670 return ObjectHierarchy::tChildContainer();
673 ObjectHierarchy::tOID
ObjectHierarchy::getParent(
674 const ObjectHierarchy::tOID
& rNode
) const
676 return m_apImpl
->getParent( rNode
);
679 sal_Int32
ObjectHierarchy::getIndexInParent(
680 const ObjectHierarchy::tOID
& rNode
) const
682 tOID
aParentOID( m_apImpl
->getParent( rNode
));
683 tChildContainer
aChildren( m_apImpl
->getChildren( aParentOID
) );
684 tChildContainer::const_iterator
aIt( aChildren
.begin() );
685 for( sal_Int32 nIndex
= 0; aIt
!= aChildren
.end(); ++nIndex
, ++aIt
)
693 ObjectKeyNavigation::ObjectKeyNavigation(
694 const ObjectHierarchy::tOID
& rCurrentOID
,
695 const Reference
< chart2::XChartDocument
> & xChartDocument
,
696 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */ ) :
697 m_aCurrentOID( rCurrentOID
),
698 m_xChartDocument( xChartDocument
),
699 m_pExplicitValueProvider( pExplicitValueProvider
),
700 m_bStepDownInDiagram( true )
702 if ( !m_aCurrentOID
.isValid() )
704 setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
708 bool ObjectKeyNavigation::handleKeyEvent(
709 const awt::KeyEvent
& rEvent
)
711 bool bResult
= false;
713 switch( rEvent
.KeyCode
)
716 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
717 bResult
= previous();
728 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
733 case awt::Key::ESCAPE
:
734 setCurrentSelection( ObjectIdentifier() );
744 void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID
& rOID
)
746 m_aCurrentOID
= rOID
;
749 bool ObjectKeyNavigation::first()
751 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
752 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
753 bool bResult
= !aSiblings
.empty();
755 setCurrentSelection( aSiblings
.front());
757 bResult
= veryFirst();
761 bool ObjectKeyNavigation::last()
763 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
764 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
765 bool bResult
= !aSiblings
.empty();
767 setCurrentSelection( aSiblings
.back());
769 bResult
= veryLast();
773 bool ObjectKeyNavigation::next()
775 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
776 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
777 bool bResult
= !aSiblings
.empty();
780 ObjectHierarchy::tChildContainer::const_iterator
aIt(
781 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
782 OSL_ASSERT( aIt
!= aSiblings
.end());
783 if( ++aIt
== aSiblings
.end())
784 aIt
= aSiblings
.begin();
785 setCurrentSelection( *aIt
);
788 bResult
= veryFirst();
793 bool ObjectKeyNavigation::previous()
795 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
796 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
797 bool bResult
= !aSiblings
.empty();
800 ObjectHierarchy::tChildContainer::const_iterator
aIt(
801 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
802 OSL_ASSERT( aIt
!= aSiblings
.end());
803 if( aIt
== aSiblings
.begin())
804 aIt
= aSiblings
.end();
806 setCurrentSelection( *aIt
);
809 bResult
= veryLast();
813 bool ObjectKeyNavigation::up()
815 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
816 bool bResult
= !ObjectHierarchy::isRootNode( getCurrentSelection());
818 setCurrentSelection( aHierarchy
.getParent( getCurrentSelection()));
822 bool ObjectKeyNavigation::down()
824 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
825 bool bResult
= aHierarchy
.hasChildren( getCurrentSelection());
828 ObjectHierarchy::tChildContainer aChildren
= aHierarchy
.getChildren( getCurrentSelection());
829 OSL_ASSERT( !aChildren
.empty());
830 setCurrentSelection( aChildren
.front());
835 bool ObjectKeyNavigation::veryFirst()
837 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
838 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
839 bool bResult
= !aChildren
.empty();
841 setCurrentSelection( aChildren
.front());
845 bool ObjectKeyNavigation::veryLast()
847 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
848 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
849 bool bResult
= !aChildren
.empty();
851 setCurrentSelection( aChildren
.back());
857 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */