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