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