1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ObjectHierarchy.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "ObjectHierarchy.hxx"
35 #include "ObjectIdentifier.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "DiagramHelper.hxx"
38 #include "RegressionCurveHelper.hxx"
39 #include "AxisHelper.hxx"
40 #include "chartview/ExplicitValueProvider.hxx"
42 #include "LineProperties.hxx"
43 #include "ChartTypeHelper.hxx"
44 #include "DataSeriesHelper.hxx"
45 #include "LegendHelper.hxx"
50 #include <com/sun/star/chart2/XTitled.hpp>
51 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
52 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
53 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
54 #include <com/sun/star/chart/ErrorBarStyle.hpp>
56 #include <com/sun/star/container/XIndexAccess.hpp>
57 #include <com/sun/star/awt/Key.hpp>
58 #include <com/sun/star/awt/KeyModifier.hpp>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::chart2
;
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::Sequence
;
65 using ::rtl::OUString
;
69 struct lcl_ObjectToCID
: public ::std::unary_function
< Reference
< uno::XInterface
>, OUString
>
71 explicit lcl_ObjectToCID( const Reference
< chart2::XChartDocument
> & xChartDoc
) :
72 m_xModel( xChartDoc
, uno::UNO_QUERY
)
75 OUString
operator() ( const Reference
< uno::XInterface
> & xObj
)
77 return ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj
, m_xModel
);
81 Reference
< frame::XModel
> m_xModel
;
84 void lcl_getChildCIDs(
85 ::chart::ObjectHierarchy::tChildContainer
& rOutChildren
,
86 const Reference
< container::XIndexAccess
> & xShapes
)
90 sal_Int32 nCount
= xShapes
->getCount();
91 for( sal_Int32 i
=0; i
<nCount
; ++i
)
93 Reference
< beans::XPropertySet
> xShapeProp( xShapes
->getByIndex( i
), uno::UNO_QUERY
);
96 Reference
< beans::XPropertySetInfo
> xInfo( xShapeProp
->getPropertySetInfo());
99 xInfo
->hasPropertyByName( C2U("Name")) &&
100 (xShapeProp
->getPropertyValue( C2U("Name")) >>= aName
) &&
101 aName
.getLength() > 0 &&
102 ::chart::ObjectIdentifier::isCID( aName
))
104 rOutChildren
.push_back( aName
);
106 Reference
< container::XIndexAccess
> xNewShapes( xShapeProp
, uno::UNO_QUERY
);
108 lcl_getChildCIDs( rOutChildren
, xNewShapes
);
114 void lcl_addAxisTitle( const Reference
< XAxis
>& xAxis
, ::chart::ObjectHierarchy::tChildContainer
& rContainer
, const Reference
< frame::XModel
>& xChartModel
)
116 Reference
< XTitled
> xAxisTitled( xAxis
, uno::UNO_QUERY
);
117 if( xAxisTitled
.is())
119 Reference
< XTitle
> xAxisTitle( xAxisTitled
->getTitleObject());
121 rContainer
.push_back(
122 ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle
, xChartModel
));
126 } // anonymous namespace
134 class ImplObjectHierarchy
137 explicit ImplObjectHierarchy(
138 const Reference
< XChartDocument
> & xChartDocument
,
139 ExplicitValueProvider
* pExplicitValueProvider
,
140 bool bFlattenDiagram
, bool bOrderingForElementSelector
);
142 bool hasChildren( const OUString
& rParent
);
143 ObjectHierarchy::tChildContainer
getChildren( const OUString
& rParent
);
144 ObjectHierarchy::tChildContainer
getSiblings( const OUString
& rNode
);
146 ObjectHierarchy::tCID
getParent( const ObjectHierarchy::tCID
& rCID
);
149 void createTree( const Reference
< XChartDocument
> & xChartDocument
);
151 ObjectHierarchy::tChildContainer
& rContainer
,
152 const Reference
< XChartDocument
> & xChartDoc
,
153 const Reference
< XDiagram
> & xDiagram
);
154 void createDiagramTree(
155 ObjectHierarchy::tChildContainer
& rContainer
,
156 const Reference
< XChartDocument
> & xChartDoc
,
157 const Reference
< XDiagram
> & xDiagram
);
158 void createDataSeriesTree(
159 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
160 const Reference
< XDiagram
> & xDiagram
);
161 void createWallAndFloor(
162 ObjectHierarchy::tChildContainer
& rContainer
,
163 const Reference
< XDiagram
> & xDiagram
);
164 void createLegendTree(
165 ObjectHierarchy::tChildContainer
& rContainer
,
166 const Reference
< XChartDocument
> & xChartDoc
,
167 const Reference
< XDiagram
> & xDiagram
);
169 ObjectHierarchy::tCID
getParentImpl(
170 const ObjectHierarchy::tCID
& rParentCID
,
171 const ObjectHierarchy::tCID
& rCID
);
173 typedef ::std::map
< OUString
, ObjectHierarchy::tChildContainer
>
175 tChildMap m_aChildMap
;
176 ExplicitValueProvider
* m_pExplicitValueProvider
;
177 bool m_bFlattenDiagram
;
178 bool m_bOrderingForElementSelector
;
181 ImplObjectHierarchy::ImplObjectHierarchy(
182 const Reference
< XChartDocument
> & xChartDocument
,
183 ExplicitValueProvider
* pExplicitValueProvider
,
184 bool bFlattenDiagram
,
185 bool bOrderingForElementSelector
) :
186 m_pExplicitValueProvider( pExplicitValueProvider
),
187 m_bFlattenDiagram( bFlattenDiagram
),
188 m_bOrderingForElementSelector( bOrderingForElementSelector
)
190 createTree( xChartDocument
);
191 // don't remember this helper to avoid access after lifetime
192 m_pExplicitValueProvider
= 0;
195 void ImplObjectHierarchy::createTree( const Reference
< XChartDocument
> & xChartDocument
)
197 if( !xChartDocument
.is())
200 //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
201 Reference
< frame::XModel
> xModel( xChartDocument
, uno::UNO_QUERY
);
202 Reference
< XDiagram
> xDiagram( ChartModelHelper::findDiagram( xChartDocument
) );
203 OUString
aDiaCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
, xModel
));
204 ObjectHierarchy::tChildContainer aTopLevelContainer
;
209 if( m_bOrderingForElementSelector
)
211 aTopLevelContainer
.push_back( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) );
212 aTopLevelContainer
.push_back( aDiaCID
);
213 createWallAndFloor( aTopLevelContainer
, xDiagram
);
214 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
218 Reference
< XTitled
> xDocTitled( xChartDocument
, uno::UNO_QUERY
);
221 Reference
< XTitle
> xMainTitle( xDocTitled
->getTitleObject());
223 aTopLevelContainer
.push_back(
224 ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle
, xModel
));
229 // Sub Title. Note: This is interpreted of being top level
230 Reference
< XTitled
> xDiaTitled( xDiagram
, uno::UNO_QUERY
);
233 Reference
< XTitle
> xSubTitle( xDiaTitled
->getTitleObject());
235 aTopLevelContainer
.push_back(
236 ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle
, xModel
));
239 if( !m_bOrderingForElementSelector
)
241 // Axis Titles. Note: These are interpreted of being top level
242 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
243 for( sal_Int32 i
=0; i
<aAxes
.getLength(); ++i
)
244 lcl_addAxisTitle( aAxes
[i
], aTopLevelContainer
, xModel
);
247 aTopLevelContainer
.push_back( aDiaCID
);
250 if( m_bFlattenDiagram
)
251 createDiagramTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
254 ObjectHierarchy::tChildContainer aSubContainer
;
255 createDiagramTree( aSubContainer
, xChartDocument
, xDiagram
);
256 if( ! aSubContainer
.empty())
257 m_aChildMap
[ aDiaCID
] = aSubContainer
;
260 if( !m_bOrderingForElementSelector
)
261 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
265 if( !m_bOrderingForElementSelector
)
266 aTopLevelContainer
.push_back(
267 ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) );
269 if( ! aTopLevelContainer
.empty())
270 m_aChildMap
[ ObjectHierarchy::getRootNodeCID() ] = aTopLevelContainer
;
273 void ImplObjectHierarchy::createLegendTree(
274 ObjectHierarchy::tChildContainer
& rContainer
,
275 const Reference
< XChartDocument
> & xChartDoc
,
276 const Reference
< XDiagram
> & xDiagram
)
278 if( xDiagram
.is() && LegendHelper::hasLegend( xDiagram
) )
280 OUString
aLegendCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
->getLegend(), Reference
< frame::XModel
>( xChartDoc
, uno::UNO_QUERY
) ));
281 rContainer
.push_back( aLegendCID
);
283 // iterate over child shapes of legend and search for matching CIDs
284 if( m_pExplicitValueProvider
)
286 Reference
< container::XIndexAccess
> xLegendShapeContainer(
287 m_pExplicitValueProvider
->getShapeForCID( aLegendCID
), uno::UNO_QUERY
);
288 ObjectHierarchy::tChildContainer aLegendEntryCIDs
;
289 lcl_getChildCIDs( aLegendEntryCIDs
, xLegendShapeContainer
);
291 m_aChildMap
[ aLegendCID
] = aLegendEntryCIDs
;
296 void ImplObjectHierarchy::createAxesTree(
297 ObjectHierarchy::tChildContainer
& rContainer
,
298 const Reference
< XChartDocument
> & xChartDoc
,
299 const Reference
< XDiagram
> & xDiagram
)
301 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
302 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
303 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
304 bool bSupportsAxesGrids
= ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimensionCount
, 0 );
305 if( bSupportsAxesGrids
)
307 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ true ) );
308 if( !m_bOrderingForElementSelector
)
309 ::std::transform( aAxes
.getConstArray(), aAxes
.getConstArray() + aAxes
.getLength(),
310 ::std::back_inserter( rContainer
),
311 lcl_ObjectToCID( xChartDoc
));
313 // get all axes, also invisible ones
314 aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ false );
316 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
317 for( sal_Int32 nA
=0; nA
<aAxes
.getLength(); ++nA
)
319 Reference
< XAxis
> xAxis( aAxes
[nA
] );
323 sal_Int32 nCooSysIndex
= 0;
324 sal_Int32 nDimensionIndex
= 0;
325 sal_Int32 nAxisIndex
= 0;
326 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
327 if( nAxisIndex
>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimensionCount
, nDimensionIndex
) )
330 if( m_bOrderingForElementSelector
)
333 if( AxisHelper::isAxisVisible( xAxis
) )
334 rContainer
.push_back(
335 ObjectIdentifier::createClassifiedIdentifierForObject( xAxis
, xChartModel
) );
338 lcl_addAxisTitle( aAxes
[nA
], rContainer
, xChartModel
);
341 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
342 if( AxisHelper::isGridVisible( xGridProperties
) )
345 rContainer
.push_back(
346 ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
) );
349 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );;
350 sal_Int32 nSubGrid
= 0;
351 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
353 Reference
< beans::XPropertySet
> xSubGridProperties( aSubGrids
[nSubGrid
] );
354 if( AxisHelper::isGridVisible( xSubGridProperties
) )
357 rContainer
.push_back(
358 ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
, nSubGrid
) );
365 void ImplObjectHierarchy::createWallAndFloor(
366 ObjectHierarchy::tChildContainer
& rContainer
,
367 const Reference
< XDiagram
> & xDiagram
)
369 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
370 bool bIsThreeD
= ( nDimensionCount
== 3 );
371 bool bHasWall
= DiagramHelper::isSupportingFloorAndWall( xDiagram
);
372 if( bHasWall
&& bIsThreeD
)
374 rContainer
.push_back(
375 ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, rtl::OUString()));
377 Reference
< beans::XPropertySet
> xFloor( xDiagram
->getFloor());
379 rContainer
.push_back(
380 ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, rtl::OUString()));
385 void ImplObjectHierarchy::createDiagramTree(
386 ObjectHierarchy::tChildContainer
& rContainer
,
387 const Reference
< XChartDocument
> & xChartDoc
,
388 const Reference
< XDiagram
> & xDiagram
)
390 if( !m_bOrderingForElementSelector
)
392 createDataSeriesTree( rContainer
, xDiagram
);
393 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
394 createWallAndFloor( rContainer
, xDiagram
);
398 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
399 createDataSeriesTree( rContainer
, xDiagram
);
403 void ImplObjectHierarchy::createDataSeriesTree(
404 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
405 const Reference
< XDiagram
> & xDiagram
)
407 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
411 sal_Int32 nDiagramIndex
= 0;
412 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
413 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
414 xCooSysCnt
->getCoordinateSystems());
415 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
417 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
418 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
419 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypeSeq
.getLength(); ++nCTIdx
)
421 Reference
< XChartType
> xChartType( aChartTypeSeq
[nCTIdx
] );
422 Reference
< XDataSeriesContainer
> xDSCnt( xChartType
, uno::UNO_QUERY_THROW
);
423 Sequence
< Reference
< XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries() );
424 const sal_Int32 nNumberOfSeries
=
425 ChartTypeHelper::getNumberOfDisplayedSeries( xChartType
, aSeriesSeq
.getLength());
427 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<nNumberOfSeries
; ++nSeriesIdx
)
429 OUString
aSeriesParticle(
430 ObjectIdentifier::createParticleForSeries(
431 nDiagramIndex
, nCooSysIdx
, nCTIdx
, nSeriesIdx
));
432 ObjectHierarchy::tCID
aSeriesCID(
433 ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle
));
434 rOutDiagramSubContainer
.push_back( aSeriesCID
);
436 ObjectHierarchy::tChildContainer aSeriesSubContainer
;
438 Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
441 if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries
) )
443 rtl::OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS
) );
444 aChildParticle
+=(C2U("="));
445 aSeriesSubContainer
.push_back(
446 ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle
, aChildParticle
));
450 if( ChartTypeHelper::isSupportingStatisticProperties( xChartType
, nDimensionCount
) )
452 Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
455 Sequence
< Reference
< chart2::XRegressionCurve
> > aCurves( xCurveCnt
->getRegressionCurves());
456 for( sal_Int32 nCurveIdx
=0; nCurveIdx
<aCurves
.getLength(); ++nCurveIdx
)
458 bool bIsAverageLine
= RegressionCurveHelper::isMeanValueLine( aCurves
[nCurveIdx
] );
459 aSeriesSubContainer
.push_back(
460 ObjectIdentifier::createDataCurveCID( aSeriesParticle
, nCurveIdx
, bIsAverageLine
));
461 if( RegressionCurveHelper::hasEquation( aCurves
[nCurveIdx
] ) )
463 aSeriesSubContainer
.push_back(
464 ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle
, nCurveIdx
));
467 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
468 Reference
< beans::XPropertySet
> xErrorBarProp
;
469 if( xSeriesProp
.is() &&
470 (xSeriesProp
->getPropertyValue( C2U("ErrorBarY")) >>= xErrorBarProp
) &&
473 sal_Int32 nStyle
= ::com::sun::star::chart::ErrorBarStyle::NONE
;
474 if( ( xErrorBarProp
->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle
) &&
475 ( nStyle
!= ::com::sun::star::chart::ErrorBarStyle::NONE
) )
477 aSeriesSubContainer
.push_back(
478 ObjectIdentifier::createClassifiedIdentifierWithParent(
479 OBJECTTYPE_DATA_ERRORS
, OUString(), aSeriesParticle
));
486 // iterate over child shapes of legend and search for matching CIDs
487 if( m_pExplicitValueProvider
)
489 Reference
< container::XIndexAccess
> xSeriesShapeContainer(
490 m_pExplicitValueProvider
->getShapeForCID( aSeriesCID
), uno::UNO_QUERY
);
491 lcl_getChildCIDs( aSeriesSubContainer
, xSeriesShapeContainer
);
494 if( ! aSeriesSubContainer
.empty())
495 m_aChildMap
[ aSeriesCID
] = aSeriesSubContainer
;
500 catch( uno::Exception
& ex
)
502 ASSERT_EXCEPTION( ex
);
506 bool ImplObjectHierarchy::hasChildren( const OUString
& rParent
)
508 if( rParent
.getLength())
510 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
511 if( aIt
!= m_aChildMap
.end())
512 return ! (aIt
->second
.empty());
517 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getChildren( const OUString
& rParent
)
519 if( rParent
.getLength())
521 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
522 if( aIt
!= m_aChildMap
.end())
525 return ObjectHierarchy::tChildContainer();
528 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getSiblings( const OUString
& rNode
)
530 if( rNode
.getLength() && !ObjectHierarchy::isRootNode( rNode
))
532 for( tChildMap::const_iterator
aIt( m_aChildMap
.begin());
533 aIt
!= m_aChildMap
.end(); ++aIt
)
535 ObjectHierarchy::tChildContainer::const_iterator
aElemIt(
536 ::std::find( aIt
->second
.begin(), aIt
->second
.end(), rNode
));
537 if( aElemIt
!= aIt
->second
.end())
541 return ObjectHierarchy::tChildContainer();
544 ObjectHierarchy::tCID
ImplObjectHierarchy::getParentImpl(
545 const ObjectHierarchy::tCID
& rParentCID
,
546 const ObjectHierarchy::tCID
& rCID
)
549 ObjectHierarchy::tChildContainer
aChildren( getChildren( rParentCID
));
550 ObjectHierarchy::tChildContainer::const_iterator
aIt(
551 ::std::find( aChildren
.begin(), aChildren
.end(), rCID
));
553 if( aIt
!= aChildren
.end())
556 for( aIt
= aChildren
.begin(); aIt
!= aChildren
.end(); ++aIt
)
559 ObjectHierarchy::tCID
aTempParent( getParentImpl( *aIt
, rCID
));
560 if( aTempParent
.getLength())
568 return ObjectHierarchy::tCID();
571 ObjectHierarchy::tCID
ImplObjectHierarchy::getParent(
572 const ObjectHierarchy::tCID
& rCID
)
574 return getParentImpl( ObjectHierarchy::getRootNodeCID(), rCID
);
579 ObjectHierarchy::ObjectHierarchy(
580 const Reference
< XChartDocument
> & xChartDocument
,
581 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */,
582 bool bFlattenDiagram
/* = false */,
583 bool bOrderingForElementSelector
/* = false */) :
584 m_apImpl( new impl::ImplObjectHierarchy( xChartDocument
, pExplicitValueProvider
, bFlattenDiagram
, bOrderingForElementSelector
))
587 ObjectHierarchy::~ObjectHierarchy()
591 ObjectHierarchy::tCID
ObjectHierarchy::getRootNodeCID()
597 bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tCID
& rCID
)
599 return rCID
.equals( ObjectHierarchy::getRootNodeCID());
602 ObjectHierarchy::tChildContainer
ObjectHierarchy::getTopLevelChildren() const
604 return m_apImpl
->getChildren( ObjectHierarchy::getRootNodeCID());
607 bool ObjectHierarchy::hasChildren( const tCID
& rParent
) const
609 return m_apImpl
->hasChildren( rParent
);
612 ObjectHierarchy::tChildContainer
ObjectHierarchy::getChildren(
613 const ObjectHierarchy::tCID
& rParent
) const
615 if( rParent
.getLength())
616 return m_apImpl
->getChildren( rParent
);
618 return ObjectHierarchy::tChildContainer();
621 ObjectHierarchy::tChildContainer
ObjectHierarchy::getSiblings(
622 const ObjectHierarchy::tCID
& rNode
) const
624 if( rNode
.getLength() && !isRootNode( rNode
))
625 return m_apImpl
->getSiblings( rNode
);
627 return ObjectHierarchy::tChildContainer();
630 ObjectHierarchy::tCID
ObjectHierarchy::getParent(
631 const ObjectHierarchy::tCID
& rNode
) const
633 return m_apImpl
->getParent( rNode
);
636 sal_Int32
ObjectHierarchy::getIndexInParent(
637 const ObjectHierarchy::tCID
& rNode
) const
639 tCID
aParentCID( m_apImpl
->getParent( rNode
));
640 tChildContainer
aChildren( m_apImpl
->getChildren( aParentCID
));
641 tChildContainer::const_iterator
aIt( aChildren
.begin());
642 for( sal_Int32 nIndex
= 0; aIt
!= aChildren
.end(); ++nIndex
, ++aIt
)
644 if( aIt
->equals( rNode
))
650 // ================================================================================
652 ObjectKeyNavigation::ObjectKeyNavigation(
653 const ObjectHierarchy::tCID
& rCurrentCID
,
654 const Reference
< chart2::XChartDocument
> & xChartDocument
,
655 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */ ) :
656 m_aCurrentCID( rCurrentCID
),
657 m_xChartDocument( xChartDocument
),
658 m_pExplicitValueProvider( pExplicitValueProvider
),
659 m_bStepDownInDiagram( true )
661 if( m_aCurrentCID
.getLength() == 0 )
662 setCurrentSelection( ObjectHierarchy::getRootNodeCID());
665 bool ObjectKeyNavigation::handleKeyEvent(
666 const awt::KeyEvent
& rEvent
)
668 bool bResult
= false;
670 switch( rEvent
.KeyCode
)
673 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
674 bResult
= previous();
685 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
690 case awt::Key::ESCAPE
:
691 setCurrentSelection( OUString());
701 void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tCID
& rCID
)
703 m_aCurrentCID
= rCID
;
706 ObjectHierarchy::tCID
ObjectKeyNavigation::getCurrentSelection() const
708 return m_aCurrentCID
;
711 bool ObjectKeyNavigation::first()
713 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
714 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
715 bool bResult
= !aSiblings
.empty();
717 setCurrentSelection( aSiblings
.front());
719 bResult
= veryFirst();
723 bool ObjectKeyNavigation::last()
725 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
726 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
727 bool bResult
= !aSiblings
.empty();
729 setCurrentSelection( aSiblings
.back());
731 bResult
= veryLast();
735 bool ObjectKeyNavigation::next()
737 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
738 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
739 bool bResult
= !aSiblings
.empty();
742 ObjectHierarchy::tChildContainer::const_iterator
aIt(
743 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
744 OSL_ASSERT( aIt
!= aSiblings
.end());
745 if( ++aIt
== aSiblings
.end())
746 aIt
= aSiblings
.begin();
747 setCurrentSelection( *aIt
);
750 bResult
= veryFirst();
755 bool ObjectKeyNavigation::previous()
757 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
758 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
759 bool bResult
= !aSiblings
.empty();
762 ObjectHierarchy::tChildContainer::const_iterator
aIt(
763 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
764 OSL_ASSERT( aIt
!= aSiblings
.end());
765 if( aIt
== aSiblings
.begin())
766 aIt
= aSiblings
.end();
768 setCurrentSelection( *aIt
);
771 bResult
= veryLast();
775 bool ObjectKeyNavigation::up()
777 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
778 bool bResult
= !ObjectHierarchy::isRootNode( getCurrentSelection());
780 setCurrentSelection( aHierarchy
.getParent( getCurrentSelection()));
784 bool ObjectKeyNavigation::down()
786 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
787 bool bResult
= aHierarchy
.hasChildren( getCurrentSelection());
790 ObjectHierarchy::tChildContainer aChildren
= aHierarchy
.getChildren( getCurrentSelection());
791 OSL_ASSERT( !aChildren
.empty());
792 setCurrentSelection( aChildren
.front());
797 bool ObjectKeyNavigation::veryFirst()
799 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
800 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
801 bool bResult
= !aChildren
.empty();
803 setCurrentSelection( aChildren
.front());
807 bool ObjectKeyNavigation::veryLast()
809 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
810 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
811 bool bResult
= !aChildren
.empty();
813 setCurrentSelection( aChildren
.back());