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 <Diagram.hxx>
23 #include <RegressionCurveHelper.hxx>
24 #include <RegressionCurveModel.hxx>
26 #include <AxisHelper.hxx>
27 #include <chartview/ExplicitValueProvider.hxx>
28 #include <ChartType.hxx>
29 #include <ChartTypeHelper.hxx>
30 #include <ChartModel.hxx>
31 #include <DataSeries.hxx>
32 #include <DataSeriesHelper.hxx>
33 #include <GridProperties.hxx>
34 #include <LegendHelper.hxx>
35 #include <chartview/DrawModelWrapper.hxx>
36 #include <unonames.hxx>
37 #include <BaseCoordinateSystem.hxx>
43 #include <com/sun/star/drawing/XShapes.hpp>
44 #include <com/sun/star/chart/ErrorBarStyle.hpp>
46 #include <com/sun/star/container/XIndexAccess.hpp>
47 #include <com/sun/star/awt/Key.hpp>
48 #include <com/sun/star/awt/KeyModifier.hpp>
50 #include <comphelper/diagnose_ex.hxx>
52 using namespace ::com::sun::star
;
53 using namespace ::com::sun::star::chart2
;
55 using ::com::sun::star::uno::Reference
;
60 void lcl_getChildOIDs(
61 ::chart::ObjectHierarchy::tChildContainer
& rOutChildren
,
62 const Reference
< container::XIndexAccess
>& xShapes
)
67 sal_Int32 nCount
= xShapes
->getCount();
68 for( sal_Int32 i
=0; i
<nCount
; ++i
)
70 Reference
< beans::XPropertySet
> xShapeProp( xShapes
->getByIndex( i
), uno::UNO_QUERY
);
73 Reference
< beans::XPropertySetInfo
> xInfo( xShapeProp
->getPropertySetInfo());
76 xInfo
->hasPropertyByName( u
"Name"_ustr
) &&
77 (xShapeProp
->getPropertyValue( u
"Name"_ustr
) >>= aName
) &&
79 ::chart::ObjectIdentifier::isCID( aName
))
81 rOutChildren
.emplace_back( aName
);
83 Reference
< container::XIndexAccess
> xNewShapes( xShapeProp
, uno::UNO_QUERY
);
85 lcl_getChildOIDs( rOutChildren
, xNewShapes
);
90 void lcl_addAxisTitle( const rtl::Reference
< ::chart::Axis
>& xAxis
, ::chart::ObjectHierarchy::tChildContainer
& rContainer
, const rtl::Reference
<::chart::ChartModel
>& xChartModel
)
94 Reference
< XTitle
> xAxisTitle( xAxis
->getTitleObject());
96 rContainer
.emplace_back( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle
, xChartModel
) );
100 } // anonymous namespace
105 void ObjectHierarchy::createTree( const rtl::Reference
<::chart::ChartModel
>& xChartDocument
)
109 if( !xChartDocument
.is() )
112 //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
113 rtl::Reference
< Diagram
> xDiagram
= xChartDocument
->getFirstChartDiagram();
114 ObjectIdentifier aDiaOID
;
116 aDiaOID
= ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( static_cast<cppu::OWeakObject
*>(xDiagram
.get()), xChartDocument
) );
117 tChildContainer aTopLevelContainer
;
122 if( m_bOrderingForElementSelector
)
124 aTopLevelContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, u
"" ) );
127 aTopLevelContainer
.push_back( aDiaOID
);
128 createWallAndFloor( aTopLevelContainer
, xDiagram
);
129 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
134 Reference
< XTitle
> xMainTitle( xChartDocument
->getTitleObject());
136 aTopLevelContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle
, xChartDocument
) );
140 // Sub Title. Note: This is interpreted of being top level
141 Reference
< XTitle
> xSubTitle( xDiagram
->getTitleObject());
143 aTopLevelContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle
, xChartDocument
) );
145 if( !m_bOrderingForElementSelector
)
147 // Axis Titles. Note: These are interpreted of being top level
148 const std::vector
< rtl::Reference
< Axis
> > aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
);
149 for( rtl::Reference
< Axis
> const & axis
: aAxes
)
150 lcl_addAxisTitle( axis
, aTopLevelContainer
, xChartDocument
);
153 aTopLevelContainer
.push_back( aDiaOID
);
156 if( m_bFlattenDiagram
)
157 createDiagramTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
160 tChildContainer aSubContainer
;
161 createDiagramTree( aSubContainer
, xChartDocument
, xDiagram
);
162 if( !aSubContainer
.empty() )
163 m_aChildMap
[ aDiaOID
] = std::move(aSubContainer
);
166 if( !m_bOrderingForElementSelector
)
167 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
170 // #i12587# support for shapes in chart
171 if ( !m_bOrderingForElementSelector
)
173 createAdditionalShapesTree( aTopLevelContainer
);
177 if( !m_bOrderingForElementSelector
)
178 aTopLevelContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, u
"" ) );
180 if( ! aTopLevelContainer
.empty())
181 m_aChildMap
[ObjectHierarchy::getRootNodeOID()] = std::move(aTopLevelContainer
);
184 void ObjectHierarchy::createLegendTree(
185 tChildContainer
& rContainer
,
186 const rtl::Reference
<::chart::ChartModel
> & xChartDoc
,
187 const rtl::Reference
< Diagram
> & xDiagram
)
189 if( !(xDiagram
.is() && LegendHelper::hasLegend( xDiagram
)) )
192 ObjectIdentifier
aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
->getLegend(), xChartDoc
) ) );
193 rContainer
.push_back( aLegendOID
);
195 // iterate over child shapes of legend and search for matching CIDs
196 if( m_pExplicitValueProvider
)
198 rtl::Reference
< SvxShapeGroupAnyD
> xLegendShapeContainer
=
199 dynamic_cast<SvxShapeGroupAnyD
*>(
200 m_pExplicitValueProvider
->getShapeForCID( aLegendOID
.getObjectCID() ).get() );
201 tChildContainer aLegendEntryOIDs
;
202 lcl_getChildOIDs( aLegendEntryOIDs
, xLegendShapeContainer
);
204 m_aChildMap
[aLegendOID
] = std::move(aLegendEntryOIDs
);
208 void ObjectHierarchy::createAxesTree(
209 tChildContainer
& rContainer
,
210 const rtl::Reference
<::chart::ChartModel
> & xChartDoc
,
211 const rtl::Reference
< Diagram
> & xDiagram
)
213 sal_Int32 nDimensionCount
= xDiagram
->getDimension();
214 rtl::Reference
< ChartType
> xChartType( xDiagram
->getChartTypeByIndex( 0 ) );
215 bool bSupportsAxesGrids
= ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimensionCount
, 0 );
216 if( !bSupportsAxesGrids
)
220 uno::Reference
<chart2::XDataTable
> xDataTable
= xDiagram
->getDataTable();
223 rContainer
.push_back(ObjectIdentifier::createClassifiedIdentifierForObject(xDataTable
, xChartDoc
));
227 std::vector
< rtl::Reference
< Axis
> > aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ true );
228 if( !m_bOrderingForElementSelector
)
230 for (const auto& rAxis
: aAxes
)
231 rContainer
.push_back( ObjectIdentifier::createClassifiedIdentifierForObject( rAxis
, xChartDoc
) );
234 // get all axes, also invisible ones
235 aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
);
237 for( rtl::Reference
< Axis
> const & xAxis
: aAxes
)
242 sal_Int32 nCooSysIndex
= 0;
243 sal_Int32 nDimensionIndex
= 0;
244 sal_Int32 nAxisIndex
= 0;
245 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
246 if( nAxisIndex
>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimensionCount
) )
249 if( m_bOrderingForElementSelector
)
252 if( AxisHelper::isAxisVisible( xAxis
) )
253 rContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis
, xChartDoc
) );
256 lcl_addAxisTitle( xAxis
, rContainer
, xChartDoc
);
259 rtl::Reference
< ::chart::GridProperties
> xGridProperties( xAxis
->getGridProperties2() );
260 if( AxisHelper::isGridVisible( xGridProperties
) )
263 rContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartDoc
) );
266 std::vector
< rtl::Reference
< ::chart::GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
267 for( size_t nSubGrid
= 0; nSubGrid
< aSubGrids
.size(); ++nSubGrid
)
269 if( AxisHelper::isGridVisible( aSubGrids
[nSubGrid
] ) )
272 rContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartDoc
, nSubGrid
) );
278 void ObjectHierarchy::createWallAndFloor(
279 tChildContainer
& rContainer
,
280 const rtl::Reference
< Diagram
> & xDiagram
)
282 sal_Int32 nDimensionCount
= xDiagram
->getDimension();
283 bool bIsThreeD
= ( nDimensionCount
== 3 );
284 bool bHasWall
= xDiagram
->isSupportingFloorAndWall();
285 if( bHasWall
&& bIsThreeD
)
287 rContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, u
"" ) );
289 Reference
< beans::XPropertySet
> xFloor( xDiagram
->getFloor());
291 rContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, u
"" ) );
296 void ObjectHierarchy::createDiagramTree(
297 tChildContainer
& rContainer
,
298 const rtl::Reference
<::chart::ChartModel
> & xChartDoc
,
299 const rtl::Reference
< Diagram
> & xDiagram
)
301 if( !m_bOrderingForElementSelector
)
303 createDataSeriesTree( rContainer
, xDiagram
);
304 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
305 createWallAndFloor( rContainer
, xDiagram
);
309 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
310 createDataSeriesTree( rContainer
, xDiagram
);
314 void ObjectHierarchy::createDataSeriesTree(
315 tChildContainer
& rOutDiagramSubContainer
,
316 const rtl::Reference
< Diagram
> & xDiagram
)
320 sal_Int32 nDimensionCount
= xDiagram
->getDimension();
321 std::vector
< rtl::Reference
< BaseCoordinateSystem
> > aCooSysSeq(
322 xDiagram
->getBaseCoordinateSystems());
323 for( std::size_t nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.size(); ++nCooSysIdx
)
325 std::vector
< rtl::Reference
< ChartType
> > aChartTypeSeq( aCooSysSeq
[nCooSysIdx
]->getChartTypes2());
326 for( std::size_t nCTIdx
=0; nCTIdx
<aChartTypeSeq
.size(); ++nCTIdx
)
328 const rtl::Reference
< ChartType
>& xChartType( aChartTypeSeq
[nCTIdx
] );
329 std::vector
< rtl::Reference
< DataSeries
> > aSeriesSeq( xChartType
->getDataSeries2() );
330 const sal_Int32 nNumberOfSeries
=
331 ChartTypeHelper::getNumberOfDisplayedSeries( xChartType
, aSeriesSeq
.size());
333 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<nNumberOfSeries
; ++nSeriesIdx
)
335 OUString
aSeriesParticle(
336 ObjectIdentifier::createParticleForSeries(
337 0, nCooSysIdx
, nCTIdx
, nSeriesIdx
));
338 ObjectIdentifier
aSeriesOID(
339 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle
) ) );
340 rOutDiagramSubContainer
.push_back( aSeriesOID
);
342 tChildContainer aSeriesSubContainer
;
344 rtl::Reference
< DataSeries
> const & xSeries
= aSeriesSeq
[nSeriesIdx
];
347 if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries
) )
349 OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS
) + "=" );
350 aSeriesSubContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle
, aChildParticle
) );
354 if( ChartTypeHelper::isSupportingStatisticProperties( xChartType
, nDimensionCount
) )
356 const std::vector
< rtl::Reference
< RegressionCurveModel
> > & rCurves( xSeries
->getRegressionCurves2());
357 for( size_t nCurveIdx
=0; nCurveIdx
<rCurves
.size(); ++nCurveIdx
)
359 bool bIsAverageLine
= RegressionCurveHelper::isMeanValueLine( rCurves
[nCurveIdx
] );
360 aSeriesSubContainer
.emplace_back( ObjectIdentifier::createDataCurveCID( aSeriesParticle
, nCurveIdx
, bIsAverageLine
) );
361 if( RegressionCurveHelper::hasEquation( rCurves
[nCurveIdx
] ) )
363 aSeriesSubContainer
.emplace_back( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle
, nCurveIdx
) );
366 Reference
< beans::XPropertySet
> xErrorBarProp
;
367 if( (xSeries
->getPropertyValue( CHART_UNONAME_ERRORBAR_Y
) >>= xErrorBarProp
) &&
370 sal_Int32 nStyle
= css::chart::ErrorBarStyle::NONE
;
371 if( ( xErrorBarProp
->getPropertyValue( u
"ErrorBarStyle"_ustr
) >>= nStyle
) &&
372 ( nStyle
!= css::chart::ErrorBarStyle::NONE
) )
374 aSeriesSubContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierWithParent(
375 OBJECTTYPE_DATA_ERRORS_Y
, u
"", aSeriesParticle
) );
379 if( (xSeries
->getPropertyValue(CHART_UNONAME_ERRORBAR_X
) >>= xErrorBarProp
) &&
382 sal_Int32 nStyle
= css::chart::ErrorBarStyle::NONE
;
383 if( ( xErrorBarProp
->getPropertyValue( u
"ErrorBarStyle"_ustr
) >>= nStyle
) &&
384 ( nStyle
!= css::chart::ErrorBarStyle::NONE
) )
386 aSeriesSubContainer
.emplace_back( ObjectIdentifier::createClassifiedIdentifierWithParent(
387 OBJECTTYPE_DATA_ERRORS_X
, u
"", aSeriesParticle
) );
393 // iterate over child shapes of legend and search for matching CIDs
394 if( m_pExplicitValueProvider
)
396 rtl::Reference
< SvxShapeGroupAnyD
> xSeriesShapeContainer
=
397 dynamic_cast<SvxShapeGroupAnyD
*>(
398 m_pExplicitValueProvider
->getShapeForCID( aSeriesOID
.getObjectCID() ).get() );
399 lcl_getChildOIDs( aSeriesSubContainer
, xSeriesShapeContainer
);
402 if( ! aSeriesSubContainer
.empty())
403 m_aChildMap
[ aSeriesOID
] = std::move(aSeriesSubContainer
);
408 catch( const uno::Exception
& )
410 DBG_UNHANDLED_EXCEPTION("chart2");
414 void ObjectHierarchy::createAdditionalShapesTree(tChildContainer
& rContainer
)
418 if ( m_pExplicitValueProvider
)
420 rtl::Reference
<SvxDrawPage
> xDrawPage( m_pExplicitValueProvider
->getDrawModelWrapper()->getMainDrawPage() );
421 Reference
< drawing::XShapes
> xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage
) );
422 sal_Int32 nCount
= xDrawPage
->getCount();
423 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
425 Reference
< drawing::XShape
> xShape
;
426 if ( xDrawPage
->getByIndex( i
) >>= xShape
)
428 if ( xShape
.is() && xShape
!= xChartRoot
)
430 rContainer
.emplace_back( xShape
);
436 catch ( const uno::Exception
& )
438 DBG_UNHANDLED_EXCEPTION("chart2");
442 bool ObjectHierarchy::hasChildren( const ObjectIdentifier
& rParent
) const
444 if ( rParent
.isValid() )
446 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
447 if( aIt
!= m_aChildMap
.end())
448 return ! (aIt
->second
.empty());
453 const ObjectHierarchy::tChildContainer
& ObjectHierarchy::getChildren( const ObjectIdentifier
& rParent
) const
455 if ( rParent
.isValid() )
457 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
458 if( aIt
!= m_aChildMap
.end())
461 static const tChildContainer EMPTY
;
465 const ObjectHierarchy::tChildContainer
& ObjectHierarchy::getSiblings( const ObjectIdentifier
& rNode
) const
467 if ( rNode
.isValid() && !ObjectHierarchy::isRootNode( rNode
) )
469 for (auto const& child
: m_aChildMap
)
471 tChildContainer::const_iterator
aElemIt(
472 std::find( child
.second
.begin(), child
.second
.end(), rNode
));
473 if( aElemIt
!= child
.second
.end())
477 static const tChildContainer EMPTY
;
481 ObjectIdentifier
ObjectHierarchy::getParentImpl(
482 const ObjectIdentifier
& rParentOID
,
483 const ObjectIdentifier
& rOID
) const
486 tChildContainer
aChildren( getChildren( rParentOID
));
487 tChildContainer::const_iterator
aIt(
488 std::find( aChildren
.begin(), aChildren
.end(), rOID
));
490 if( aIt
!= aChildren
.end())
493 for (auto const& child
: aChildren
)
496 ObjectIdentifier
aTempParent( getParentImpl( child
, rOID
));
497 if ( aTempParent
.isValid() )
505 return ObjectIdentifier();
508 ObjectIdentifier
ObjectHierarchy::getParent(
509 const ObjectIdentifier
& rOID
) const
511 return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID
);
514 ObjectHierarchy::ObjectHierarchy(
515 const rtl::Reference
<::chart::ChartModel
> & xChartDocument
,
516 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */,
517 bool bFlattenDiagram
/* = false */,
518 bool bOrderingForElementSelector
/* = false */) :
519 m_pExplicitValueProvider( pExplicitValueProvider
),
520 m_bFlattenDiagram( bFlattenDiagram
),
521 m_bOrderingForElementSelector( bOrderingForElementSelector
)
523 createTree( xChartDocument
);
524 // don't remember this helper to avoid access after lifetime
525 m_pExplicitValueProvider
= nullptr;
528 ObjectHierarchy::~ObjectHierarchy()
531 ObjectIdentifier
ObjectHierarchy::getRootNodeOID()
533 return ObjectIdentifier( u
"ROOT"_ustr
);
536 bool ObjectHierarchy::isRootNode( const ObjectIdentifier
& rOID
)
538 return ( rOID
== ObjectHierarchy::getRootNodeOID() );
541 const ObjectHierarchy::tChildContainer
& ObjectHierarchy::getTopLevelChildren() const
543 return getChildren( ObjectHierarchy::getRootNodeOID());
546 sal_Int32
ObjectHierarchy::getIndexInParent(
547 const ObjectIdentifier
& rNode
) const
549 ObjectIdentifier
aParentOID( getParent( rNode
));
550 const tChildContainer
& aChildren( getChildren( aParentOID
) );
551 sal_Int32 nIndex
= 0;
552 for (auto const& child
: aChildren
)
554 if ( child
== rNode
)
561 ObjectKeyNavigation::ObjectKeyNavigation(
562 ObjectIdentifier aCurrentOID
,
563 rtl::Reference
<::chart::ChartModel
> xChartDocument
,
564 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */ ) :
565 m_aCurrentOID(std::move( aCurrentOID
)),
566 m_xChartDocument(std::move( xChartDocument
)),
567 m_pExplicitValueProvider( pExplicitValueProvider
)
569 if ( !m_aCurrentOID
.isValid() )
571 setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
575 bool ObjectKeyNavigation::handleKeyEvent(
576 const awt::KeyEvent
& rEvent
)
578 bool bResult
= false;
580 switch( rEvent
.KeyCode
)
583 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
584 bResult
= previous();
595 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
600 case awt::Key::ESCAPE
:
601 setCurrentSelection( ObjectIdentifier() );
611 void ObjectKeyNavigation::setCurrentSelection( const ObjectIdentifier
& rOID
)
613 m_aCurrentOID
= rOID
;
616 bool ObjectKeyNavigation::first()
618 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
619 const ObjectHierarchy::tChildContainer
& aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
620 bool bResult
= !aSiblings
.empty();
622 setCurrentSelection( aSiblings
.front());
624 bResult
= veryFirst();
628 bool ObjectKeyNavigation::last()
630 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
631 const ObjectHierarchy::tChildContainer
& aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
632 bool bResult
= !aSiblings
.empty();
634 setCurrentSelection( aSiblings
.back());
636 bResult
= veryLast();
640 bool ObjectKeyNavigation::next()
642 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
643 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
644 bool bResult
= !aSiblings
.empty();
647 ObjectHierarchy::tChildContainer::const_iterator
aIt(
648 std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
649 assert(aIt
!= aSiblings
.end());
650 if( ++aIt
== aSiblings
.end())
651 aIt
= aSiblings
.begin();
652 setCurrentSelection( *aIt
);
655 bResult
= veryFirst();
660 bool ObjectKeyNavigation::previous()
662 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
663 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
664 bool bResult
= !aSiblings
.empty();
667 ObjectHierarchy::tChildContainer::const_iterator
aIt(
668 std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
669 OSL_ASSERT( aIt
!= aSiblings
.end());
670 if( aIt
== aSiblings
.begin())
671 aIt
= aSiblings
.end();
673 setCurrentSelection( *aIt
);
676 bResult
= veryLast();
680 bool ObjectKeyNavigation::up()
682 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
683 bool bResult
= !ObjectHierarchy::isRootNode( getCurrentSelection());
685 setCurrentSelection( aHierarchy
.getParent( getCurrentSelection()));
689 bool ObjectKeyNavigation::down()
691 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
692 bool bResult
= aHierarchy
.hasChildren( getCurrentSelection());
695 const ObjectHierarchy::tChildContainer
& aChildren
= aHierarchy
.getChildren( getCurrentSelection());
696 OSL_ASSERT( !aChildren
.empty());
697 setCurrentSelection( aChildren
.front());
702 bool ObjectKeyNavigation::veryFirst()
704 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
705 const ObjectHierarchy::tChildContainer
& aChildren( aHierarchy
.getTopLevelChildren());
706 bool bResult
= !aChildren
.empty();
708 setCurrentSelection( aChildren
.front());
712 bool ObjectKeyNavigation::veryLast()
714 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
);
715 const ObjectHierarchy::tChildContainer
& aChildren( aHierarchy
.getTopLevelChildren());
716 bool bResult
= !aChildren
.empty();
718 setCurrentSelection( aChildren
.back());
724 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */