1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "ObjectHierarchy.hxx"
31 #include "ObjectIdentifier.hxx"
32 #include "ChartModelHelper.hxx"
33 #include "DiagramHelper.hxx"
34 #include "RegressionCurveHelper.hxx"
35 #include "AxisHelper.hxx"
36 #include "chartview/ExplicitValueProvider.hxx"
38 #include "LineProperties.hxx"
39 #include "ChartTypeHelper.hxx"
40 #include "DataSeriesHelper.hxx"
41 #include "LegendHelper.hxx"
42 #include "chartview/DrawModelWrapper.hxx"
47 #include <com/sun/star/chart2/XTitled.hpp>
48 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
49 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
50 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
51 #include <com/sun/star/chart/ErrorBarStyle.hpp>
53 #include <com/sun/star/container/XIndexAccess.hpp>
54 #include <com/sun/star/awt/Key.hpp>
55 #include <com/sun/star/awt/KeyModifier.hpp>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::chart2
;
60 using ::com::sun::star::uno::Reference
;
61 using ::com::sun::star::uno::Sequence
;
62 using ::rtl::OUString
;
67 struct lcl_ObjectToOID
: public ::std::unary_function
< Reference
< uno::XInterface
>, ::chart::ObjectIdentifier
>
69 explicit lcl_ObjectToOID( const Reference
< chart2::XChartDocument
> & xChartDoc
) :
70 m_xModel( xChartDoc
, uno::UNO_QUERY
)
73 ::chart::ObjectIdentifier
operator() ( const Reference
< uno::XInterface
> & xObj
)
75 return ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj
, m_xModel
) );
79 Reference
< frame::XModel
> m_xModel
;
82 void lcl_getChildOIDs(
83 ::chart::ObjectHierarchy::tChildContainer
& rOutChildren
,
84 const Reference
< container::XIndexAccess
>& xShapes
)
88 sal_Int32 nCount
= xShapes
->getCount();
89 for( sal_Int32 i
=0; i
<nCount
; ++i
)
91 Reference
< beans::XPropertySet
> xShapeProp( xShapes
->getByIndex( i
), uno::UNO_QUERY
);
94 Reference
< beans::XPropertySetInfo
> xInfo( xShapeProp
->getPropertySetInfo());
97 xInfo
->hasPropertyByName( C2U("Name")) &&
98 (xShapeProp
->getPropertyValue( C2U("Name")) >>= aName
) &&
100 ::chart::ObjectIdentifier::isCID( aName
))
102 rOutChildren
.push_back( ::chart::ObjectIdentifier( aName
) );
104 Reference
< container::XIndexAccess
> xNewShapes( xShapeProp
, uno::UNO_QUERY
);
106 lcl_getChildOIDs( rOutChildren
, xNewShapes
);
112 void lcl_addAxisTitle( const Reference
< XAxis
>& xAxis
, ::chart::ObjectHierarchy::tChildContainer
& rContainer
, const Reference
< frame::XModel
>& xChartModel
)
114 Reference
< XTitled
> xAxisTitled( xAxis
, uno::UNO_QUERY
);
115 if( xAxisTitled
.is())
117 Reference
< XTitle
> xAxisTitle( xAxisTitled
->getTitleObject());
119 rContainer
.push_back(
120 ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle
, xChartModel
) ) );
124 } // anonymous namespace
132 class ImplObjectHierarchy
135 explicit ImplObjectHierarchy(
136 const Reference
< XChartDocument
>& xChartDocument
,
137 ExplicitValueProvider
* pExplicitValueProvider
,
138 bool bFlattenDiagram
, bool bOrderingForElementSelector
);
140 bool hasChildren( const ObjectHierarchy::tOID
& rParent
);
141 ObjectHierarchy::tChildContainer
getChildren( const ObjectHierarchy::tOID
& rParent
);
142 ObjectHierarchy::tChildContainer
getSiblings( const ObjectHierarchy::tOID
& rNode
);
144 ObjectHierarchy::tOID
getParent( const ObjectHierarchy::tOID
& rOID
);
147 void createTree( const Reference
< XChartDocument
> & xChartDocument
);
149 ObjectHierarchy::tChildContainer
& rContainer
,
150 const Reference
< XChartDocument
> & xChartDoc
,
151 const Reference
< XDiagram
> & xDiagram
);
152 void createDiagramTree(
153 ObjectHierarchy::tChildContainer
& rContainer
,
154 const Reference
< XChartDocument
>& xChartDoc
,
155 const Reference
< XDiagram
>& xDiagram
);
156 void createDataSeriesTree(
157 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
158 const Reference
< XDiagram
> & xDiagram
);
159 void createWallAndFloor(
160 ObjectHierarchy::tChildContainer
& rContainer
,
161 const Reference
< XDiagram
> & xDiagram
);
162 void createLegendTree(
163 ObjectHierarchy::tChildContainer
& rContainer
,
164 const Reference
< XChartDocument
> & xChartDoc
,
165 const Reference
< XDiagram
> & xDiagram
);
166 void createAdditionalShapesTree( ObjectHierarchy::tChildContainer
& rContainer
);
168 ObjectHierarchy::tOID
getParentImpl(
169 const ObjectHierarchy::tOID
& rParentOID
,
170 const ObjectHierarchy::tOID
& rOID
);
172 typedef ::std::map
< ObjectHierarchy::tOID
, ObjectHierarchy::tChildContainer
>
174 tChildMap m_aChildMap
;
175 ExplicitValueProvider
* m_pExplicitValueProvider
;
176 bool m_bFlattenDiagram
;
177 bool m_bOrderingForElementSelector
;
180 ImplObjectHierarchy::ImplObjectHierarchy(
181 const Reference
< XChartDocument
>& xChartDocument
,
182 ExplicitValueProvider
* pExplicitValueProvider
,
183 bool bFlattenDiagram
,
184 bool bOrderingForElementSelector
) :
185 m_pExplicitValueProvider( pExplicitValueProvider
),
186 m_bFlattenDiagram( bFlattenDiagram
),
187 m_bOrderingForElementSelector( bOrderingForElementSelector
)
189 createTree( xChartDocument
);
190 // don't remember this helper to avoid access after lifetime
191 m_pExplicitValueProvider
= 0;
194 void ImplObjectHierarchy::createTree( const Reference
< XChartDocument
>& xChartDocument
)
196 m_aChildMap
= tChildMap();//clear tree
198 if( !xChartDocument
.is() )
201 //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
202 Reference
< frame::XModel
> xModel( xChartDocument
, uno::UNO_QUERY
);
203 Reference
< XDiagram
> xDiagram( ChartModelHelper::findDiagram( xChartDocument
) );
204 ObjectHierarchy::tOID aDiaOID
;
206 aDiaOID
= ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
, xModel
) );
207 ObjectHierarchy::tChildContainer aTopLevelContainer
;
212 if( m_bOrderingForElementSelector
)
214 aTopLevelContainer
.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) ) );
217 aTopLevelContainer
.push_back( aDiaOID
);
218 createWallAndFloor( aTopLevelContainer
, xDiagram
);
219 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
224 Reference
< XTitled
> xDocTitled( xChartDocument
, uno::UNO_QUERY
);
227 Reference
< XTitle
> xMainTitle( xDocTitled
->getTitleObject());
229 aTopLevelContainer
.push_back(
230 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle
, xModel
) ) );
235 // Sub Title. Note: This is interpreted of being top level
236 Reference
< XTitled
> xDiaTitled( xDiagram
, uno::UNO_QUERY
);
239 Reference
< XTitle
> xSubTitle( xDiaTitled
->getTitleObject());
241 aTopLevelContainer
.push_back(
242 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle
, xModel
) ) );
245 if( !m_bOrderingForElementSelector
)
247 // Axis Titles. Note: These are interpreted of being top level
248 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
249 for( sal_Int32 i
=0; i
<aAxes
.getLength(); ++i
)
250 lcl_addAxisTitle( aAxes
[i
], aTopLevelContainer
, xModel
);
253 aTopLevelContainer
.push_back( aDiaOID
);
256 if( m_bFlattenDiagram
)
257 createDiagramTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
260 ObjectHierarchy::tChildContainer aSubContainer
;
261 createDiagramTree( aSubContainer
, xChartDocument
, xDiagram
);
262 if( !aSubContainer
.empty() )
263 m_aChildMap
[ aDiaOID
] = aSubContainer
;
266 if( !m_bOrderingForElementSelector
)
267 createLegendTree( aTopLevelContainer
, xChartDocument
, xDiagram
);
270 // #i12587# support for shapes in chart
271 if ( !m_bOrderingForElementSelector
)
273 createAdditionalShapesTree( aTopLevelContainer
);
277 if( !m_bOrderingForElementSelector
)
278 aTopLevelContainer
.push_back(
279 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) ) );
281 if( ! aTopLevelContainer
.empty())
282 m_aChildMap
[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer
;
285 void ImplObjectHierarchy::createLegendTree(
286 ObjectHierarchy::tChildContainer
& rContainer
,
287 const Reference
< XChartDocument
> & xChartDoc
,
288 const Reference
< XDiagram
> & xDiagram
)
290 if( xDiagram
.is() && LegendHelper::hasLegend( xDiagram
) )
292 ObjectHierarchy::tOID
aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram
->getLegend(), Reference
< frame::XModel
>( xChartDoc
, uno::UNO_QUERY
) ) ) );
293 rContainer
.push_back( aLegendOID
);
295 // iterate over child shapes of legend and search for matching CIDs
296 if( m_pExplicitValueProvider
)
298 Reference
< container::XIndexAccess
> xLegendShapeContainer(
299 m_pExplicitValueProvider
->getShapeForCID( aLegendOID
.getObjectCID() ), uno::UNO_QUERY
);
300 ObjectHierarchy::tChildContainer aLegendEntryOIDs
;
301 lcl_getChildOIDs( aLegendEntryOIDs
, xLegendShapeContainer
);
303 m_aChildMap
[ aLegendOID
] = aLegendEntryOIDs
;
308 void ImplObjectHierarchy::createAxesTree(
309 ObjectHierarchy::tChildContainer
& rContainer
,
310 const Reference
< XChartDocument
> & xChartDoc
,
311 const Reference
< XDiagram
> & xDiagram
)
313 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
314 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
315 uno::Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
316 bool bSupportsAxesGrids
= ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimensionCount
, 0 );
317 if( bSupportsAxesGrids
)
319 Sequence
< Reference
< XAxis
> > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ true ) );
320 if( !m_bOrderingForElementSelector
)
321 ::std::transform( aAxes
.getConstArray(), aAxes
.getConstArray() + aAxes
.getLength(),
322 ::std::back_inserter( rContainer
),
323 lcl_ObjectToOID( xChartDoc
));
325 // get all axes, also invisible ones
326 aAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
, /* bOnlyVisible = */ false );
328 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
329 for( sal_Int32 nA
=0; nA
<aAxes
.getLength(); ++nA
)
331 Reference
< XAxis
> xAxis( aAxes
[nA
] );
335 sal_Int32 nCooSysIndex
= 0;
336 sal_Int32 nDimensionIndex
= 0;
337 sal_Int32 nAxisIndex
= 0;
338 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
339 if( nAxisIndex
>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimensionCount
, nDimensionIndex
) )
342 if( m_bOrderingForElementSelector
)
345 if( AxisHelper::isAxisVisible( xAxis
) )
346 rContainer
.push_back(
347 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis
, xChartModel
) ) );
350 lcl_addAxisTitle( aAxes
[nA
], rContainer
, xChartModel
);
353 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
354 if( AxisHelper::isGridVisible( xGridProperties
) )
357 rContainer
.push_back(
358 ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
) ) ) );
361 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );;
362 sal_Int32 nSubGrid
= 0;
363 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
365 Reference
< beans::XPropertySet
> xSubGridProperties( aSubGrids
[nSubGrid
] );
366 if( AxisHelper::isGridVisible( xSubGridProperties
) )
369 rContainer
.push_back(
370 ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis
, xChartModel
, nSubGrid
) ) ) );
377 void ImplObjectHierarchy::createWallAndFloor(
378 ObjectHierarchy::tChildContainer
& rContainer
,
379 const Reference
< XDiagram
> & xDiagram
)
381 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
382 bool bIsThreeD
= ( nDimensionCount
== 3 );
383 bool bHasWall
= DiagramHelper::isSupportingFloorAndWall( xDiagram
);
384 if( bHasWall
&& bIsThreeD
)
386 rContainer
.push_back(
387 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL
, rtl::OUString() ) ) );
389 Reference
< beans::XPropertySet
> xFloor( xDiagram
->getFloor());
391 rContainer
.push_back(
392 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR
, rtl::OUString() ) ) );
397 void ImplObjectHierarchy::createDiagramTree(
398 ObjectHierarchy::tChildContainer
& rContainer
,
399 const Reference
< XChartDocument
> & xChartDoc
,
400 const Reference
< XDiagram
> & xDiagram
)
402 if( !m_bOrderingForElementSelector
)
404 createDataSeriesTree( rContainer
, xDiagram
);
405 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
406 createWallAndFloor( rContainer
, xDiagram
);
410 createAxesTree( rContainer
, xChartDoc
, xDiagram
);
411 createDataSeriesTree( rContainer
, xDiagram
);
415 void ImplObjectHierarchy::createDataSeriesTree(
416 ObjectHierarchy::tChildContainer
& rOutDiagramSubContainer
,
417 const Reference
< XDiagram
> & xDiagram
)
419 Reference
< XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
423 sal_Int32 nDiagramIndex
= 0;
424 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
425 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
426 xCooSysCnt
->getCoordinateSystems());
427 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
429 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
430 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
431 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypeSeq
.getLength(); ++nCTIdx
)
433 Reference
< XChartType
> xChartType( aChartTypeSeq
[nCTIdx
] );
434 Reference
< XDataSeriesContainer
> xDSCnt( xChartType
, uno::UNO_QUERY_THROW
);
435 Sequence
< Reference
< XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries() );
436 const sal_Int32 nNumberOfSeries
=
437 ChartTypeHelper::getNumberOfDisplayedSeries( xChartType
, aSeriesSeq
.getLength());
439 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<nNumberOfSeries
; ++nSeriesIdx
)
441 OUString
aSeriesParticle(
442 ObjectIdentifier::createParticleForSeries(
443 nDiagramIndex
, nCooSysIdx
, nCTIdx
, nSeriesIdx
));
444 ObjectHierarchy::tOID
aSeriesOID(
445 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle
) ) );
446 rOutDiagramSubContainer
.push_back( aSeriesOID
);
448 ObjectHierarchy::tChildContainer aSeriesSubContainer
;
450 Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nSeriesIdx
], uno::UNO_QUERY
);
453 if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries
) )
455 rtl::OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS
) );
456 aChildParticle
+=(C2U("="));
457 aSeriesSubContainer
.push_back(
458 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle
, aChildParticle
) ) );
462 if( ChartTypeHelper::isSupportingStatisticProperties( xChartType
, nDimensionCount
) )
464 Reference
< chart2::XRegressionCurveContainer
> xCurveCnt( xSeries
, uno::UNO_QUERY
);
467 Sequence
< Reference
< chart2::XRegressionCurve
> > aCurves( xCurveCnt
->getRegressionCurves());
468 for( sal_Int32 nCurveIdx
=0; nCurveIdx
<aCurves
.getLength(); ++nCurveIdx
)
470 bool bIsAverageLine
= RegressionCurveHelper::isMeanValueLine( aCurves
[nCurveIdx
] );
471 aSeriesSubContainer
.push_back(
472 ObjectIdentifier( ObjectIdentifier::createDataCurveCID( aSeriesParticle
, nCurveIdx
, bIsAverageLine
) ) );
473 if( RegressionCurveHelper::hasEquation( aCurves
[nCurveIdx
] ) )
475 aSeriesSubContainer
.push_back(
476 ObjectIdentifier( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle
, nCurveIdx
) ) );
479 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
480 Reference
< beans::XPropertySet
> xErrorBarProp
;
481 if( xSeriesProp
.is() &&
482 (xSeriesProp
->getPropertyValue( C2U("ErrorBarY")) >>= xErrorBarProp
) &&
485 sal_Int32 nStyle
= ::com::sun::star::chart::ErrorBarStyle::NONE
;
486 if( ( xErrorBarProp
->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle
) &&
487 ( nStyle
!= ::com::sun::star::chart::ErrorBarStyle::NONE
) )
489 aSeriesSubContainer
.push_back(
490 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
491 OBJECTTYPE_DATA_ERRORS_Y
, OUString(), aSeriesParticle
) ) );
495 if( xSeriesProp
.is() &&
496 (xSeriesProp
->getPropertyValue( C2U("ErrorBarX")) >>= xErrorBarProp
) &&
499 sal_Int32 nStyle
= ::com::sun::star::chart::ErrorBarStyle::NONE
;
500 if( ( xErrorBarProp
->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle
) &&
501 ( nStyle
!= ::com::sun::star::chart::ErrorBarStyle::NONE
) )
503 aSeriesSubContainer
.push_back(
504 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
505 OBJECTTYPE_DATA_ERRORS_X
, OUString(), aSeriesParticle
) ) );
512 // iterate over child shapes of legend and search for matching CIDs
513 if( m_pExplicitValueProvider
)
515 Reference
< container::XIndexAccess
> xSeriesShapeContainer(
516 m_pExplicitValueProvider
->getShapeForCID( aSeriesOID
.getObjectCID() ), uno::UNO_QUERY
);
517 lcl_getChildOIDs( aSeriesSubContainer
, xSeriesShapeContainer
);
520 if( ! aSeriesSubContainer
.empty())
521 m_aChildMap
[ aSeriesOID
] = aSeriesSubContainer
;
526 catch( const uno::Exception
& ex
)
528 ASSERT_EXCEPTION( ex
);
532 void ImplObjectHierarchy::createAdditionalShapesTree( ObjectHierarchy::tChildContainer
& rContainer
)
536 if ( m_pExplicitValueProvider
)
538 Reference
< drawing::XDrawPage
> xDrawPage( m_pExplicitValueProvider
->getDrawModelWrapper()->getMainDrawPage() );
539 Reference
< drawing::XShapes
> xDrawPageShapes( xDrawPage
, uno::UNO_QUERY_THROW
);
540 Reference
< drawing::XShapes
> xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage
) );
541 sal_Int32 nCount
= xDrawPageShapes
->getCount();
542 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
544 Reference
< drawing::XShape
> xShape
;
545 if ( xDrawPageShapes
->getByIndex( i
) >>= xShape
)
547 if ( xShape
.is() && xShape
!= xChartRoot
)
549 rContainer
.push_back( ObjectIdentifier( xShape
) );
555 catch ( const uno::Exception
& ex
)
557 ASSERT_EXCEPTION( ex
);
561 bool ImplObjectHierarchy::hasChildren( const ObjectHierarchy::tOID
& rParent
)
563 if ( rParent
.isValid() )
565 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
566 if( aIt
!= m_aChildMap
.end())
567 return ! (aIt
->second
.empty());
572 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID
& rParent
)
574 if ( rParent
.isValid() )
576 tChildMap::const_iterator
aIt( m_aChildMap
.find( rParent
));
577 if( aIt
!= m_aChildMap
.end())
580 return ObjectHierarchy::tChildContainer();
583 ObjectHierarchy::tChildContainer
ImplObjectHierarchy::getSiblings( const ObjectHierarchy::tOID
& rNode
)
585 if ( rNode
.isValid() && !ObjectHierarchy::isRootNode( rNode
) )
587 for( tChildMap::const_iterator
aIt( m_aChildMap
.begin());
588 aIt
!= m_aChildMap
.end(); ++aIt
)
590 ObjectHierarchy::tChildContainer::const_iterator
aElemIt(
591 ::std::find( aIt
->second
.begin(), aIt
->second
.end(), rNode
));
592 if( aElemIt
!= aIt
->second
.end())
596 return ObjectHierarchy::tChildContainer();
599 ObjectHierarchy::tOID
ImplObjectHierarchy::getParentImpl(
600 const ObjectHierarchy::tOID
& rParentOID
,
601 const ObjectHierarchy::tOID
& rOID
)
604 ObjectHierarchy::tChildContainer
aChildren( getChildren( rParentOID
));
605 ObjectHierarchy::tChildContainer::const_iterator
aIt(
606 ::std::find( aChildren
.begin(), aChildren
.end(), rOID
));
608 if( aIt
!= aChildren
.end())
611 for( aIt
= aChildren
.begin(); aIt
!= aChildren
.end(); ++aIt
)
614 ObjectHierarchy::tOID
aTempParent( getParentImpl( *aIt
, rOID
));
615 if ( aTempParent
.isValid() )
623 return ObjectHierarchy::tOID();
626 ObjectHierarchy::tOID
ImplObjectHierarchy::getParent(
627 const ObjectHierarchy::tOID
& rOID
)
629 return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID
);
635 ObjectHierarchy::ObjectHierarchy(
636 const Reference
< XChartDocument
> & xChartDocument
,
637 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */,
638 bool bFlattenDiagram
/* = false */,
639 bool bOrderingForElementSelector
/* = false */) :
640 m_apImpl( new impl::ImplObjectHierarchy( xChartDocument
, pExplicitValueProvider
, bFlattenDiagram
, bOrderingForElementSelector
))
643 ObjectHierarchy::~ObjectHierarchy()
646 ObjectHierarchy::tOID
ObjectHierarchy::getRootNodeOID()
648 return ObjectIdentifier( C2U( "ROOT" ) );
651 bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID
& rOID
)
653 return ( rOID
== ObjectHierarchy::getRootNodeOID() );
656 ObjectHierarchy::tChildContainer
ObjectHierarchy::getTopLevelChildren() const
658 return m_apImpl
->getChildren( ObjectHierarchy::getRootNodeOID());
661 bool ObjectHierarchy::hasChildren( const tOID
& rParent
) const
663 return m_apImpl
->hasChildren( rParent
);
666 ObjectHierarchy::tChildContainer
ObjectHierarchy::getChildren(
667 const ObjectHierarchy::tOID
& rParent
) const
669 if ( rParent
.isValid() )
670 return m_apImpl
->getChildren( rParent
);
672 return ObjectHierarchy::tChildContainer();
675 ObjectHierarchy::tChildContainer
ObjectHierarchy::getSiblings(
676 const ObjectHierarchy::tOID
& rNode
) const
678 if ( rNode
.isValid() && !isRootNode( rNode
) )
679 return m_apImpl
->getSiblings( rNode
);
681 return ObjectHierarchy::tChildContainer();
684 ObjectHierarchy::tOID
ObjectHierarchy::getParent(
685 const ObjectHierarchy::tOID
& rNode
) const
687 return m_apImpl
->getParent( rNode
);
690 sal_Int32
ObjectHierarchy::getIndexInParent(
691 const ObjectHierarchy::tOID
& rNode
) const
693 tOID
aParentOID( m_apImpl
->getParent( rNode
));
694 tChildContainer
aChildren( m_apImpl
->getChildren( aParentOID
) );
695 tChildContainer::const_iterator
aIt( aChildren
.begin() );
696 for( sal_Int32 nIndex
= 0; aIt
!= aChildren
.end(); ++nIndex
, ++aIt
)
704 // ================================================================================
706 ObjectKeyNavigation::ObjectKeyNavigation(
707 const ObjectHierarchy::tOID
& rCurrentOID
,
708 const Reference
< chart2::XChartDocument
> & xChartDocument
,
709 ExplicitValueProvider
* pExplicitValueProvider
/* = 0 */ ) :
710 m_aCurrentOID( rCurrentOID
),
711 m_xChartDocument( xChartDocument
),
712 m_pExplicitValueProvider( pExplicitValueProvider
),
713 m_bStepDownInDiagram( true )
715 if ( !m_aCurrentOID
.isValid() )
717 setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
721 bool ObjectKeyNavigation::handleKeyEvent(
722 const awt::KeyEvent
& rEvent
)
724 bool bResult
= false;
726 switch( rEvent
.KeyCode
)
729 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
730 bResult
= previous();
741 if( rEvent
.Modifiers
& awt::KeyModifier::SHIFT
)
746 case awt::Key::ESCAPE
:
747 setCurrentSelection( ObjectIdentifier() );
757 void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID
& rOID
)
759 m_aCurrentOID
= rOID
;
762 ObjectHierarchy::tOID
ObjectKeyNavigation::getCurrentSelection() const
764 return m_aCurrentOID
;
767 bool ObjectKeyNavigation::first()
769 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
770 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
771 bool bResult
= !aSiblings
.empty();
773 setCurrentSelection( aSiblings
.front());
775 bResult
= veryFirst();
779 bool ObjectKeyNavigation::last()
781 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
782 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
783 bool bResult
= !aSiblings
.empty();
785 setCurrentSelection( aSiblings
.back());
787 bResult
= veryLast();
791 bool ObjectKeyNavigation::next()
793 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
794 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection() ) );
795 bool bResult
= !aSiblings
.empty();
798 ObjectHierarchy::tChildContainer::const_iterator
aIt(
799 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
800 OSL_ASSERT( aIt
!= aSiblings
.end());
801 if( ++aIt
== aSiblings
.end())
802 aIt
= aSiblings
.begin();
803 setCurrentSelection( *aIt
);
806 bResult
= veryFirst();
811 bool ObjectKeyNavigation::previous()
813 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
814 ObjectHierarchy::tChildContainer
aSiblings( aHierarchy
.getSiblings( getCurrentSelection()));
815 bool bResult
= !aSiblings
.empty();
818 ObjectHierarchy::tChildContainer::const_iterator
aIt(
819 ::std::find( aSiblings
.begin(), aSiblings
.end(), getCurrentSelection()));
820 OSL_ASSERT( aIt
!= aSiblings
.end());
821 if( aIt
== aSiblings
.begin())
822 aIt
= aSiblings
.end();
824 setCurrentSelection( *aIt
);
827 bResult
= veryLast();
831 bool ObjectKeyNavigation::up()
833 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
834 bool bResult
= !ObjectHierarchy::isRootNode( getCurrentSelection());
836 setCurrentSelection( aHierarchy
.getParent( getCurrentSelection()));
840 bool ObjectKeyNavigation::down()
842 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
843 bool bResult
= aHierarchy
.hasChildren( getCurrentSelection());
846 ObjectHierarchy::tChildContainer aChildren
= aHierarchy
.getChildren( getCurrentSelection());
847 OSL_ASSERT( !aChildren
.empty());
848 setCurrentSelection( aChildren
.front());
853 bool ObjectKeyNavigation::veryFirst()
855 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
856 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
857 bool bResult
= !aChildren
.empty();
859 setCurrentSelection( aChildren
.front());
863 bool ObjectKeyNavigation::veryLast()
865 ObjectHierarchy
aHierarchy( m_xChartDocument
, m_pExplicitValueProvider
, m_bStepDownInDiagram
);
866 ObjectHierarchy::tChildContainer
aChildren( aHierarchy
.getTopLevelChildren());
867 bool bResult
= !aChildren
.empty();
869 setCurrentSelection( aChildren
.back());
875 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */