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