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 : #include "DiagramHelper.hxx"
21 : #include "LegendHelper.hxx"
22 : #include "PropertyHelper.hxx"
23 : #include "macros.hxx"
24 : #include "DataSeriesHelper.hxx"
25 : #include "AxisHelper.hxx"
26 : #include "ContainerHelper.hxx"
27 : #include "ChartTypeHelper.hxx"
28 : #include "ChartModelHelper.hxx"
29 : #include "CommonConverters.hxx"
30 : #include "ExplicitCategoriesProvider.hxx"
31 : #include "servicenames_charttypes.hxx"
32 : #include "RelativePositionHelper.hxx"
33 : #include "ControllerLockGuard.hxx"
34 : #include "NumberFormatterWrapper.hxx"
35 :
36 : #include <com/sun/star/chart/MissingValueTreatment.hpp>
37 : #include <com/sun/star/chart/XChartDocument.hpp>
38 : #include <com/sun/star/chart/XDiagramPositioning.hpp>
39 : #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
40 : #include <com/sun/star/chart2/XTitled.hpp>
41 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
42 : #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
43 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
44 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
45 : #include <com/sun/star/chart2/InterpretedData.hpp>
46 : #include <com/sun/star/chart2/AxisType.hpp>
47 : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
48 : #include <com/sun/star/chart2/RelativePosition.hpp>
49 : #include <com/sun/star/chart2/RelativeSize.hpp>
50 :
51 : #include <com/sun/star/util/NumberFormat.hpp>
52 : #include <com/sun/star/util/XModifiable.hpp>
53 : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
54 :
55 : #include <unotools/saveopt.hxx>
56 : #include <rtl/math.hxx>
57 : #include <svl/zformat.hxx>
58 : // header for class Application
59 : #include <vcl/svapp.hxx>
60 : #include <vcl/settings.hxx>
61 :
62 : using namespace ::com::sun::star;
63 : using namespace ::com::sun::star::chart2;
64 : using namespace ::std;
65 :
66 : using ::com::sun::star::uno::Reference;
67 : using ::com::sun::star::uno::Sequence;
68 : using ::com::sun::star::uno::Any;
69 : using ::com::sun::star::chart2::XAnyDescriptionAccess;
70 :
71 : namespace chart
72 : {
73 :
74 : DiagramHelper::tTemplateWithServiceName
75 0 : DiagramHelper::getTemplateForDiagram(
76 : const Reference< XDiagram > & xDiagram,
77 : const Reference< lang::XMultiServiceFactory > & xChartTypeManager,
78 : const OUString & rPreferredTemplateName )
79 : {
80 0 : DiagramHelper::tTemplateWithServiceName aResult;
81 :
82 0 : if( ! (xChartTypeManager.is() && xDiagram.is()))
83 0 : return aResult;
84 :
85 0 : Sequence< OUString > aServiceNames( xChartTypeManager->getAvailableServiceNames());
86 0 : const sal_Int32 nLength = aServiceNames.getLength();
87 :
88 0 : bool bHasPreferredTemplate = !rPreferredTemplateName.isEmpty();
89 0 : bool bTemplateFound = false;
90 :
91 0 : if( bHasPreferredTemplate )
92 : {
93 : Reference< XChartTypeTemplate > xTempl(
94 0 : xChartTypeManager->createInstance( rPreferredTemplateName ), uno::UNO_QUERY );
95 :
96 0 : if( xTempl.is() &&
97 0 : xTempl->matchesTemplate( xDiagram, sal_True ))
98 : {
99 0 : aResult.first = xTempl;
100 0 : aResult.second = rPreferredTemplateName;
101 0 : bTemplateFound = true;
102 0 : }
103 : }
104 :
105 0 : for( sal_Int32 i = 0; ! bTemplateFound && i < nLength; ++i )
106 : {
107 : try
108 : {
109 0 : if( ! bHasPreferredTemplate ||
110 0 : ! rPreferredTemplateName.equals( aServiceNames[ i ] ))
111 : {
112 : Reference< XChartTypeTemplate > xTempl(
113 0 : xChartTypeManager->createInstance( aServiceNames[ i ] ), uno::UNO_QUERY_THROW );
114 :
115 0 : if (xTempl.is() && xTempl->matchesTemplate(xDiagram, true))
116 : {
117 0 : aResult.first = xTempl;
118 0 : aResult.second = aServiceNames[ i ];
119 0 : bTemplateFound = true;
120 0 : }
121 : }
122 : }
123 0 : catch( const uno::Exception & ex )
124 : {
125 : ASSERT_EXCEPTION( ex );
126 : }
127 : }
128 :
129 0 : return aResult;
130 : }
131 :
132 0 : void DiagramHelper::setVertical(
133 : const Reference< XDiagram > & xDiagram,
134 : bool bVertical /* = true */ )
135 : {
136 : try
137 : {
138 0 : Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
139 0 : if( xCnt.is())
140 : {
141 : Sequence< Reference< XCoordinateSystem > > aCooSys(
142 0 : xCnt->getCoordinateSystems());
143 0 : uno::Any aValue;
144 0 : aValue <<= bVertical;
145 0 : for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
146 : {
147 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSys[i] );
148 0 : Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
149 0 : bool bChanged = false;
150 0 : if( xProp.is() )
151 : {
152 0 : bool bOldSwap = false;
153 0 : if( !(xProp->getPropertyValue( "SwapXAndYAxis" ) >>= bOldSwap)
154 0 : || bVertical != bOldSwap )
155 0 : bChanged = true;
156 :
157 0 : if( bChanged )
158 0 : xProp->setPropertyValue( "SwapXAndYAxis", aValue );
159 : }
160 0 : if( xCooSys.is() )
161 : {
162 0 : const sal_Int32 nDimensionCount( xCooSys->getDimension() );
163 0 : sal_Int32 nDimIndex = 0;
164 0 : for(nDimIndex=0; nDimIndex<nDimensionCount; ++nDimIndex)
165 : {
166 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex);
167 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
168 : {
169 0 : Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimIndex,nI ));
170 0 : if( xAxis.is() )
171 : {
172 : //adapt title rotation only when axis swapping has changed
173 0 : if( bChanged )
174 : {
175 0 : Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
176 0 : if( xTitled.is())
177 : {
178 0 : Reference< beans::XPropertySet > xTitleProps( xTitled->getTitleObject(), uno::UNO_QUERY );
179 0 : if( !xTitleProps.is() )
180 0 : continue;
181 0 : double fAngleDegree = 0.0;
182 0 : xTitleProps->getPropertyValue( "TextRotation" ) >>= fAngleDegree;
183 0 : if( !::rtl::math::approxEqual( fAngleDegree, 0.0 )
184 0 : && !::rtl::math::approxEqual( fAngleDegree, 90.0 ) )
185 0 : continue;
186 :
187 0 : double fNewAngleDegree = 0.0;
188 0 : if( !bVertical && nDimIndex == 1 )
189 0 : fNewAngleDegree = 90.0;
190 0 : else if( bVertical && nDimIndex == 0 )
191 0 : fNewAngleDegree = 90.0;
192 :
193 0 : xTitleProps->setPropertyValue( "TextRotation", uno::makeAny( fNewAngleDegree ));
194 0 : }
195 : }
196 : }
197 0 : }
198 : }
199 : }
200 0 : }
201 0 : }
202 : }
203 0 : catch( const uno::Exception & ex )
204 : {
205 : ASSERT_EXCEPTION( ex );
206 : }
207 0 : }
208 :
209 0 : bool DiagramHelper::getVertical( const uno::Reference< chart2::XDiagram > & xDiagram,
210 : bool& rbFound, bool& rbAmbiguous )
211 : {
212 0 : bool bValue = false;
213 0 : rbFound = false;
214 0 : rbAmbiguous = false;
215 :
216 0 : Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
217 0 : if( xCnt.is())
218 : {
219 : Sequence< Reference< XCoordinateSystem > > aCooSys(
220 0 : xCnt->getCoordinateSystems());
221 0 : for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
222 : {
223 0 : Reference< beans::XPropertySet > xProp( aCooSys[i], uno::UNO_QUERY );
224 0 : if( xProp.is())
225 : {
226 0 : bool bCurrent = false;
227 0 : if( xProp->getPropertyValue( "SwapXAndYAxis" ) >>= bCurrent )
228 : {
229 0 : if( !rbFound )
230 : {
231 0 : bValue = bCurrent;
232 0 : rbFound = true;
233 : }
234 0 : else if( bCurrent != bValue )
235 : {
236 : // ambiguous -> choose always first found
237 0 : rbAmbiguous = true;
238 : }
239 : }
240 : }
241 0 : }
242 : }
243 0 : return bValue;
244 : }
245 :
246 0 : void DiagramHelper::setStackMode(
247 : const Reference< XDiagram > & xDiagram,
248 : StackMode eStackMode,
249 : bool bOnlyAtFirstChartType /* = true */
250 : )
251 : {
252 : try
253 : {
254 0 : if( eStackMode == StackMode_AMBIGUOUS )
255 0 : return;
256 :
257 0 : bool bValueFound = false;
258 0 : bool bIsAmbiguous = false;
259 0 : StackMode eOldStackMode = DiagramHelper::getStackMode( xDiagram, bValueFound, bIsAmbiguous );
260 :
261 0 : if( eStackMode == eOldStackMode && !bIsAmbiguous )
262 0 : return;
263 :
264 0 : StackingDirection eNewDirection = StackingDirection_NO_STACKING;
265 0 : if( eStackMode == StackMode_Y_STACKED || eStackMode == StackMode_Y_STACKED_PERCENT )
266 0 : eNewDirection = StackingDirection_Y_STACKING;
267 0 : else if( eStackMode == StackMode_Z_STACKED )
268 0 : eNewDirection = StackingDirection_Z_STACKING;
269 :
270 0 : uno::Any aNewDirection( uno::makeAny(eNewDirection) );
271 :
272 0 : bool bPercent = false;
273 0 : if( eStackMode == StackMode_Y_STACKED_PERCENT )
274 0 : bPercent = true;
275 :
276 : //iterate through all coordinate systems
277 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
278 0 : if( !xCooSysContainer.is() )
279 0 : return;
280 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
281 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
282 : {
283 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
284 : //set correct percent stacking
285 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(1);
286 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
287 : {
288 0 : Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
289 0 : if( xAxis.is())
290 : {
291 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
292 0 : if( (aScaleData.AxisType==AxisType::PERCENT) != bPercent )
293 : {
294 0 : if( bPercent )
295 0 : aScaleData.AxisType = AxisType::PERCENT;
296 : else
297 0 : aScaleData.AxisType = AxisType::REALNUMBER;
298 0 : xAxis->setScaleData( aScaleData );
299 0 : }
300 : }
301 0 : }
302 : //iterate through all chart types in the current coordinate system
303 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
304 0 : if( !xChartTypeContainer.is() )
305 0 : continue;
306 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
307 0 : sal_Int32 nMax = aChartTypeList.getLength();
308 0 : if( bOnlyAtFirstChartType
309 0 : && nMax >= 1 )
310 0 : nMax = 1;
311 0 : for( sal_Int32 nT = 0; nT < nMax; ++nT )
312 : {
313 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
314 :
315 : //iterate through all series in this chart type
316 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
317 : OSL_ASSERT( xDataSeriesContainer.is());
318 0 : if( !xDataSeriesContainer.is() )
319 0 : continue;
320 :
321 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
322 0 : for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
323 : {
324 0 : Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
325 0 : if(xProp.is())
326 0 : xProp->setPropertyValue( "StackingDirection", aNewDirection );
327 0 : }
328 0 : }
329 0 : }
330 : }
331 0 : catch( const uno::Exception & ex )
332 : {
333 : ASSERT_EXCEPTION( ex );
334 : }
335 : }
336 :
337 0 : StackMode DiagramHelper::getStackMode( const Reference< XDiagram > & xDiagram, bool& rbFound, bool& rbAmbiguous )
338 : {
339 0 : rbFound=false;
340 0 : rbAmbiguous=false;
341 :
342 0 : StackMode eGlobalStackMode = StackMode_NONE;
343 :
344 : //iterate through all coordinate systems
345 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
346 0 : if( !xCooSysContainer.is() )
347 0 : return eGlobalStackMode;
348 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
349 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
350 : {
351 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
352 :
353 : //iterate through all chart types in the current coordinate system
354 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
355 0 : if( !xChartTypeContainer.is() )
356 0 : continue;
357 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
358 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
359 : {
360 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
361 :
362 : StackMode eLocalStackMode = DiagramHelper::getStackModeFromChartType(
363 0 : xChartType, rbFound, rbAmbiguous, xCooSys );
364 :
365 0 : if( rbFound && eLocalStackMode != eGlobalStackMode && nT>0 )
366 : {
367 0 : rbAmbiguous = true;
368 0 : return eGlobalStackMode;
369 : }
370 :
371 0 : eGlobalStackMode = eLocalStackMode;
372 0 : }
373 0 : }
374 :
375 0 : return eGlobalStackMode;
376 : }
377 :
378 0 : StackMode DiagramHelper::getStackModeFromChartType(
379 : const Reference< XChartType > & xChartType,
380 : bool& rbFound, bool& rbAmbiguous,
381 : const Reference< XCoordinateSystem > & xCorrespondingCoordinateSystem )
382 : {
383 0 : StackMode eStackMode = StackMode_NONE;
384 0 : rbFound = false;
385 0 : rbAmbiguous = false;
386 :
387 : try
388 : {
389 0 : Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
390 0 : Sequence< Reference< chart2::XDataSeries > > aSeries( xDSCnt->getDataSeries());
391 :
392 0 : chart2::StackingDirection eCommonDirection = chart2::StackingDirection_NO_STACKING;
393 0 : bool bDirectionInitialized = false;
394 :
395 : // first series is irrelvant for stacking, start with second, unless
396 : // there is only one series
397 0 : const sal_Int32 nSeriesCount = aSeries.getLength();
398 0 : sal_Int32 i = (nSeriesCount == 1) ? 0: 1;
399 0 : for( ; i<nSeriesCount; ++i )
400 : {
401 0 : rbFound = true;
402 0 : Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY_THROW );
403 0 : chart2::StackingDirection eCurrentDirection = eCommonDirection;
404 : // property is not MAYBEVOID
405 0 : bool bSuccess = ( xProp->getPropertyValue( "StackingDirection" ) >>= eCurrentDirection );
406 : OSL_ASSERT( bSuccess );
407 : (void)(bSuccess); // avoid warning in non-debug builds
408 0 : if( ! bDirectionInitialized )
409 : {
410 0 : eCommonDirection = eCurrentDirection;
411 0 : bDirectionInitialized = true;
412 : }
413 : else
414 : {
415 0 : if( eCommonDirection != eCurrentDirection )
416 : {
417 0 : rbAmbiguous = true;
418 0 : break;
419 : }
420 : }
421 0 : }
422 :
423 0 : if( rbFound )
424 : {
425 0 : if( eCommonDirection == chart2::StackingDirection_Z_STACKING )
426 0 : eStackMode = StackMode_Z_STACKED;
427 0 : else if( eCommonDirection == chart2::StackingDirection_Y_STACKING )
428 : {
429 0 : eStackMode = StackMode_Y_STACKED;
430 :
431 : // percent stacking
432 0 : if( xCorrespondingCoordinateSystem.is() )
433 : {
434 0 : if( 1 < xCorrespondingCoordinateSystem->getDimension() )
435 : {
436 0 : sal_Int32 nAxisIndex = 0;
437 0 : if( nSeriesCount )
438 0 : nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(aSeries[0]);
439 :
440 : Reference< chart2::XAxis > xAxis(
441 0 : xCorrespondingCoordinateSystem->getAxisByDimension( 1,nAxisIndex ));
442 0 : if( xAxis.is())
443 : {
444 0 : chart2::ScaleData aScaleData = xAxis->getScaleData();
445 0 : if( aScaleData.AxisType==chart2::AxisType::PERCENT )
446 0 : eStackMode = StackMode_Y_STACKED_PERCENT;
447 0 : }
448 : }
449 : }
450 : }
451 0 : }
452 : }
453 0 : catch( const uno::Exception & ex )
454 : {
455 : ASSERT_EXCEPTION( ex );
456 : }
457 :
458 0 : return eStackMode;
459 : }
460 :
461 0 : sal_Int32 DiagramHelper::getDimension( const Reference< XDiagram > & xDiagram )
462 : {
463 : // -1: not yet set
464 0 : sal_Int32 nResult = -1;
465 :
466 : try
467 : {
468 0 : Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
469 0 : if( xCooSysCnt.is() )
470 : {
471 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
472 0 : xCooSysCnt->getCoordinateSystems());
473 :
474 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
475 : {
476 0 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
477 0 : if(xCooSys.is())
478 : {
479 0 : nResult = xCooSys->getDimension();
480 0 : break;
481 : }
482 0 : }
483 0 : }
484 : }
485 0 : catch( const uno::Exception & ex )
486 : {
487 : ASSERT_EXCEPTION( ex );
488 : }
489 :
490 0 : return nResult;
491 : }
492 :
493 0 : void DiagramHelper::setDimension(
494 : const Reference< XDiagram > & xDiagram,
495 : sal_Int32 nNewDimensionCount )
496 : {
497 0 : if( ! xDiagram.is())
498 0 : return;
499 :
500 0 : if( DiagramHelper::getDimension( xDiagram ) == nNewDimensionCount )
501 0 : return;
502 :
503 : try
504 : {
505 0 : bool rbFound = false;
506 0 : bool rbAmbiguous = true;
507 0 : StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous );
508 0 : bool bIsSupportingOnlyDeepStackingFor3D=false;
509 :
510 : //change all coordinate systems:
511 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
512 0 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
513 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
514 : {
515 0 : Reference< XCoordinateSystem > xOldCooSys( aCooSysList[nCS], uno::UNO_QUERY );
516 0 : Reference< XCoordinateSystem > xNewCooSys;
517 :
518 0 : Reference< XChartTypeContainer > xChartTypeContainer( xOldCooSys, uno::UNO_QUERY );
519 0 : if( !xChartTypeContainer.is() )
520 0 : continue;
521 :
522 0 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
523 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
524 : {
525 0 : Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY );
526 0 : bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType );
527 0 : if(!xNewCooSys.is())
528 : {
529 0 : xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount );
530 0 : break;
531 : }
532 : //@todo make sure that all following charttypes are also capable of the new dimension
533 : //otherwise separate them in a different group
534 : //BM: might be done in replaceCoordinateSystem()
535 0 : }
536 :
537 : // replace the old coordinate system at all places where it was used
538 0 : DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys );
539 0 : }
540 :
541 : //correct stack mode if necessary
542 0 : if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D )
543 0 : DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED );
544 0 : else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED )
545 0 : DiagramHelper::setStackMode( xDiagram, StackMode_NONE );
546 : }
547 0 : catch( const uno::Exception & ex )
548 : {
549 : ASSERT_EXCEPTION( ex );
550 : }
551 : }
552 :
553 0 : void DiagramHelper::replaceCoordinateSystem(
554 : const Reference< XDiagram > & xDiagram,
555 : const Reference< XCoordinateSystem > & xCooSysToReplace,
556 : const Reference< XCoordinateSystem > & xReplacement )
557 : {
558 : OSL_ASSERT( xDiagram.is());
559 0 : if( ! xDiagram.is())
560 0 : return;
561 :
562 : // update the coordinate-system container
563 0 : Reference< XCoordinateSystemContainer > xCont( xDiagram, uno::UNO_QUERY );
564 0 : if( xCont.is())
565 : {
566 : try
567 : {
568 0 : Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
569 :
570 : // move chart types of xCooSysToReplace to xReplacement
571 0 : Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW );
572 0 : Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW );
573 0 : xCTCntReplacement->setChartTypes( xCTCntCooSys->getChartTypes());
574 :
575 0 : xCont->removeCoordinateSystem( xCooSysToReplace );
576 0 : xCont->addCoordinateSystem( xReplacement );
577 :
578 0 : if( xCategories.is() )
579 0 : DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram );
580 : }
581 0 : catch( const uno::Exception & ex )
582 : {
583 : ASSERT_EXCEPTION( ex );
584 : }
585 0 : }
586 : }
587 :
588 0 : bool DiagramHelper::isSeriesAttachedToMainAxis(
589 : const uno::Reference< chart2::XDataSeries >& xDataSeries )
590 : {
591 0 : sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
592 0 : return (nAxisIndex==0);
593 : }
594 :
595 0 : bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis
596 : , const uno::Reference< chart2::XDataSeries >& xDataSeries
597 : , const uno::Reference< chart2::XDiagram >& xDiagram
598 : , const uno::Reference< uno::XComponentContext > & xContext
599 : , bool bAdaptAxes )
600 : {
601 0 : bool bChanged = false;
602 :
603 : //set property at axis
604 0 : Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
605 0 : if( !xProp.is() )
606 0 : return bChanged;
607 :
608 0 : sal_Int32 nNewAxisIndex = bAttachToMainAxis ? 0 : 1;
609 0 : sal_Int32 nOldAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
610 0 : uno::Reference< chart2::XAxis > xOldAxis( DiagramHelper::getAttachedAxis( xDataSeries, xDiagram ) );
611 :
612 0 : if( nOldAxisIndex != nNewAxisIndex )
613 : {
614 : try
615 : {
616 0 : xProp->setPropertyValue( "AttachedAxisIndex", uno::makeAny( nNewAxisIndex ) );
617 0 : bChanged = true;
618 : }
619 0 : catch( const uno::Exception & ex )
620 : {
621 : ASSERT_EXCEPTION( ex );
622 : }
623 : }
624 :
625 0 : if( bChanged && xDiagram.is() )
626 : {
627 0 : uno::Reference< XAxis > xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis, xDiagram ) );
628 0 : if(!xAxis.is()) //create an axis if necessary
629 0 : xAxis = AxisHelper::createAxis( 1, bAttachToMainAxis, xDiagram, xContext );
630 0 : if( bAdaptAxes )
631 : {
632 0 : AxisHelper::makeAxisVisible( xAxis );
633 0 : AxisHelper::hideAxisIfNoDataIsAttached( xOldAxis, xDiagram );
634 0 : }
635 : }
636 :
637 0 : return bChanged;
638 : }
639 :
640 0 : uno::Reference< XAxis > DiagramHelper::getAttachedAxis(
641 : const uno::Reference< XDataSeries >& xSeries,
642 : const uno::Reference< XDiagram >& xDiagram )
643 : {
644 0 : return AxisHelper::getAxis( 1, DiagramHelper::isSeriesAttachedToMainAxis( xSeries ), xDiagram );
645 : }
646 :
647 0 : uno::Reference< XChartType > DiagramHelper::getChartTypeOfSeries(
648 : const uno::Reference< chart2::XDiagram >& xDiagram
649 : , const uno::Reference< XDataSeries >& xGivenDataSeries )
650 : {
651 0 : if( !xGivenDataSeries.is() )
652 0 : return 0;
653 0 : if(!xDiagram.is())
654 0 : return 0;
655 :
656 : //iterate through the model to find the given xSeries
657 : //the found parent indicates the charttype
658 :
659 : //iterate through all coordinate systems
660 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
661 0 : if( !xCooSysContainer.is())
662 0 : return 0;
663 :
664 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
665 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
666 : {
667 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
668 :
669 : //iterate through all chart types in the current coordinate system
670 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
671 : OSL_ASSERT( xChartTypeContainer.is());
672 0 : if( !xChartTypeContainer.is() )
673 0 : continue;
674 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
675 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
676 : {
677 0 : uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
678 :
679 : //iterate through all series in this chart type
680 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
681 : OSL_ASSERT( xDataSeriesContainer.is());
682 0 : if( !xDataSeriesContainer.is() )
683 0 : continue;
684 :
685 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
686 0 : for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
687 : {
688 0 : if( xGivenDataSeries==aSeriesList[nS] )
689 0 : return xChartType;
690 : }
691 0 : }
692 0 : }
693 0 : return 0;
694 : }
695 :
696 : ::std::vector< Reference< XDataSeries > >
697 0 : DiagramHelper::getDataSeriesFromDiagram(
698 : const Reference< XDiagram > & xDiagram )
699 : {
700 0 : ::std::vector< Reference< XDataSeries > > aResult;
701 :
702 : try
703 : {
704 : Reference< XCoordinateSystemContainer > xCooSysCnt(
705 0 : xDiagram, uno::UNO_QUERY_THROW );
706 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
707 0 : xCooSysCnt->getCoordinateSystems());
708 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
709 : {
710 0 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
711 0 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
712 0 : for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
713 : {
714 0 : Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
715 0 : Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
716 0 : ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
717 0 : ::std::back_inserter( aResult ));
718 0 : }
719 0 : }
720 : }
721 0 : catch( const uno::Exception & ex )
722 : {
723 : ASSERT_EXCEPTION( ex );
724 : }
725 :
726 0 : return aResult;
727 : }
728 :
729 : Sequence< Sequence< Reference< XDataSeries > > >
730 0 : DiagramHelper::getDataSeriesGroups( const Reference< XDiagram > & xDiagram )
731 : {
732 0 : vector< Sequence< Reference< XDataSeries > > > aResult;
733 :
734 : //iterate through all coordinate systems
735 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
736 0 : if( xCooSysContainer.is() )
737 : {
738 0 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
739 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
740 : {
741 : //iterate through all chart types in the current coordinate system
742 0 : Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
743 0 : if( !xChartTypeContainer.is() )
744 0 : continue;
745 0 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
746 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
747 : {
748 0 : Reference< XDataSeriesContainer > xDataSeriesContainer( aChartTypeList[nT], uno::UNO_QUERY );
749 0 : if( !xDataSeriesContainer.is() )
750 0 : continue;
751 0 : aResult.push_back( xDataSeriesContainer->getDataSeries() );
752 0 : }
753 0 : }
754 : }
755 0 : return ContainerHelper::ContainerToSequence( aResult );
756 : }
757 :
758 : Reference< XChartType >
759 0 : DiagramHelper::getChartTypeByIndex( const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
760 : {
761 0 : Reference< XChartType > xChartType;
762 :
763 : //iterate through all coordinate systems
764 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
765 0 : if( ! xCooSysContainer.is())
766 0 : return xChartType;
767 :
768 0 : Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
769 0 : sal_Int32 nTypesSoFar = 0;
770 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
771 : {
772 0 : Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
773 0 : if( !xChartTypeContainer.is() )
774 0 : continue;
775 0 : Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
776 0 : if( nIndex >= 0 && nIndex < (nTypesSoFar + aChartTypeList.getLength()) )
777 : {
778 0 : xChartType.set( aChartTypeList[nIndex - nTypesSoFar] );
779 0 : break;
780 : }
781 0 : nTypesSoFar += aChartTypeList.getLength();
782 0 : }
783 :
784 0 : return xChartType;
785 : }
786 :
787 : namespace
788 : {
789 :
790 0 : std::vector< Reference< XAxis > > lcl_getAxisHoldingCategoriesFromDiagram(
791 : const Reference< XDiagram > & xDiagram )
792 : {
793 0 : std::vector< Reference< XAxis > > aRet;
794 :
795 0 : Reference< XAxis > xResult;
796 : // return first x-axis as fall-back
797 0 : Reference< XAxis > xFallBack;
798 : try
799 : {
800 : Reference< XCoordinateSystemContainer > xCooSysCnt(
801 0 : xDiagram, uno::UNO_QUERY_THROW );
802 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
803 0 : xCooSysCnt->getCoordinateSystems());
804 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
805 : {
806 0 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
807 : OSL_ASSERT( xCooSys.is());
808 0 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
809 : {
810 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
811 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
812 : {
813 0 : Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
814 : OSL_ASSERT( xAxis.is());
815 0 : if( xAxis.is())
816 : {
817 0 : ScaleData aScaleData = xAxis->getScaleData();
818 0 : if( aScaleData.Categories.is() || (aScaleData.AxisType == AxisType::CATEGORY) )
819 : {
820 0 : aRet.push_back(xAxis);
821 : }
822 0 : if( (nN == 0) && !xFallBack.is())
823 0 : xFallBack.set( xAxis );
824 : }
825 0 : }
826 : }
827 0 : }
828 : }
829 0 : catch( const uno::Exception & ex )
830 : {
831 : ASSERT_EXCEPTION( ex );
832 : }
833 :
834 0 : if( aRet.empty() )
835 0 : aRet.push_back(xFallBack);
836 :
837 0 : return aRet;
838 : }
839 :
840 : } // anonymous namespace
841 :
842 0 : bool DiagramHelper::isCategoryDiagram(
843 : const Reference< XDiagram >& xDiagram )
844 : {
845 : try
846 : {
847 : Reference< XCoordinateSystemContainer > xCooSysCnt(
848 0 : xDiagram, uno::UNO_QUERY_THROW );
849 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
850 0 : xCooSysCnt->getCoordinateSystems());
851 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
852 : {
853 0 : Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
854 : OSL_ASSERT( xCooSys.is());
855 0 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
856 : {
857 0 : const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
858 0 : for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
859 : {
860 0 : Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
861 : OSL_ASSERT( xAxis.is());
862 0 : if( xAxis.is())
863 : {
864 0 : ScaleData aScaleData = xAxis->getScaleData();
865 0 : if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE )
866 0 : return true;
867 : }
868 0 : }
869 : }
870 0 : }
871 : }
872 0 : catch( const uno::Exception & ex )
873 : {
874 : ASSERT_EXCEPTION( ex );
875 : }
876 :
877 0 : return false;
878 : }
879 :
880 0 : void DiagramHelper::setCategoriesToDiagram(
881 : const Reference< chart2::data::XLabeledDataSequence >& xCategories,
882 : const Reference< XDiagram >& xDiagram,
883 : bool bSetAxisType /* = false */,
884 : bool bCategoryAxis /* = true */ )
885 : {
886 : std::vector< Reference< chart2::XAxis > > aCatAxes(
887 0 : lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
888 :
889 0 : std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
890 0 : std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
891 :
892 0 : for( aIt = aCatAxes.begin(); aIt != aEnd; ++aIt )
893 : {
894 0 : Reference< chart2::XAxis > xCatAxis(*aIt);
895 0 : if( xCatAxis.is())
896 : {
897 0 : ScaleData aScaleData( xCatAxis->getScaleData());
898 0 : aScaleData.Categories = xCategories;
899 0 : if( bSetAxisType )
900 : {
901 0 : if( bCategoryAxis )
902 0 : aScaleData.AxisType = AxisType::CATEGORY;
903 0 : else if( aScaleData.AxisType == AxisType::CATEGORY || aScaleData.AxisType == AxisType::DATE )
904 0 : aScaleData.AxisType = AxisType::REALNUMBER;
905 : }
906 0 : xCatAxis->setScaleData( aScaleData );
907 : }
908 0 : }
909 0 : }
910 :
911 : Reference< data::XLabeledDataSequence >
912 0 : DiagramHelper::getCategoriesFromDiagram(
913 : const Reference< XDiagram > & xDiagram )
914 : {
915 0 : Reference< data::XLabeledDataSequence > xResult;
916 :
917 : try
918 : {
919 : std::vector< Reference< chart2::XAxis > > aCatAxes(
920 0 : lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
921 0 : std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
922 0 : std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
923 : //search for first categories
924 0 : if( aIt != aEnd )
925 : {
926 0 : Reference< chart2::XAxis > xCatAxis(*aIt);
927 0 : if( xCatAxis.is())
928 : {
929 0 : ScaleData aScaleData( xCatAxis->getScaleData());
930 0 : if( aScaleData.Categories.is() )
931 : {
932 0 : xResult.set( aScaleData.Categories );
933 0 : uno::Reference<beans::XPropertySet> xProp(aScaleData.Categories->getValues(), uno::UNO_QUERY );
934 0 : if( xProp.is() )
935 : {
936 : try
937 : {
938 0 : xProp->setPropertyValue( "Role", uno::makeAny( OUString("categories") ) );
939 : }
940 0 : catch( const uno::Exception & ex )
941 : {
942 : ASSERT_EXCEPTION( ex );
943 : }
944 0 : }
945 0 : }
946 0 : }
947 0 : }
948 : }
949 0 : catch( const uno::Exception & ex )
950 : {
951 : ASSERT_EXCEPTION( ex );
952 : }
953 :
954 0 : return xResult;
955 : }
956 :
957 0 : void lcl_generateAutomaticCategoriesFromChartType(
958 : Sequence< OUString >& rRet,
959 : const Reference< XChartType >& xChartType )
960 : {
961 0 : if(!xChartType.is())
962 0 : return;
963 0 : OUString aMainSeq( xChartType->getRoleOfSequenceForSeriesLabel() );
964 0 : Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY );
965 0 : if( xSeriesCnt.is() )
966 : {
967 0 : Sequence< Reference< XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
968 0 : for( sal_Int32 nS = 0; nS < aSeriesSeq.getLength(); nS++ )
969 : {
970 0 : Reference< data::XDataSource > xDataSource( aSeriesSeq[nS], uno::UNO_QUERY );
971 0 : if( !xDataSource.is() )
972 0 : continue;
973 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
974 0 : ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aMainSeq ));
975 0 : if( !xLabeledSeq.is() )
976 0 : continue;
977 0 : Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
978 0 : if( !xValueSeq.is() )
979 0 : continue;
980 0 : rRet = xValueSeq->generateLabel( chart2::data::LabelOrigin_LONG_SIDE );
981 0 : if( rRet.getLength() )
982 0 : return;
983 0 : }
984 0 : }
985 : }
986 :
987 0 : Sequence< OUString > DiagramHelper::generateAutomaticCategoriesFromCooSys( const Reference< XCoordinateSystem > & xCooSys )
988 : {
989 0 : Sequence< OUString > aRet;
990 :
991 0 : Reference< XChartTypeContainer > xTypeCntr( xCooSys, uno::UNO_QUERY );
992 0 : if( xTypeCntr.is() )
993 : {
994 0 : Sequence< Reference< XChartType > > aChartTypes( xTypeCntr->getChartTypes() );
995 0 : for( sal_Int32 nN=0; nN<aChartTypes.getLength(); nN++ )
996 : {
997 0 : lcl_generateAutomaticCategoriesFromChartType( aRet, aChartTypes[nN] );
998 0 : if( aRet.getLength() )
999 0 : return aRet;
1000 0 : }
1001 : }
1002 0 : return aRet;
1003 : }
1004 :
1005 0 : Sequence< OUString > DiagramHelper::getExplicitSimpleCategories(
1006 : ChartModel& rModel )
1007 : {
1008 0 : uno::Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( rModel ) );
1009 0 : ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, rModel );
1010 0 : return aExplicitCategoriesProvider.getSimpleCategories();
1011 : }
1012 :
1013 : namespace
1014 : {
1015 0 : void lcl_switchToDateCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis )
1016 : {
1017 0 : if( !xAxis.is() )
1018 0 : return;
1019 0 : if( !xChartDoc.is() )
1020 0 : return;
1021 :
1022 0 : ScaleData aScale( xAxis->getScaleData() );
1023 0 : if( xChartDoc->hasInternalDataProvider() )
1024 : {
1025 : //remove all content the is not of type double and remove multiple level
1026 0 : Reference< XAnyDescriptionAccess > xDataAccess( xChartDoc->getDataProvider(), uno::UNO_QUERY );
1027 0 : if( xDataAccess.is() )
1028 : {
1029 0 : Sequence< Sequence< Any > > aAnyCategories( xDataAccess->getAnyRowDescriptions() );
1030 0 : double fTest = 0.0;
1031 0 : double fNan = 0.0;
1032 0 : ::rtl::math::setNan( & fNan );
1033 0 : sal_Int32 nN = aAnyCategories.getLength();
1034 0 : for( ; nN--; )
1035 : {
1036 0 : Sequence< Any >& rCat = aAnyCategories[nN];
1037 0 : if( rCat.getLength() > 1 )
1038 0 : rCat.realloc(1);
1039 0 : if( rCat.getLength() == 1 )
1040 : {
1041 0 : Any& rAny = rCat[0];
1042 0 : if( !(rAny>>=fTest) )
1043 : {
1044 0 : rAny = uno::makeAny(fNan);
1045 : }
1046 : }
1047 : }
1048 0 : xDataAccess->setAnyRowDescriptions( aAnyCategories );
1049 : }
1050 : //check the numberformat at the axis
1051 0 : Reference< beans::XPropertySet > xAxisProps( xAxis, uno::UNO_QUERY );
1052 0 : Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartDoc, uno::UNO_QUERY );
1053 0 : if( xAxisProps.is() && xNumberFormatsSupplier.is() )
1054 : {
1055 0 : sal_Int32 nNumberFormat = -1;
1056 0 : xAxisProps->getPropertyValue( "NumberFormat" ) >>= nNumberFormat;
1057 :
1058 0 : Reference< util::XNumberFormats > xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
1059 0 : if( xNumberFormats.is() )
1060 : {
1061 0 : Reference< beans::XPropertySet > xKeyProps;
1062 : try
1063 : {
1064 0 : xKeyProps = xNumberFormats->getByKey( nNumberFormat );
1065 : }
1066 0 : catch( const uno::Exception & ex )
1067 : {
1068 : ASSERT_EXCEPTION( ex );
1069 : }
1070 0 : sal_Int32 nType = util::NumberFormat::UNDEFINED;
1071 0 : if( xKeyProps.is() )
1072 0 : xKeyProps->getPropertyValue( "Type" ) >>= nType;
1073 0 : if( !( nType & util::NumberFormat::DATE ) )
1074 : {
1075 : //set a date format to the axis
1076 0 : sal_Bool bCreate = sal_True;
1077 0 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1078 0 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::DATE, rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1079 0 : if( aKeySeq.getLength() )
1080 : {
1081 0 : xAxisProps->setPropertyValue( "NumberFormat", uno::makeAny(aKeySeq[0]) );
1082 0 : }
1083 0 : }
1084 0 : }
1085 0 : }
1086 : }
1087 0 : if( aScale.AxisType != chart2::AxisType::DATE )
1088 0 : AxisHelper::removeExplicitScaling( aScale );
1089 0 : aScale.AxisType = chart2::AxisType::DATE;
1090 0 : xAxis->setScaleData( aScale );
1091 : }
1092 :
1093 0 : void lcl_switchToTextCategories( const Reference< XChartDocument >& xChartDoc, const Reference< XAxis >& xAxis )
1094 : {
1095 0 : if( !xAxis.is() )
1096 0 : return;
1097 0 : if( !xChartDoc.is() )
1098 0 : return;
1099 0 : ScaleData aScale( xAxis->getScaleData() );
1100 0 : if( aScale.AxisType != chart2::AxisType::CATEGORY )
1101 0 : AxisHelper::removeExplicitScaling( aScale );
1102 : //todo migrate dates to text?
1103 0 : aScale.AxisType = chart2::AxisType::CATEGORY;
1104 0 : aScale.AutoDateAxis = false;
1105 0 : xAxis->setScaleData( aScale );
1106 : }
1107 :
1108 : }
1109 :
1110 0 : void DiagramHelper::switchToDateCategories( const Reference< XChartDocument >& xChartDoc )
1111 : {
1112 0 : Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
1113 0 : if(xChartModel.is())
1114 : {
1115 0 : ControllerLockGuardUNO aCtrlLockGuard( xChartModel );
1116 :
1117 0 : Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
1118 0 : if( xCooSys.is() )
1119 : {
1120 0 : Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) );
1121 0 : lcl_switchToDateCategories( xChartDoc, xAxis );
1122 0 : }
1123 0 : }
1124 0 : }
1125 :
1126 0 : void DiagramHelper::switchToTextCategories( const Reference< XChartDocument >& xChartDoc )
1127 : {
1128 0 : Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
1129 0 : if(xChartModel.is())
1130 : {
1131 0 : ControllerLockGuardUNO aCtrlLockGuard( xChartModel );
1132 :
1133 0 : Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
1134 0 : if( xCooSys.is() )
1135 : {
1136 0 : Reference< XAxis > xAxis( xCooSys->getAxisByDimension(0,0) );
1137 0 : lcl_switchToTextCategories( xChartDoc, xAxis );
1138 0 : }
1139 0 : }
1140 0 : }
1141 :
1142 0 : bool DiagramHelper::isSupportingDateAxis( const Reference< chart2::XDiagram >& xDiagram )
1143 : {
1144 : return ::chart::ChartTypeHelper::isSupportingDateAxis(
1145 0 : DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), DiagramHelper::getDimension( xDiagram ), 0 );
1146 : }
1147 :
1148 0 : bool DiagramHelper::isDateNumberFormat( sal_Int32 nNumberFormat, const Reference< util::XNumberFormats >& xNumberFormats )
1149 : {
1150 0 : bool bIsDate = false;
1151 0 : if( !xNumberFormats.is() )
1152 0 : return bIsDate;
1153 :
1154 0 : Reference< beans::XPropertySet > xKeyProps = xNumberFormats->getByKey( nNumberFormat );
1155 0 : if( xKeyProps.is() )
1156 : {
1157 0 : sal_Int32 nType = util::NumberFormat::UNDEFINED;
1158 0 : xKeyProps->getPropertyValue( "Type" ) >>= nType;
1159 0 : bIsDate = nType & util::NumberFormat::DATE;
1160 : }
1161 0 : return bIsDate;
1162 : }
1163 :
1164 0 : sal_Int32 DiagramHelper::getDateNumberFormat( const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1165 : {
1166 0 : sal_Int32 nRet=-1;
1167 0 : Reference< util::XNumberFormats > xNumberFormats( xNumberFormatsSupplier->getNumberFormats() );
1168 0 : if( xNumberFormats.is() )
1169 : {
1170 0 : sal_Bool bCreate = sal_True;
1171 0 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1172 0 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::DATE,
1173 0 : rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1174 0 : if( aKeySeq.getLength() )
1175 : {
1176 0 : nRet = aKeySeq[0];
1177 0 : }
1178 : }
1179 :
1180 : //try to get a date format with full year display
1181 0 : NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
1182 0 : SvNumberFormatter* pNumFormatter = aNumberFormatterWrapper.getSvNumberFormatter();
1183 0 : if( pNumFormatter )
1184 : {
1185 0 : const SvNumberformat* pFormat = pNumFormatter->GetEntry( nRet );
1186 0 : if( pFormat )
1187 0 : nRet = pNumFormatter->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, pFormat->GetLanguage() );
1188 : }
1189 0 : return nRet;
1190 : }
1191 :
1192 0 : sal_Int32 DiagramHelper::getPercentNumberFormat( const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
1193 : {
1194 0 : sal_Int32 nRet=-1;
1195 0 : Reference< util::XNumberFormats > xNumberFormats( xNumberFormatsSupplier->getNumberFormats() );
1196 0 : if( xNumberFormats.is() )
1197 : {
1198 0 : sal_Bool bCreate = sal_True;
1199 0 : const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
1200 0 : Sequence<sal_Int32> aKeySeq = xNumberFormats->queryKeys( util::NumberFormat::PERCENT,
1201 0 : rLocaleDataWrapper.getLanguageTag().getLocale(), bCreate );
1202 0 : if( aKeySeq.getLength() )
1203 : {
1204 0 : nRet = aKeySeq[0];
1205 0 : }
1206 : }
1207 0 : return nRet;
1208 : }
1209 :
1210 : Sequence< Reference< XChartType > >
1211 0 : DiagramHelper::getChartTypesFromDiagram(
1212 : const Reference< XDiagram > & xDiagram )
1213 : {
1214 0 : ::std::vector< Reference< XChartType > > aResult;
1215 :
1216 0 : if(xDiagram.is())
1217 : {
1218 : try
1219 : {
1220 : Reference< XCoordinateSystemContainer > xCooSysCnt(
1221 0 : xDiagram, uno::UNO_QUERY_THROW );
1222 : Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
1223 0 : xCooSysCnt->getCoordinateSystems());
1224 0 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
1225 : {
1226 0 : Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
1227 0 : Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
1228 : ::std::copy( aChartTypeSeq.getConstArray(),
1229 0 : aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
1230 0 : ::std::back_inserter( aResult ));
1231 0 : }
1232 : }
1233 0 : catch( const uno::Exception & ex )
1234 : {
1235 : ASSERT_EXCEPTION( ex );
1236 : }
1237 : }
1238 :
1239 0 : return ContainerHelper::ContainerToSequence( aResult );
1240 : }
1241 :
1242 0 : bool DiagramHelper::areChartTypesCompatible( const Reference< ::chart2::XChartType >& xFirstType,
1243 : const Reference< ::chart2::XChartType >& xSecondType )
1244 : {
1245 0 : if( !xFirstType.is() || !xSecondType.is() )
1246 0 : return false;
1247 :
1248 0 : ::std::vector< OUString > aFirstRoles( ContainerHelper::SequenceToVector( xFirstType->getSupportedMandatoryRoles() ) );
1249 0 : ::std::vector< OUString > aSecondRoles( ContainerHelper::SequenceToVector( xSecondType->getSupportedMandatoryRoles() ) );
1250 0 : ::std::sort( aFirstRoles.begin(), aFirstRoles.end() );
1251 0 : ::std::sort( aSecondRoles.begin(), aSecondRoles.end() );
1252 0 : return ( aFirstRoles == aSecondRoles );
1253 : }
1254 :
1255 : namespace
1256 : {
1257 : /**
1258 : * This method implements the logic of checking if a series can be moved
1259 : * forward/backward. Depending on the "bDoMove" parameter the series will
1260 : * be moved (bDoMove = true) or the function just will test if the
1261 : * series can be moved without doing the move (bDoMove = false).
1262 : *
1263 : * @param xDiagram
1264 : * Reference to the diagram that contains the series.
1265 : *
1266 : * @param xGivenDataSeries
1267 : * Reference to the series that should moved or tested for moving.
1268 : *
1269 : * @param bForward
1270 : * Direction in which the series should be moved or tested for moving.
1271 : *
1272 : * @param bDoMove
1273 : * Should this function really move the series (true) or just test if it is
1274 : * possible (false).
1275 : *
1276 : *
1277 : * @returns
1278 : * in case of bDoMove == true
1279 : * - True : if the move was done
1280 : * - False : the move failed
1281 : * in case of bDoMove == false
1282 : * - True : the series can be moved
1283 : * - False : the series can not be moved
1284 : *
1285 : */
1286 :
1287 0 : bool lcl_moveSeriesOrCheckIfMoveIsAllowed(
1288 : const Reference< XDiagram >& xDiagram,
1289 : const Reference< XDataSeries >& xGivenDataSeries,
1290 : bool bForward,
1291 : bool bDoMove )
1292 : {
1293 0 : bool bMovedOrMoveAllowed = false;
1294 :
1295 : try
1296 : {
1297 0 : uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
1298 :
1299 : //find position of series.
1300 0 : bool bFound = false;
1301 :
1302 0 : if( xGivenDataSeries.is() && xCooSysContainer.is() )
1303 : {
1304 0 : uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
1305 :
1306 0 : for( sal_Int32 nCS = 0; !bFound && nCS < aCooSysList.getLength(); ++nCS )
1307 : {
1308 0 : uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
1309 :
1310 : //iterate through all chart types in the current coordinate system
1311 0 : uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
1312 : OSL_ASSERT( xChartTypeContainer.is());
1313 0 : if( !xChartTypeContainer.is() )
1314 0 : continue;
1315 0 : uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
1316 0 : uno::Reference< XChartType > xFormerChartType;
1317 :
1318 0 : for( sal_Int32 nT = 0; !bFound && nT < aChartTypeList.getLength(); ++nT )
1319 : {
1320 0 : uno::Reference< XChartType > xCurrentChartType( aChartTypeList[nT] );
1321 :
1322 : //iterate through all series in this chart type
1323 0 : uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xCurrentChartType, uno::UNO_QUERY );
1324 : OSL_ASSERT( xDataSeriesContainer.is());
1325 0 : if( !xDataSeriesContainer.is() )
1326 0 : continue;
1327 :
1328 0 : uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
1329 :
1330 0 : for( sal_Int32 nS = 0; !bFound && nS < aSeriesList.getLength(); ++nS )
1331 : {
1332 :
1333 : // We found the series we are interrested in !
1334 0 : if( xGivenDataSeries==aSeriesList[nS] )
1335 : {
1336 0 : sal_Int32 nOldSeriesIndex = nS;
1337 0 : bFound = true;
1338 :
1339 : try
1340 : {
1341 0 : sal_Int32 nNewSeriesIndex = nS;
1342 :
1343 0 : if( bForward )
1344 0 : nNewSeriesIndex--;
1345 : else
1346 0 : nNewSeriesIndex++;
1347 :
1348 0 : if( nNewSeriesIndex >= 0 && nNewSeriesIndex < aSeriesList.getLength() )
1349 : {
1350 : //move series in the same charttype
1351 0 : bMovedOrMoveAllowed = true;
1352 0 : if( bDoMove )
1353 : {
1354 0 : aSeriesList[ nOldSeriesIndex ] = aSeriesList[ nNewSeriesIndex ];
1355 0 : aSeriesList[ nNewSeriesIndex ] = xGivenDataSeries;
1356 0 : xDataSeriesContainer->setDataSeries( aSeriesList );
1357 : }
1358 : }
1359 0 : else if( nNewSeriesIndex<0 )
1360 : {
1361 : //exchange series with former charttype
1362 0 : if( xFormerChartType.is() && DiagramHelper::areChartTypesCompatible( xFormerChartType, xCurrentChartType ) )
1363 : {
1364 0 : bMovedOrMoveAllowed = true;
1365 0 : if( bDoMove )
1366 : {
1367 0 : uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xFormerChartType, uno::UNO_QUERY );
1368 0 : if( xOtherDataSeriesContainer.is() )
1369 : {
1370 0 : uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1371 0 : sal_Int32 nOtherSeriesIndex = aOtherSeriesList.getLength()-1;
1372 0 : if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1373 : {
1374 0 : uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1375 0 : aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1376 0 : xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1377 :
1378 0 : aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1379 0 : xDataSeriesContainer->setDataSeries(aSeriesList);
1380 0 : }
1381 0 : }
1382 : }
1383 : }
1384 : }
1385 0 : else if( nT+1 < aChartTypeList.getLength() )
1386 : {
1387 : //exchange series with next charttype
1388 0 : uno::Reference< XChartType > xOtherChartType( aChartTypeList[nT+1] );
1389 0 : if( xOtherChartType.is() && DiagramHelper::areChartTypesCompatible( xOtherChartType, xCurrentChartType ) )
1390 : {
1391 0 : bMovedOrMoveAllowed = true;
1392 0 : if( bDoMove )
1393 : {
1394 0 : uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xOtherChartType, uno::UNO_QUERY );
1395 0 : if( xOtherDataSeriesContainer.is() )
1396 : {
1397 0 : uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1398 0 : sal_Int32 nOtherSeriesIndex = 0;
1399 0 : if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1400 : {
1401 0 : uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1402 0 : aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1403 0 : xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1404 :
1405 0 : aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1406 0 : xDataSeriesContainer->setDataSeries(aSeriesList);
1407 0 : }
1408 0 : }
1409 : }
1410 0 : }
1411 : }
1412 : }
1413 0 : catch( const util::CloseVetoException& )
1414 : {
1415 : }
1416 0 : catch( const uno::RuntimeException& )
1417 : {
1418 : }
1419 : }
1420 : }
1421 0 : xFormerChartType = xCurrentChartType;
1422 0 : }
1423 0 : }
1424 0 : }
1425 : }
1426 0 : catch( const util::CloseVetoException& )
1427 : {
1428 : }
1429 0 : catch( const uno::RuntimeException& )
1430 : {
1431 : }
1432 0 : return bMovedOrMoveAllowed;
1433 : }
1434 : } // anonymous namespace
1435 :
1436 0 : bool DiagramHelper::isSeriesMoveable(
1437 : const Reference< XDiagram >& xDiagram,
1438 : const Reference< XDataSeries >& xGivenDataSeries,
1439 : bool bForward )
1440 : {
1441 0 : const bool bDoMove = false;
1442 :
1443 : bool bIsMoveable = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1444 0 : xDiagram, xGivenDataSeries, bForward, bDoMove );
1445 :
1446 0 : return bIsMoveable;
1447 : }
1448 :
1449 0 : bool DiagramHelper::moveSeries( const Reference< XDiagram >& xDiagram, const Reference< XDataSeries >& xGivenDataSeries, bool bForward )
1450 : {
1451 0 : const bool bDoMove = true;
1452 :
1453 : bool bMoved = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1454 0 : xDiagram, xGivenDataSeries, bForward, bDoMove );
1455 :
1456 0 : return bMoved;
1457 : }
1458 :
1459 0 : bool DiagramHelper::isSupportingFloorAndWall( const Reference<
1460 : chart2::XDiagram >& xDiagram )
1461 : {
1462 : //pies and donuts currently do not support this because of wrong files from older versions
1463 : //todo: allow this in future again, if fileversion are available for ole objects (metastream)
1464 : //thus the wrong bottom can be removed on import
1465 :
1466 : Sequence< Reference< chart2::XChartType > > aTypes(
1467 0 : ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ) );
1468 0 : for( sal_Int32 nN = 0; nN < aTypes.getLength(); nN++ )
1469 : {
1470 0 : Reference< chart2::XChartType > xType( aTypes[nN] );
1471 0 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1472 0 : return false;
1473 0 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
1474 0 : return false;
1475 0 : if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
1476 0 : return false;
1477 0 : }
1478 0 : return true;
1479 : }
1480 :
1481 0 : bool DiagramHelper::isPieOrDonutChart( const ::com::sun::star::uno::Reference<
1482 : ::com::sun::star::chart2::XDiagram >& xDiagram )
1483 : {
1484 : uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex(
1485 0 : xDiagram, 0 ) );
1486 :
1487 0 : if( xChartType .is() )
1488 : {
1489 0 : OUString aChartType = xChartType->getChartType();
1490 0 : if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1491 0 : return true;
1492 : }
1493 0 : return false;
1494 : }
1495 :
1496 0 : sal_Int32 DiagramHelper::getGeometry3D(
1497 : const uno::Reference< chart2::XDiagram > & xDiagram,
1498 : bool& rbFound, bool& rbAmbiguous )
1499 : {
1500 0 : sal_Int32 nCommonGeom( DataPointGeometry3D::CUBOID );
1501 0 : rbFound = false;
1502 0 : rbAmbiguous = false;
1503 :
1504 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1505 0 : DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1506 :
1507 0 : if( aSeriesVec.empty())
1508 0 : rbAmbiguous = true;
1509 :
1510 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1511 0 : aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1512 : {
1513 : try
1514 : {
1515 0 : sal_Int32 nGeom = 0;
1516 0 : Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY_THROW );
1517 0 : if( xProp->getPropertyValue( "Geometry3D") >>= nGeom )
1518 : {
1519 0 : if( ! rbFound )
1520 : {
1521 : // first series
1522 0 : nCommonGeom = nGeom;
1523 0 : rbFound = true;
1524 : }
1525 : // further series: compare for uniqueness
1526 0 : else if( nCommonGeom != nGeom )
1527 : {
1528 0 : rbAmbiguous = true;
1529 0 : break;
1530 : }
1531 0 : }
1532 : }
1533 0 : catch( const uno::Exception & ex )
1534 : {
1535 : ASSERT_EXCEPTION( ex );
1536 : }
1537 : }
1538 :
1539 0 : return nCommonGeom;
1540 : }
1541 :
1542 0 : void DiagramHelper::setGeometry3D(
1543 : const Reference< chart2::XDiagram > & xDiagram,
1544 : sal_Int32 nNewGeometry )
1545 : {
1546 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1547 0 : DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1548 :
1549 0 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1550 0 : aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1551 : {
1552 : DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(
1553 0 : *aIt, "Geometry3D", uno::makeAny( nNewGeometry ));
1554 0 : }
1555 0 : }
1556 :
1557 0 : sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment(
1558 : const Reference< chart2::XDiagram > & xDiagram,
1559 : const Reference< chart2::XChartType >& xChartType )
1560 : {
1561 0 : sal_Int32 nResult = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
1562 : uno::Sequence < sal_Int32 > aAvailableMissingValueTreatments(
1563 0 : ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
1564 :
1565 0 : uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
1566 0 : if( xDiaProp.is() && (xDiaProp->getPropertyValue( "MissingValueTreatment" ) >>= nResult) )
1567 : {
1568 : //ensure that the set value is supported by this charttype
1569 0 : for( sal_Int32 nN = 0; nN < aAvailableMissingValueTreatments.getLength(); nN++ )
1570 0 : if( aAvailableMissingValueTreatments[nN] == nResult )
1571 0 : return nResult; //ok
1572 : }
1573 :
1574 : //otherwise use the first supported one
1575 0 : if( aAvailableMissingValueTreatments.getLength() )
1576 : {
1577 0 : nResult = aAvailableMissingValueTreatments[0];
1578 0 : return nResult;
1579 : }
1580 :
1581 0 : return nResult;
1582 : }
1583 :
1584 0 : DiagramPositioningMode DiagramHelper::getDiagramPositioningMode( const uno::Reference<
1585 : chart2::XDiagram > & xDiagram )
1586 : {
1587 0 : DiagramPositioningMode eMode = DiagramPositioningMode_AUTO;
1588 0 : uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY );
1589 0 : if( xDiaProps.is() )
1590 : {
1591 0 : RelativePosition aRelPos;
1592 0 : RelativeSize aRelSize;
1593 0 : if( (xDiaProps->getPropertyValue("RelativePosition") >>= aRelPos ) &&
1594 0 : (xDiaProps->getPropertyValue("RelativeSize") >>= aRelSize ) )
1595 : {
1596 0 : bool bPosSizeExcludeAxes=false;
1597 0 : xDiaProps->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxes;
1598 0 : if( bPosSizeExcludeAxes )
1599 0 : eMode = DiagramPositioningMode_EXCLUDING;
1600 : else
1601 0 : eMode = DiagramPositioningMode_INCLUDING;
1602 : }
1603 : }
1604 0 : return eMode;
1605 : }
1606 :
1607 0 : void lcl_ensureRange0to1( double& rValue )
1608 : {
1609 0 : if(rValue<0.0)
1610 0 : rValue=0.0;
1611 0 : if(rValue>1.0)
1612 0 : rValue=1.0;
1613 0 : }
1614 :
1615 0 : bool DiagramHelper::setDiagramPositioning( const uno::Reference< frame::XModel >& xChartModel,
1616 : const awt::Rectangle& rPosRect /*100th mm*/ )
1617 : {
1618 0 : ControllerLockGuardUNO aCtrlLockGuard( xChartModel );
1619 :
1620 0 : bool bChanged = false;
1621 0 : awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
1622 0 : uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
1623 0 : if( !xDiaProps.is() )
1624 0 : return bChanged;
1625 :
1626 0 : RelativePosition aOldPos;
1627 0 : RelativeSize aOldSize;
1628 0 : xDiaProps->getPropertyValue("RelativePosition" ) >>= aOldPos;
1629 0 : xDiaProps->getPropertyValue("RelativeSize" ) >>= aOldSize;
1630 :
1631 0 : RelativePosition aNewPos;
1632 0 : aNewPos.Anchor = drawing::Alignment_TOP_LEFT;
1633 0 : aNewPos.Primary = double(rPosRect.X)/double(aPageSize.Width);
1634 0 : aNewPos.Secondary = double(rPosRect.Y)/double(aPageSize.Height);
1635 :
1636 0 : chart2::RelativeSize aNewSize;
1637 0 : aNewSize.Primary = double(rPosRect.Width)/double(aPageSize.Width);
1638 0 : aNewSize.Secondary = double(rPosRect.Height)/double(aPageSize.Height);
1639 :
1640 0 : lcl_ensureRange0to1( aNewPos.Primary );
1641 0 : lcl_ensureRange0to1( aNewPos.Secondary );
1642 0 : lcl_ensureRange0to1( aNewSize.Primary );
1643 0 : lcl_ensureRange0to1( aNewSize.Secondary );
1644 0 : if( (aNewPos.Primary + aNewSize.Primary) > 1.0 )
1645 0 : aNewPos.Primary = 1.0 - aNewSize.Primary;
1646 0 : if( (aNewPos.Secondary + aNewSize.Secondary) > 1.0 )
1647 0 : aNewPos.Secondary = 1.0 - aNewSize.Secondary;
1648 :
1649 0 : xDiaProps->setPropertyValue( "RelativePosition", uno::makeAny(aNewPos) );
1650 0 : xDiaProps->setPropertyValue( "RelativeSize", uno::makeAny(aNewSize) );
1651 :
1652 0 : bChanged = (aOldPos.Anchor!=aNewPos.Anchor) ||
1653 0 : (aOldPos.Primary!=aNewPos.Primary) ||
1654 0 : (aOldPos.Secondary!=aNewPos.Secondary) ||
1655 0 : (aOldSize.Primary!=aNewSize.Primary) ||
1656 0 : (aOldSize.Secondary!=aNewSize.Secondary);
1657 0 : return bChanged;
1658 : }
1659 :
1660 0 : awt::Rectangle DiagramHelper::getDiagramRectangleFromModel( const uno::Reference< frame::XModel >& xChartModel )
1661 : {
1662 0 : awt::Rectangle aRet(-1,-1,-1,-1);
1663 :
1664 0 : uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
1665 0 : if( !xDiaProps.is() )
1666 0 : return aRet;
1667 :
1668 0 : awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
1669 :
1670 0 : RelativePosition aRelPos;
1671 0 : RelativeSize aRelSize;
1672 0 : xDiaProps->getPropertyValue("RelativePosition" ) >>= aRelPos;
1673 0 : xDiaProps->getPropertyValue("RelativeSize" ) >>= aRelSize;
1674 :
1675 : awt::Size aAbsSize(
1676 0 : static_cast< sal_Int32 >( aRelSize.Primary * aPageSize.Width ),
1677 0 : static_cast< sal_Int32 >( aRelSize.Secondary * aPageSize.Height ));
1678 :
1679 : awt::Point aAbsPos(
1680 0 : static_cast< sal_Int32 >( aRelPos.Primary * aPageSize.Width ),
1681 0 : static_cast< sal_Int32 >( aRelPos.Secondary * aPageSize.Height ));
1682 :
1683 0 : awt::Point aAbsPosLeftTop = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos, aAbsSize, aRelPos.Anchor );
1684 :
1685 0 : aRet = awt::Rectangle(aAbsPosLeftTop.X, aAbsPosLeftTop.Y, aAbsSize.Width, aAbsSize.Height );
1686 :
1687 0 : return aRet;
1688 : }
1689 :
1690 0 : bool DiagramHelper::switchDiagramPositioningToExcludingPositioning(
1691 : ChartModel& rModel, bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning )
1692 : {
1693 : //return true if something was changed
1694 0 : const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
1695 0 : if( nCurrentODFVersion > SvtSaveOptions::ODFVER_012 )
1696 : {
1697 0 : uno::Reference< ::com::sun::star::chart::XDiagramPositioning > xDiagramPositioning( rModel.getFirstDiagram(), uno::UNO_QUERY );
1698 0 : if( xDiagramPositioning.is() && ( bConvertAlsoFromAutoPositioning || !xDiagramPositioning->isAutomaticDiagramPositioning() )
1699 0 : && !xDiagramPositioning->isExcludingDiagramPositioning() )
1700 : {
1701 0 : ControllerLockGuard aCtrlLockGuard( rModel );
1702 0 : bool bModelWasModified = rModel.isModified();
1703 0 : xDiagramPositioning->setDiagramPositionExcludingAxes( xDiagramPositioning->calculateDiagramPositionExcludingAxes() );
1704 0 : if(bResetModifiedState && !bModelWasModified )
1705 0 : rModel.setModified(sal_False);
1706 0 : return true;
1707 0 : }
1708 : }
1709 0 : return false;
1710 : }
1711 :
1712 : } // namespace chart
1713 :
1714 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|