Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include "ObjectHierarchy.hxx"
22 : : #include "ObjectIdentifier.hxx"
23 : : #include "ChartModelHelper.hxx"
24 : : #include "DiagramHelper.hxx"
25 : : #include "RegressionCurveHelper.hxx"
26 : : #include "AxisHelper.hxx"
27 : : #include "chartview/ExplicitValueProvider.hxx"
28 : : #include "macros.hxx"
29 : : #include "LineProperties.hxx"
30 : : #include "ChartTypeHelper.hxx"
31 : : #include "DataSeriesHelper.hxx"
32 : : #include "LegendHelper.hxx"
33 : : #include "chartview/DrawModelWrapper.hxx"
34 : :
35 : : #include <map>
36 : : #include <algorithm>
37 : :
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>
43 : :
44 : : #include <com/sun/star/container/XIndexAccess.hpp>
45 : : #include <com/sun/star/awt/Key.hpp>
46 : : #include <com/sun/star/awt/KeyModifier.hpp>
47 : :
48 : : using namespace ::com::sun::star;
49 : : using namespace ::com::sun::star::chart2;
50 : :
51 : : using ::com::sun::star::uno::Reference;
52 : : using ::com::sun::star::uno::Sequence;
53 : : using ::rtl::OUString;
54 : :
55 : : namespace
56 : : {
57 : :
58 : 0 : struct lcl_ObjectToOID : public ::std::unary_function< Reference< uno::XInterface >, ::chart::ObjectIdentifier >
59 : : {
60 : 0 : explicit lcl_ObjectToOID( const Reference< chart2::XChartDocument > & xChartDoc ) :
61 : 0 : m_xModel( xChartDoc, uno::UNO_QUERY )
62 : 0 : {}
63 : :
64 : 0 : ::chart::ObjectIdentifier operator() ( const Reference< uno::XInterface > & xObj )
65 : : {
66 [ # # ]: 0 : return ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel ) );
67 : : }
68 : :
69 : : private:
70 : : Reference< frame::XModel > m_xModel;
71 : : };
72 : :
73 : 0 : void lcl_getChildOIDs(
74 : : ::chart::ObjectHierarchy::tChildContainer& rOutChildren,
75 : : const Reference< container::XIndexAccess >& xShapes )
76 : : {
77 [ # # ]: 0 : if( xShapes.is())
78 : : {
79 : 0 : sal_Int32 nCount = xShapes->getCount();
80 [ # # ]: 0 : for( sal_Int32 i=0; i<nCount; ++i)
81 : : {
82 [ # # ][ # # ]: 0 : Reference< beans::XPropertySet > xShapeProp( xShapes->getByIndex( i ), uno::UNO_QUERY );
[ # # ]
83 [ # # ]: 0 : if( xShapeProp.is())
84 : : {
85 [ # # ][ # # ]: 0 : Reference< beans::XPropertySetInfo > xInfo( xShapeProp->getPropertySetInfo());
86 : 0 : OUString aName;
87 [ # # # # : 0 : if( xInfo.is() &&
# # ][ # # ]
[ # # ][ # # ]
88 [ # # ][ # # ]: 0 : xInfo->hasPropertyByName( C2U("Name")) &&
[ # # ][ # # ]
[ # # ]
89 [ # # ][ # # ]: 0 : (xShapeProp->getPropertyValue( C2U("Name")) >>= aName ) &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
90 : 0 : !aName.isEmpty() &&
91 [ # # ]: 0 : ::chart::ObjectIdentifier::isCID( aName ))
92 : : {
93 [ # # ][ # # ]: 0 : rOutChildren.push_back( ::chart::ObjectIdentifier( aName ) );
[ # # ]
94 : : }
95 [ # # ]: 0 : Reference< container::XIndexAccess > xNewShapes( xShapeProp, uno::UNO_QUERY );
96 [ # # ]: 0 : if( xNewShapes.is())
97 [ # # ]: 0 : lcl_getChildOIDs( rOutChildren, xNewShapes );
98 : : }
99 : 0 : }
100 : : }
101 : 0 : }
102 : :
103 : 4450 : void lcl_addAxisTitle( const Reference< XAxis >& xAxis, ::chart::ObjectHierarchy::tChildContainer& rContainer, const Reference< frame::XModel >& xChartModel )
104 : : {
105 [ + - ]: 4450 : Reference< XTitled > xAxisTitled( xAxis, uno::UNO_QUERY );
106 [ + - ]: 4450 : if( xAxisTitled.is())
107 : : {
108 [ + - ][ + - ]: 4450 : Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject());
109 [ - + ]: 4450 : if( xAxisTitle.is())
110 : : rContainer.push_back(
111 [ # # ][ # # ]: 4450 : ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xChartModel ) ) );
[ # # ][ # # ]
112 : 4450 : }
113 : 4450 : }
114 : :
115 : : } // anonymous namespace
116 : :
117 : : namespace chart
118 : : {
119 : :
120 : : namespace impl
121 : : {
122 : :
123 : 2271 : class ImplObjectHierarchy
124 : : {
125 : : public:
126 : : explicit ImplObjectHierarchy(
127 : : const Reference< XChartDocument >& xChartDocument,
128 : : ExplicitValueProvider* pExplicitValueProvider,
129 : : bool bFlattenDiagram, bool bOrderingForElementSelector );
130 : :
131 : : bool hasChildren( const ObjectHierarchy::tOID& rParent );
132 : : ObjectHierarchy::tChildContainer getChildren( const ObjectHierarchy::tOID& rParent );
133 : : ObjectHierarchy::tChildContainer getSiblings( const ObjectHierarchy::tOID& rNode );
134 : :
135 : : ObjectHierarchy::tOID getParent( const ObjectHierarchy::tOID& rOID );
136 : :
137 : : private:
138 : : void createTree( const Reference< XChartDocument > & xChartDocument );
139 : : void createAxesTree(
140 : : ObjectHierarchy::tChildContainer & rContainer,
141 : : const Reference< XChartDocument > & xChartDoc,
142 : : const Reference< XDiagram > & xDiagram );
143 : : void createDiagramTree(
144 : : ObjectHierarchy::tChildContainer& rContainer,
145 : : const Reference< XChartDocument >& xChartDoc,
146 : : const Reference< XDiagram >& xDiagram );
147 : : void createDataSeriesTree(
148 : : ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
149 : : const Reference< XDiagram > & xDiagram );
150 : : void createWallAndFloor(
151 : : ObjectHierarchy::tChildContainer & rContainer,
152 : : const Reference< XDiagram > & xDiagram );
153 : : void createLegendTree(
154 : : ObjectHierarchy::tChildContainer & rContainer,
155 : : const Reference< XChartDocument > & xChartDoc,
156 : : const Reference< XDiagram > & xDiagram );
157 : : void createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer );
158 : :
159 : : ObjectHierarchy::tOID getParentImpl(
160 : : const ObjectHierarchy::tOID& rParentOID,
161 : : const ObjectHierarchy::tOID& rOID );
162 : :
163 : : typedef ::std::map< ObjectHierarchy::tOID, ObjectHierarchy::tChildContainer >
164 : : tChildMap;
165 : : tChildMap m_aChildMap;
166 : : ExplicitValueProvider* m_pExplicitValueProvider;
167 : : bool m_bFlattenDiagram;
168 : : bool m_bOrderingForElementSelector;
169 : : };
170 : :
171 : 2271 : ImplObjectHierarchy::ImplObjectHierarchy(
172 : : const Reference< XChartDocument >& xChartDocument,
173 : : ExplicitValueProvider* pExplicitValueProvider,
174 : : bool bFlattenDiagram,
175 : : bool bOrderingForElementSelector ) :
176 : : m_pExplicitValueProvider( pExplicitValueProvider ),
177 : : m_bFlattenDiagram( bFlattenDiagram ),
178 : 2271 : m_bOrderingForElementSelector( bOrderingForElementSelector )
179 : : {
180 [ + - ]: 2271 : createTree( xChartDocument );
181 : : // don't remember this helper to avoid access after lifetime
182 : 2271 : m_pExplicitValueProvider = 0;
183 : 2271 : }
184 : :
185 : 2271 : void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartDocument )
186 : : {
187 [ + - ][ + - ]: 2271 : m_aChildMap = tChildMap();//clear tree
188 : :
189 [ + - ]: 2271 : if( !xChartDocument.is() )
190 : 2271 : return;
191 : :
192 : : //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
193 [ + - ]: 2271 : Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
194 [ + - ]: 2271 : Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ) );
195 [ + - ]: 2271 : ObjectHierarchy::tOID aDiaOID;
196 [ + + ]: 2271 : if( xDiagram.is() )
197 [ + - ][ + - ]: 2265 : aDiaOID = ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) );
[ + - ][ + - ]
198 [ + - ]: 2271 : ObjectHierarchy::tChildContainer aTopLevelContainer;
199 : :
200 : : // First Level
201 : :
202 : : // Chart Area
203 [ + - ]: 2271 : if( m_bOrderingForElementSelector )
204 : : {
205 [ + - ][ + - ]: 2271 : aTopLevelContainer.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
[ + - ][ + - ]
206 [ + + ]: 2271 : if( xDiagram.is() )
207 : : {
208 [ + - ]: 2265 : aTopLevelContainer.push_back( aDiaOID );
209 [ + - ]: 2265 : createWallAndFloor( aTopLevelContainer, xDiagram );
210 [ + - ]: 2265 : createLegendTree( aTopLevelContainer, xChartDocument, xDiagram );
211 : : }
212 : : }
213 : :
214 : : // Main Title
215 [ + - ]: 2271 : Reference< XTitled > xDocTitled( xChartDocument, uno::UNO_QUERY );
216 [ + - ]: 2271 : if( xDocTitled.is())
217 : : {
218 [ + - ][ + - ]: 2271 : Reference< XTitle > xMainTitle( xDocTitled->getTitleObject());
219 [ + + ]: 2271 : if( xMainTitle.is())
220 : : aTopLevelContainer.push_back(
221 [ + - ][ + - ]: 2271 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ) ) );
[ + - ][ + - ]
222 : : }
223 : :
224 [ + + ]: 2271 : if( xDiagram.is())
225 : : {
226 : : // Sub Title. Note: This is interpreted of being top level
227 [ + - ]: 2265 : Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
228 [ + - ]: 2265 : if( xDiaTitled.is())
229 : : {
230 [ + - ][ + - ]: 2265 : Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject());
231 [ + + ]: 2265 : if( xSubTitle.is())
232 : : aTopLevelContainer.push_back(
233 [ + - ][ + - ]: 2265 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ) ) );
[ + - ][ + - ]
234 : : }
235 : :
236 [ - + ]: 2265 : if( !m_bOrderingForElementSelector )
237 : : {
238 : : // Axis Titles. Note: These are interpreted of being top level
239 [ # # ]: 0 : Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
240 [ # # ]: 0 : for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
241 [ # # ][ # # ]: 0 : lcl_addAxisTitle( aAxes[i], aTopLevelContainer, xModel );
242 : :
243 : : // Diagram
244 [ # # ][ # # ]: 0 : aTopLevelContainer.push_back( aDiaOID );
245 : : }
246 : :
247 [ + - ]: 2265 : if( m_bFlattenDiagram )
248 [ + - ]: 2265 : createDiagramTree( aTopLevelContainer, xChartDocument, xDiagram );
249 : : else
250 : : {
251 [ # # ]: 0 : ObjectHierarchy::tChildContainer aSubContainer;
252 [ # # ]: 0 : createDiagramTree( aSubContainer, xChartDocument, xDiagram );
253 [ # # ]: 0 : if( !aSubContainer.empty() )
254 [ # # ][ # # ]: 0 : m_aChildMap[ aDiaOID ] = aSubContainer;
255 : : }
256 : :
257 [ - + ]: 2265 : if( !m_bOrderingForElementSelector )
258 [ # # ]: 2265 : createLegendTree( aTopLevelContainer, xChartDocument, xDiagram );
259 : : }
260 : :
261 : : // #i12587# support for shapes in chart
262 [ - + ]: 2271 : if ( !m_bOrderingForElementSelector )
263 : : {
264 [ # # ]: 0 : createAdditionalShapesTree( aTopLevelContainer );
265 : : }
266 : :
267 : : // Chart Area
268 [ - + ]: 2271 : if( !m_bOrderingForElementSelector )
269 : : aTopLevelContainer.push_back(
270 [ # # ][ # # ]: 0 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
[ # # ][ # # ]
271 : :
272 [ + - ]: 2271 : if( ! aTopLevelContainer.empty())
273 [ + - ][ + - ]: 2271 : m_aChildMap[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer;
[ + - ][ + - ]
[ + - ]
274 : : }
275 : :
276 : 2265 : void ImplObjectHierarchy::createLegendTree(
277 : : ObjectHierarchy::tChildContainer & rContainer,
278 : : const Reference< XChartDocument > & xChartDoc,
279 : : const Reference< XDiagram > & xDiagram )
280 : : {
281 [ + - ][ + + ]: 2265 : if( xDiagram.is() && LegendHelper::hasLegend( xDiagram ) )
[ + + ]
282 : : {
283 [ + - ][ + - ]: 2185 : ObjectHierarchy::tOID aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram->getLegend(), Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ) );
[ + - ][ + - ]
[ + - ]
284 [ + - ]: 2185 : rContainer.push_back( aLegendOID );
285 : :
286 : : // iterate over child shapes of legend and search for matching CIDs
287 [ - + ]: 2185 : if( m_pExplicitValueProvider )
288 : : {
289 : : Reference< container::XIndexAccess > xLegendShapeContainer(
290 [ # # ][ # # ]: 0 : m_pExplicitValueProvider->getShapeForCID( aLegendOID.getObjectCID() ), uno::UNO_QUERY );
[ # # ]
291 [ # # ]: 0 : ObjectHierarchy::tChildContainer aLegendEntryOIDs;
292 [ # # ]: 0 : lcl_getChildOIDs( aLegendEntryOIDs, xLegendShapeContainer );
293 : :
294 [ # # ][ # # ]: 0 : m_aChildMap[ aLegendOID ] = aLegendEntryOIDs;
295 [ + - ]: 2185 : }
296 : : }
297 : 2265 : }
298 : :
299 : 2265 : void ImplObjectHierarchy::createAxesTree(
300 : : ObjectHierarchy::tChildContainer & rContainer,
301 : : const Reference< XChartDocument > & xChartDoc,
302 : : const Reference< XDiagram > & xDiagram )
303 : : {
304 [ + - ]: 2265 : Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
305 [ + - ]: 2265 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
306 [ + - ]: 2265 : uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
307 [ + - ]: 2265 : bool bSupportsAxesGrids = ChartTypeHelper::isSupportingMainAxis( xChartType, nDimensionCount, 0 );
308 [ + + ]: 2265 : if( bSupportsAxesGrids )
309 : : {
310 [ + - ]: 2226 : Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ true ) );
311 [ - + ]: 2226 : if( !m_bOrderingForElementSelector )
312 : 0 : ::std::transform( aAxes.getConstArray(), aAxes.getConstArray() + aAxes.getLength(),
313 : : ::std::back_inserter( rContainer ),
314 [ # # ]: 0 : lcl_ObjectToOID( xChartDoc ));
[ # # # # ]
[ # # ]
315 : :
316 : : // get all axes, also invisible ones
317 [ + - ][ + - ]: 2226 : aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ false );
[ + - ]
318 : : // Grids
319 [ + - ]: 2226 : Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
320 [ + + ]: 6676 : for( sal_Int32 nA=0; nA<aAxes.getLength(); ++nA )
321 : : {
322 [ + - ]: 4450 : Reference< XAxis > xAxis( aAxes[nA] );
323 [ - + ]: 4450 : if(!xAxis.is())
324 : 0 : continue;
325 : :
326 : 4450 : sal_Int32 nCooSysIndex = 0;
327 : 4450 : sal_Int32 nDimensionIndex = 0;
328 : 4450 : sal_Int32 nAxisIndex = 0;
329 [ + - ]: 4450 : AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
330 [ - + ][ # # ]: 4450 : if( nAxisIndex>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, nDimensionIndex ) )
[ # # ][ - + ]
331 : 0 : continue;
332 : :
333 [ + - ]: 4450 : if( m_bOrderingForElementSelector )
334 : : {
335 : : // axis
336 [ + - ][ + + ]: 4450 : if( AxisHelper::isAxisVisible( xAxis ) )
337 : : rContainer.push_back(
338 [ + - ][ + - ]: 3855 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel ) ) );
[ + - ][ + - ]
339 : :
340 : : // axis title
341 [ + - ][ + - ]: 4450 : lcl_addAxisTitle( aAxes[nA], rContainer, xChartModel );
342 : : }
343 : :
344 [ + - ][ + - ]: 4450 : Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
345 [ + - ][ + + ]: 4450 : if( AxisHelper::isGridVisible( xGridProperties ) )
346 : : {
347 : : //main grid
348 : : rContainer.push_back(
349 [ + - ][ + - ]: 1812 : ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) ) ) );
[ + - ][ + - ]
350 : : }
351 : :
352 [ + - ][ + - ]: 4450 : Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
353 : 4450 : sal_Int32 nSubGrid = 0;
354 [ + + ]: 8900 : for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
355 : : {
356 [ + - ]: 4450 : Reference< beans::XPropertySet > xSubGridProperties( aSubGrids[nSubGrid] );
357 [ - + ][ + - ]: 4450 : if( AxisHelper::isGridVisible( xSubGridProperties ) )
358 : : {
359 : : //sub grid
360 : : rContainer.push_back(
361 [ # # ][ # # ]: 0 : ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) ) ) );
[ # # ][ # # ]
362 : : }
363 : 4450 : }
364 [ + - ][ + - ]: 6676 : }
[ + - ]
365 : 2265 : }
366 : 2265 : }
367 : :
368 : 2265 : void ImplObjectHierarchy::createWallAndFloor(
369 : : ObjectHierarchy::tChildContainer & rContainer,
370 : : const Reference< XDiagram > & xDiagram )
371 : : {
372 : 2265 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
373 : 2265 : bool bIsThreeD = ( nDimensionCount == 3 );
374 : 2265 : bool bHasWall = DiagramHelper::isSupportingFloorAndWall( xDiagram );
375 [ + + ][ + + ]: 2265 : if( bHasWall && bIsThreeD )
376 : : {
377 : : rContainer.push_back(
378 [ + - ][ + - ]: 12 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) ) );
[ + - ][ + - ]
379 : :
380 [ + - ][ + - ]: 12 : Reference< beans::XPropertySet > xFloor( xDiagram->getFloor());
381 [ + - ]: 12 : if( xFloor.is())
382 : : rContainer.push_back(
383 [ + - ][ + - ]: 12 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, rtl::OUString() ) ) );
[ + - ][ + - ]
384 : : }
385 : :
386 : 2265 : }
387 : :
388 : 2265 : void ImplObjectHierarchy::createDiagramTree(
389 : : ObjectHierarchy::tChildContainer & rContainer,
390 : : const Reference< XChartDocument > & xChartDoc,
391 : : const Reference< XDiagram > & xDiagram )
392 : : {
393 [ - + ]: 2265 : if( !m_bOrderingForElementSelector )
394 : : {
395 : 0 : createDataSeriesTree( rContainer, xDiagram );
396 : 0 : createAxesTree( rContainer, xChartDoc, xDiagram );
397 : 0 : createWallAndFloor( rContainer, xDiagram );
398 : : }
399 : : else
400 : : {
401 : 2265 : createAxesTree( rContainer, xChartDoc, xDiagram );
402 : 2265 : createDataSeriesTree( rContainer, xDiagram );
403 : : }
404 : 2265 : }
405 : :
406 : 2265 : void ImplObjectHierarchy::createDataSeriesTree(
407 : : ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
408 : : const Reference< XDiagram > & xDiagram )
409 : : {
410 [ + - ]: 2265 : Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
411 : :
412 : : try
413 : : {
414 : 2265 : sal_Int32 nDiagramIndex = 0;
415 [ + - ]: 2265 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
416 : : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
417 [ + - ][ + - ]: 2265 : xCooSysCnt->getCoordinateSystems());
418 [ + + ]: 4523 : for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
419 : : {
420 [ + - ][ + - ]: 2258 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
421 [ + - ][ + - ]: 2258 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
422 [ + + ]: 4516 : for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypeSeq.getLength(); ++nCTIdx )
423 : : {
424 [ + - ]: 2258 : Reference< XChartType > xChartType( aChartTypeSeq[nCTIdx] );
425 [ + - ]: 2258 : Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
426 [ + - ][ + - ]: 2258 : Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
427 : : const sal_Int32 nNumberOfSeries =
428 [ + - ]: 2258 : ChartTypeHelper::getNumberOfDisplayedSeries( xChartType, aSeriesSeq.getLength());
429 : :
430 [ + + ]: 8954 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<nNumberOfSeries; ++nSeriesIdx )
431 : : {
432 : : OUString aSeriesParticle(
433 : : ObjectIdentifier::createParticleForSeries(
434 [ + - ]: 6696 : nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx ));
435 : : ObjectHierarchy::tOID aSeriesOID(
436 [ + - ][ + - ]: 6696 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ) ) );
437 [ + - ]: 6696 : rOutDiagramSubContainer.push_back( aSeriesOID );
438 : :
439 [ + - ]: 6696 : ObjectHierarchy::tChildContainer aSeriesSubContainer;
440 : :
441 [ + - ][ + - ]: 6696 : Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
442 : :
443 : : // data lablels
444 [ + - ][ - + ]: 6696 : if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries ) )
445 : : {
446 [ # # ]: 0 : rtl::OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) );
447 [ # # ]: 0 : aChildParticle+=(C2U("="));
448 : : aSeriesSubContainer.push_back(
449 [ # # ][ # # ]: 0 : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle ) ) );
[ # # ][ # # ]
450 : : }
451 : :
452 : : // Statistics
453 [ + - ][ + + ]: 6696 : if( ChartTypeHelper::isSupportingStatisticProperties( xChartType, nDimensionCount ) )
454 : : {
455 [ + - ]: 6621 : Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
456 [ + - ]: 6621 : if( xCurveCnt.is())
457 : : {
458 [ + - ][ + - ]: 6621 : Sequence< Reference< chart2::XRegressionCurve > > aCurves( xCurveCnt->getRegressionCurves());
459 [ + + ]: 6637 : for( sal_Int32 nCurveIdx=0; nCurveIdx<aCurves.getLength(); ++nCurveIdx )
460 : : {
461 [ + - ][ + - ]: 16 : bool bIsAverageLine = RegressionCurveHelper::isMeanValueLine( aCurves[nCurveIdx] );
462 : : aSeriesSubContainer.push_back(
463 [ + - ][ + - ]: 16 : ObjectIdentifier( ObjectIdentifier::createDataCurveCID( aSeriesParticle, nCurveIdx, bIsAverageLine ) ) );
[ + - ][ + - ]
464 [ + - ][ - + ]: 16 : if( RegressionCurveHelper::hasEquation( aCurves[nCurveIdx] ) )
[ + - ]
465 : : {
466 : : aSeriesSubContainer.push_back(
467 [ # # ][ # # ]: 0 : ObjectIdentifier( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle, nCurveIdx ) ) );
[ # # ][ # # ]
468 : : }
469 : : }
470 [ + - ]: 6621 : Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
471 : 6621 : Reference< beans::XPropertySet > xErrorBarProp;
472 [ + - + + ]: 26484 : if( xSeriesProp.is() &&
[ + + ][ + - ]
473 [ + - ][ + - ]: 13242 : (xSeriesProp->getPropertyValue( C2U("ErrorBarY")) >>= xErrorBarProp) &&
[ + - ][ + - ]
[ + - ][ + - ]
[ # # # # ]
474 : 6621 : xErrorBarProp.is())
475 : : {
476 : 2439 : sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
477 [ + - ][ + - ]: 2439 : if( ( xErrorBarProp->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
[ + - ][ + - ]
[ - + ][ + - ]
[ + - ][ - +
# # # # ]
478 : : ( nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE ) )
479 : : {
480 : : aSeriesSubContainer.push_back(
481 : : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
482 [ # # ][ # # ]: 2439 : OBJECTTYPE_DATA_ERRORS_Y, OUString(), aSeriesParticle ) ) );
[ # # ][ # # ]
483 : : }
484 : : }
485 : :
486 [ + - ]: 26484 : if( xSeriesProp.is() &&
[ + - - + ]
[ - + ]
487 [ + - ][ + - ]: 13242 : (xSeriesProp->getPropertyValue( C2U("ErrorBarX")) >>= xErrorBarProp) &&
[ + - ][ + - ]
[ + - ][ + - ]
[ # # # # ]
488 : 6621 : xErrorBarProp.is())
489 : : {
490 : 0 : sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
491 [ # # ][ # # ]: 0 : if( ( xErrorBarProp->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
492 : : ( nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE ) )
493 : : {
494 : : aSeriesSubContainer.push_back(
495 : : ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
496 [ # # ][ # # ]: 0 : OBJECTTYPE_DATA_ERRORS_X, OUString(), aSeriesParticle ) ) );
[ # # ][ # # ]
497 : : }
498 [ + - ]: 6621 : }
499 : 6621 : }
500 : : }
501 : :
502 : : // Data Points
503 : : // iterate over child shapes of legend and search for matching CIDs
504 [ - + ]: 6696 : if( m_pExplicitValueProvider )
505 : : {
506 : : Reference< container::XIndexAccess > xSeriesShapeContainer(
507 [ # # ][ # # ]: 0 : m_pExplicitValueProvider->getShapeForCID( aSeriesOID.getObjectCID() ), uno::UNO_QUERY );
[ # # ]
508 [ # # ]: 0 : lcl_getChildOIDs( aSeriesSubContainer, xSeriesShapeContainer );
509 : : }
510 : :
511 [ + + ]: 6696 : if( ! aSeriesSubContainer.empty())
512 [ + - ][ + - ]: 16 : m_aChildMap[ aSeriesOID ] = aSeriesSubContainer;
513 [ + - ]: 6696 : }
514 [ + - ]: 2258 : }
515 [ + - ][ + - ]: 4523 : }
[ # # ]
516 : : }
517 [ # # ]: 0 : catch( const uno::Exception & ex )
518 : : {
519 : : ASSERT_EXCEPTION( ex );
520 : 2265 : }
521 : 2265 : }
522 : :
523 : 0 : void ImplObjectHierarchy::createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer )
524 : : {
525 : : try
526 : : {
527 [ # # ]: 0 : if ( m_pExplicitValueProvider )
528 : : {
529 [ # # ][ # # ]: 0 : Reference< drawing::XDrawPage > xDrawPage( m_pExplicitValueProvider->getDrawModelWrapper()->getMainDrawPage() );
[ # # ]
530 [ # # ]: 0 : Reference< drawing::XShapes > xDrawPageShapes( xDrawPage, uno::UNO_QUERY_THROW );
531 [ # # ]: 0 : Reference< drawing::XShapes > xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage ) );
532 [ # # ][ # # ]: 0 : sal_Int32 nCount = xDrawPageShapes->getCount();
533 [ # # ]: 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
534 : : {
535 : 0 : Reference< drawing::XShape > xShape;
536 [ # # ][ # # ]: 0 : if ( xDrawPageShapes->getByIndex( i ) >>= xShape )
[ # # ][ # # ]
537 : : {
538 [ # # ][ # # ]: 0 : if ( xShape.is() && xShape != xChartRoot )
[ # # ][ # # ]
539 : : {
540 [ # # ][ # # ]: 0 : rContainer.push_back( ObjectIdentifier( xShape ) );
[ # # ]
541 : : }
542 : : }
543 [ # # ]: 0 : }
544 : : }
545 : : }
546 : 0 : catch ( const uno::Exception& ex )
547 : : {
548 : : ASSERT_EXCEPTION( ex );
549 : : }
550 : 0 : }
551 : :
552 : 0 : bool ImplObjectHierarchy::hasChildren( const ObjectHierarchy::tOID& rParent )
553 : : {
554 [ # # ]: 0 : if ( rParent.isValid() )
555 : : {
556 [ # # ][ # # ]: 0 : tChildMap::const_iterator aIt( m_aChildMap.find( rParent ));
557 [ # # ][ # # ]: 0 : if( aIt != m_aChildMap.end())
[ # # ]
558 [ # # ]: 0 : return ! (aIt->second.empty());
559 : : }
560 : 0 : return false;
561 : : }
562 : :
563 : 23605 : ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID& rParent )
564 : : {
565 [ + - ]: 23605 : if ( rParent.isValid() )
566 : : {
567 [ + - ][ + - ]: 23605 : tChildMap::const_iterator aIt( m_aChildMap.find( rParent ));
568 [ + - ][ + - ]: 23605 : if( aIt != m_aChildMap.end())
[ + + ]
569 [ + - ][ + - ]: 23605 : return aIt->second;
570 : : }
571 : 23605 : return ObjectHierarchy::tChildContainer();
572 : : }
573 : :
574 : 0 : ObjectHierarchy::tChildContainer ImplObjectHierarchy::getSiblings( const ObjectHierarchy::tOID& rNode )
575 : : {
576 [ # # ][ # # ]: 0 : if ( rNode.isValid() && !ObjectHierarchy::isRootNode( rNode ) )
[ # # ]
577 : : {
578 [ # # ][ # # ]: 0 : for( tChildMap::const_iterator aIt( m_aChildMap.begin());
[ # # ][ # # ]
579 [ # # ]: 0 : aIt != m_aChildMap.end(); ++aIt )
580 : : {
581 : : ObjectHierarchy::tChildContainer::const_iterator aElemIt(
582 [ # # ][ # # ]: 0 : ::std::find( aIt->second.begin(), aIt->second.end(), rNode ));
[ # # ]
583 [ # # ][ # # ]: 0 : if( aElemIt != aIt->second.end())
[ # # ]
584 [ # # ][ # # ]: 0 : return aIt->second;
585 : : }
586 : : }
587 : 0 : return ObjectHierarchy::tChildContainer();
588 : : }
589 : :
590 : 0 : ObjectHierarchy::tOID ImplObjectHierarchy::getParentImpl(
591 : : const ObjectHierarchy::tOID & rParentOID,
592 : : const ObjectHierarchy::tOID & rOID )
593 : : {
594 : : // search children
595 [ # # ]: 0 : ObjectHierarchy::tChildContainer aChildren( getChildren( rParentOID ));
596 : : ObjectHierarchy::tChildContainer::const_iterator aIt(
597 [ # # ][ # # ]: 0 : ::std::find( aChildren.begin(), aChildren.end(), rOID ));
598 : : // recursion end
599 [ # # ][ # # ]: 0 : if( aIt != aChildren.end())
600 [ # # ]: 0 : return rParentOID;
601 : :
602 [ # # ][ # # ]: 0 : for( aIt = aChildren.begin(); aIt != aChildren.end(); ++aIt )
[ # # ][ # # ]
603 : : {
604 : : // recursion
605 [ # # ][ # # ]: 0 : ObjectHierarchy::tOID aTempParent( getParentImpl( *aIt, rOID ));
606 [ # # ][ # # ]: 0 : if ( aTempParent.isValid() )
607 : : {
608 : : // exit on success
609 [ # # ]: 0 : return aTempParent;
610 : : }
611 [ # # ][ # # ]: 0 : }
612 : :
613 : : // exit on fail
614 [ # # ]: 0 : return ObjectHierarchy::tOID();
615 : : }
616 : :
617 : 0 : ObjectHierarchy::tOID ImplObjectHierarchy::getParent(
618 : : const ObjectHierarchy::tOID & rOID )
619 : : {
620 [ # # ]: 0 : return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID );
621 : : }
622 : :
623 : : } // namespace impl
624 : :
625 : :
626 : 2271 : ObjectHierarchy::ObjectHierarchy(
627 : : const Reference< XChartDocument > & xChartDocument,
628 : : ExplicitValueProvider * pExplicitValueProvider /* = 0 */,
629 : : bool bFlattenDiagram /* = false */,
630 : : bool bOrderingForElementSelector /* = false */) :
631 [ + - ]: 2271 : m_apImpl( new impl::ImplObjectHierarchy( xChartDocument, pExplicitValueProvider, bFlattenDiagram, bOrderingForElementSelector ))
632 : 2271 : {}
633 : :
634 : 2271 : ObjectHierarchy::~ObjectHierarchy()
635 : 2271 : {}
636 : :
637 : 4542 : ObjectHierarchy::tOID ObjectHierarchy::getRootNodeOID()
638 : : {
639 [ + - ]: 4542 : return ObjectIdentifier( C2U( "ROOT" ) );
640 : : }
641 : :
642 : 0 : bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID& rOID )
643 : : {
644 [ # # ]: 0 : return ( rOID == ObjectHierarchy::getRootNodeOID() );
645 : : }
646 : :
647 : 0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getTopLevelChildren() const
648 : : {
649 [ # # ]: 0 : return m_apImpl->getChildren( ObjectHierarchy::getRootNodeOID());
650 : : }
651 : :
652 : 0 : bool ObjectHierarchy::hasChildren( const tOID& rParent ) const
653 : : {
654 : 0 : return m_apImpl->hasChildren( rParent );
655 : : }
656 : :
657 : 23605 : ObjectHierarchy::tChildContainer ObjectHierarchy::getChildren(
658 : : const ObjectHierarchy::tOID& rParent ) const
659 : : {
660 [ + - ]: 23605 : if ( rParent.isValid() )
661 : 23605 : return m_apImpl->getChildren( rParent );
662 : :
663 : 23605 : return ObjectHierarchy::tChildContainer();
664 : : }
665 : :
666 : 0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getSiblings(
667 : : const ObjectHierarchy::tOID& rNode ) const
668 : : {
669 [ # # ][ # # ]: 0 : if ( rNode.isValid() && !isRootNode( rNode ) )
[ # # ]
670 : 0 : return m_apImpl->getSiblings( rNode );
671 : :
672 : 0 : return ObjectHierarchy::tChildContainer();
673 : : }
674 : :
675 : 0 : ObjectHierarchy::tOID ObjectHierarchy::getParent(
676 : : const ObjectHierarchy::tOID& rNode ) const
677 : : {
678 : 0 : return m_apImpl->getParent( rNode );
679 : : }
680 : :
681 : 0 : sal_Int32 ObjectHierarchy::getIndexInParent(
682 : : const ObjectHierarchy::tOID& rNode ) const
683 : : {
684 [ # # ]: 0 : tOID aParentOID( m_apImpl->getParent( rNode ));
685 [ # # ]: 0 : tChildContainer aChildren( m_apImpl->getChildren( aParentOID ) );
686 [ # # ]: 0 : tChildContainer::const_iterator aIt( aChildren.begin() );
687 [ # # ][ # # ]: 0 : for( sal_Int32 nIndex = 0; aIt != aChildren.end(); ++nIndex, ++aIt )
[ # # ]
688 : : {
689 [ # # ][ # # ]: 0 : if ( *aIt == rNode )
[ # # ]
690 : 0 : return nIndex;
691 : : }
692 [ # # ]: 0 : return -1;
693 : : }
694 : :
695 : : // ================================================================================
696 : :
697 : 0 : ObjectKeyNavigation::ObjectKeyNavigation(
698 : : const ObjectHierarchy::tOID & rCurrentOID,
699 : : const Reference< chart2::XChartDocument > & xChartDocument,
700 : : ExplicitValueProvider * pExplicitValueProvider /* = 0 */ ) :
701 : : m_aCurrentOID( rCurrentOID ),
702 : : m_xChartDocument( xChartDocument ),
703 : : m_pExplicitValueProvider( pExplicitValueProvider ),
704 : 0 : m_bStepDownInDiagram( true )
705 : : {
706 [ # # ][ # # ]: 0 : if ( !m_aCurrentOID.isValid() )
707 : : {
708 [ # # ][ # # ]: 0 : setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
[ # # ]
709 : : }
710 : 0 : }
711 : :
712 : 0 : bool ObjectKeyNavigation::handleKeyEvent(
713 : : const awt::KeyEvent & rEvent )
714 : : {
715 : 0 : bool bResult = false;
716 : :
717 [ # # # # : 0 : switch( rEvent.KeyCode )
# # ]
718 : : {
719 : : case awt::Key::TAB:
720 [ # # ]: 0 : if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
721 : 0 : bResult = previous();
722 : : else
723 : 0 : bResult = next();
724 : 0 : break;
725 : : case awt::Key::HOME:
726 : 0 : bResult = first();
727 : 0 : break;
728 : : case awt::Key::END:
729 : 0 : bResult = last();
730 : 0 : break;
731 : : case awt::Key::F3:
732 [ # # ]: 0 : if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
733 : 0 : bResult = up();
734 : : else
735 : 0 : bResult = down();
736 : 0 : break;
737 : : case awt::Key::ESCAPE:
738 [ # # ]: 0 : setCurrentSelection( ObjectIdentifier() );
739 : 0 : bResult = true;
740 : 0 : break;
741 : : default:
742 : 0 : bResult = false;
743 : 0 : break;
744 : : }
745 : 0 : return bResult;
746 : : }
747 : :
748 : 0 : void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID& rOID )
749 : : {
750 : 0 : m_aCurrentOID = rOID;
751 : 0 : }
752 : :
753 : 0 : ObjectHierarchy::tOID ObjectKeyNavigation::getCurrentSelection() const
754 : : {
755 : 0 : return m_aCurrentOID;
756 : : }
757 : :
758 : 0 : bool ObjectKeyNavigation::first()
759 : : {
760 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
761 [ # # ][ # # ]: 0 : ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
[ # # ]
762 : 0 : bool bResult = !aSiblings.empty();
763 [ # # ]: 0 : if( bResult )
764 [ # # ][ # # ]: 0 : setCurrentSelection( aSiblings.front());
765 : : else
766 [ # # ]: 0 : bResult = veryFirst();
767 [ # # ]: 0 : return bResult;
768 : : }
769 : :
770 : 0 : bool ObjectKeyNavigation::last()
771 : : {
772 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
773 [ # # ][ # # ]: 0 : ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
[ # # ]
774 : 0 : bool bResult = !aSiblings.empty();
775 [ # # ]: 0 : if( bResult )
776 [ # # ][ # # ]: 0 : setCurrentSelection( aSiblings.back());
777 : : else
778 [ # # ]: 0 : bResult = veryLast();
779 [ # # ]: 0 : return bResult;
780 : : }
781 : :
782 : 0 : bool ObjectKeyNavigation::next()
783 : : {
784 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
785 [ # # ][ # # ]: 0 : ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
[ # # ]
786 : 0 : bool bResult = !aSiblings.empty();
787 [ # # ]: 0 : if( bResult )
788 : : {
789 : : ObjectHierarchy::tChildContainer::const_iterator aIt(
790 [ # # ][ # # ]: 0 : ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
[ # # ][ # # ]
791 : : OSL_ASSERT( aIt != aSiblings.end());
792 [ # # ][ # # ]: 0 : if( ++aIt == aSiblings.end())
[ # # ]
793 [ # # ]: 0 : aIt = aSiblings.begin();
794 [ # # ][ # # ]: 0 : setCurrentSelection( *aIt );
795 : : }
796 : : else
797 [ # # ]: 0 : bResult = veryFirst();
798 : :
799 [ # # ]: 0 : return bResult;
800 : : }
801 : :
802 : 0 : bool ObjectKeyNavigation::previous()
803 : : {
804 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
805 [ # # ][ # # ]: 0 : ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection()));
[ # # ]
806 : 0 : bool bResult = !aSiblings.empty();
807 [ # # ]: 0 : if( bResult )
808 : : {
809 : : ObjectHierarchy::tChildContainer::const_iterator aIt(
810 [ # # ][ # # ]: 0 : ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
[ # # ][ # # ]
811 : : OSL_ASSERT( aIt != aSiblings.end());
812 [ # # ][ # # ]: 0 : if( aIt == aSiblings.begin())
813 [ # # ]: 0 : aIt = aSiblings.end();
814 [ # # ]: 0 : --aIt;
815 [ # # ][ # # ]: 0 : setCurrentSelection( *aIt );
816 : : }
817 : : else
818 [ # # ]: 0 : bResult = veryLast();
819 [ # # ]: 0 : return bResult;
820 : : }
821 : :
822 : 0 : bool ObjectKeyNavigation::up()
823 : : {
824 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
825 [ # # ][ # # ]: 0 : bool bResult = !ObjectHierarchy::isRootNode( getCurrentSelection());
[ # # ]
826 [ # # ]: 0 : if( bResult )
827 [ # # ][ # # ]: 0 : setCurrentSelection( aHierarchy.getParent( getCurrentSelection()));
[ # # ][ # # ]
[ # # ]
828 [ # # ]: 0 : return bResult;
829 : : }
830 : :
831 : 0 : bool ObjectKeyNavigation::down()
832 : : {
833 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
834 [ # # ][ # # ]: 0 : bool bResult = aHierarchy.hasChildren( getCurrentSelection());
[ # # ]
835 [ # # ]: 0 : if( bResult )
836 : : {
837 [ # # ][ # # ]: 0 : ObjectHierarchy::tChildContainer aChildren = aHierarchy.getChildren( getCurrentSelection());
[ # # ]
838 : : OSL_ASSERT( !aChildren.empty());
839 [ # # ][ # # ]: 0 : setCurrentSelection( aChildren.front());
840 : : }
841 [ # # ]: 0 : return bResult;
842 : : }
843 : :
844 : 0 : bool ObjectKeyNavigation::veryFirst()
845 : : {
846 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
847 [ # # ]: 0 : ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
848 : 0 : bool bResult = !aChildren.empty();
849 [ # # ]: 0 : if( bResult )
850 [ # # ][ # # ]: 0 : setCurrentSelection( aChildren.front());
851 [ # # ]: 0 : return bResult;
852 : : }
853 : :
854 : 0 : bool ObjectKeyNavigation::veryLast()
855 : : {
856 [ # # ]: 0 : ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
857 [ # # ]: 0 : ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
858 : 0 : bool bResult = !aChildren.empty();
859 [ # # ]: 0 : if( bResult )
860 [ # # ][ # # ]: 0 : setCurrentSelection( aChildren.back());
861 [ # # ]: 0 : return bResult;
862 : : }
863 : :
864 : : } // namespace chart
865 : :
866 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|