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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_sc.hxx" 24 25 #include <com/sun/star/embed/Aspects.hpp> 26 #include <com/sun/star/awt/Size.hpp> 27 #include <com/sun/star/beans/PropertyAttribute.hpp> 28 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 29 #include <com/sun/star/chart/ChartDataRowSource.hpp> 30 #include <com/sun/star/chart2/XChartDocument.hpp> 31 #include <com/sun/star/embed/Aspects.hpp> 32 #include <com/sun/star/table/CellRangeAddress.hpp> 33 34 #include <svx/svditer.hxx> 35 #include <svx/svdoole2.hxx> 36 #include <svx/svdpage.hxx> 37 #include <svx/svdundo.hxx> 38 #include <sfx2/app.hxx> 39 #include <unotools/moduleoptions.hxx> 40 #include <sot/clsids.hxx> 41 #include <toolkit/helper/vclunohelper.hxx> 42 #include <svx/charthelper.hxx> 43 44 #include "chartuno.hxx" 45 #include "miscuno.hxx" 46 #include "docsh.hxx" 47 #include "drwlayer.hxx" 48 #include "undodat.hxx" 49 #include "chartarr.hxx" 50 #include "chartlis.hxx" 51 #include "unoguard.hxx" 52 #include "chart2uno.hxx" 53 #include "convuno.hxx" 54 55 using namespace com::sun::star; 56 57 #define PROP_HANDLE_RELATED_CELLRANGES 1 58 59 //------------------------------------------------------------------------ 60 61 SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" ) 62 SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" ) 63 64 //------------------------------------------------------------------------ 65 66 SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const String& rName ) 67 { 68 if (pDocShell) 69 { 70 ScDocument* pDoc = pDocShell->GetDocument(); 71 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 72 if (pDrawLayer) 73 { 74 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 75 DBG_ASSERT(pPage, "Page nicht gefunden"); 76 if (pPage) 77 { 78 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 79 SdrObject* pObject = aIter.Next(); 80 while (pObject) 81 { 82 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 83 { 84 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 85 if ( xObj.is() ) 86 { 87 String aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 88 if ( aObjName == rName ) 89 return (SdrOle2Obj*)pObject; 90 } 91 } 92 pObject = aIter.Next(); 93 } 94 } 95 } 96 } 97 return NULL; 98 } 99 100 //------------------------------------------------------------------------ 101 102 ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) : 103 pDocShell( pDocSh ), 104 nTab( nT ) 105 { 106 pDocShell->GetDocument()->AddUnoObject(*this); 107 } 108 109 ScChartsObj::~ScChartsObj() 110 { 111 if (pDocShell) 112 pDocShell->GetDocument()->RemoveUnoObject(*this); 113 } 114 115 void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 116 { 117 //! Referenz-Update 118 119 if ( rHint.ISA( SfxSimpleHint ) && 120 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 121 { 122 pDocShell = NULL; // ungueltig geworden 123 } 124 } 125 126 ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const 127 { 128 String aName; 129 if ( pDocShell ) 130 { 131 ScDocument* pDoc = pDocShell->GetDocument(); 132 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 133 if (pDrawLayer) 134 { 135 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 136 DBG_ASSERT(pPage, "Page nicht gefunden"); 137 if (pPage) 138 { 139 long nPos = 0; 140 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 141 SdrObject* pObject = aIter.Next(); 142 while (pObject) 143 { 144 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 145 { 146 if ( nPos == nIndex ) 147 { 148 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 149 if ( xObj.is() ) 150 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 151 break; // nicht weitersuchen 152 } 153 ++nPos; 154 } 155 pObject = aIter.Next(); 156 } 157 } 158 } 159 } 160 161 if (aName.Len()) 162 return new ScChartObj( pDocShell, nTab, aName ); 163 return NULL; 164 } 165 166 ScChartObj* ScChartsObj::GetObjectByName_Impl(const rtl::OUString& aName) const 167 { 168 String aNameString(aName); 169 if ( lcl_FindChartObj( pDocShell, nTab, aNameString ) ) 170 return new ScChartObj( pDocShell, nTab, aNameString ); 171 return NULL; 172 } 173 174 // XTableCharts 175 176 void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName, 177 const awt::Rectangle& aRect, 178 const uno::Sequence<table::CellRangeAddress>& aRanges, 179 sal_Bool bColumnHeaders, sal_Bool bRowHeaders ) 180 { 181 ScUnoGuard aGuard; 182 if (!pDocShell) 183 return; 184 185 ScDocument* pDoc = pDocShell->GetDocument(); 186 ScDrawLayer* pModel = pDocShell->MakeDrawLayer(); 187 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); 188 DBG_ASSERT(pPage,"addChart: keine Page"); 189 if (!pPage || !pDoc) 190 return; 191 192 // chart can't be inserted if any ole object with that name exists on any table 193 // (empty string: generate valid name) 194 195 String aNameString(aName); 196 SCTAB nDummy; 197 if ( aNameString.Len() && pModel->GetNamedObject( aNameString, OBJ_OLE2, nDummy ) ) 198 { 199 // object exists - only RuntimeException is specified 200 throw uno::RuntimeException(); 201 } 202 203 ScRangeList* pList = new ScRangeList; 204 sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength(); 205 if (nRangeCount) 206 { 207 const table::CellRangeAddress* pAry = aRanges.getConstArray(); 208 for (sal_uInt16 i=0; i<nRangeCount; i++) 209 { 210 ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet, 211 static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet ); 212 pList->Append( aRange ); 213 } 214 } 215 ScRangeListRef xNewRanges( pList ); 216 217 uno::Reference < embed::XEmbeddedObject > xObj; 218 ::rtl::OUString aTmp( aNameString ); 219 if ( SvtModuleOptions().IsChart() ) 220 xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aTmp ); 221 if ( xObj.is() ) 222 { 223 String aObjName = aTmp; // wirklich eingefuegter Name... 224 225 // Rechteck anpassen 226 //! Fehler/Exception, wenn leer/ungueltig ??? 227 Point aRectPos( aRect.X, aRect.Y ); 228 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 229 if ( ( aRectPos.X() < 0 && !bLayoutRTL ) || ( aRectPos.X() > 0 && bLayoutRTL ) ) aRectPos.X() = 0; 230 if (aRectPos.Y() < 0) aRectPos.Y() = 0; 231 Size aRectSize( aRect.Width, aRect.Height ); 232 if (aRectSize.Width() <= 0) aRectSize.Width() = 5000; // Default-Groesse 233 if (aRectSize.Height() <= 0) aRectSize.Height() = 5000; 234 Rectangle aInsRect( aRectPos, aRectSize ); 235 236 sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT); 237 MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) )); 238 Size aSize(aInsRect.GetSize()); 239 aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) ); 240 awt::Size aSz; 241 aSz.Width = aSize.Width(); 242 aSz.Height = aSize.Height(); 243 244 // Calc -> DataProvider 245 uno::Reference< chart2::data::XDataProvider > xDataProvider = new 246 ScChart2DataProvider( pDoc ); 247 // Chart -> DataReceiver 248 uno::Reference< chart2::data::XDataReceiver > xReceiver; 249 uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY ); 250 if( xCompSupp.is()) 251 xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY ); 252 if( xReceiver.is()) 253 { 254 String sRangeStr; 255 xNewRanges->Format(sRangeStr, SCR_ABS_3D, pDoc); 256 257 // connect 258 if( sRangeStr.Len() ) 259 xReceiver->attachDataProvider( xDataProvider ); 260 else 261 sRangeStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "all" ) ); 262 263 uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY ); 264 xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); 265 266 // set arguments 267 uno::Sequence< beans::PropertyValue > aArgs( 4 ); 268 aArgs[0] = beans::PropertyValue( 269 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1, 270 uno::makeAny( ::rtl::OUString( sRangeStr )), beans::PropertyState_DIRECT_VALUE ); 271 aArgs[1] = beans::PropertyValue( 272 ::rtl::OUString::createFromAscii("HasCategories"), -1, 273 uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE ); 274 aArgs[2] = beans::PropertyValue( 275 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1, 276 uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE ); 277 aArgs[3] = beans::PropertyValue( 278 ::rtl::OUString::createFromAscii("DataRowSource"), -1, 279 uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE ); 280 xReceiver->setArguments( aArgs ); 281 } 282 283 ScChartListener* pChartListener = 284 new ScChartListener( aObjName, pDoc, xNewRanges ); 285 pDoc->GetChartListenerCollection()->Insert( pChartListener ); 286 pChartListener->StartListeningTo(); 287 288 SdrOle2Obj* pObj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aObjName, aInsRect ); 289 290 // set VisArea 291 if( xObj.is()) 292 xObj->setVisualAreaSize( nAspect, aSz ); 293 294 // #121334# This call will change the chart's default background fill from white to transparent. 295 // Add here again if this is wanted (see task description for details) 296 // ChartHelper::AdaptDefaultsForChart( xObj ); 297 298 pPage->InsertObject( pObj ); 299 pModel->AddUndo( new SdrUndoNewObj( *pObj ) ); 300 301 // Dies veranlaesst Chart zum sofortigen Update 302 //SvData aEmpty; 303 //aIPObj->SendDataChanged( aEmpty ); 304 } 305 } 306 307 void SAL_CALL ScChartsObj::removeByName( const rtl::OUString& aName ) 308 { 309 ScUnoGuard aGuard; 310 String aNameString(aName); 311 SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aNameString ); 312 if (pObj) 313 { 314 ScDocument* pDoc = pDocShell->GetDocument(); 315 ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0 316 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0 317 318 pModel->AddUndo( new SdrUndoDelObj( *pObj ) ); 319 pPage->RemoveObject( pObj->GetOrdNum() ); 320 321 //! Notify etc.??? 322 } 323 } 324 325 // XEnumerationAccess 326 327 uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration() 328 { 329 ScUnoGuard aGuard; 330 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableChartsEnumeration"))); 331 } 332 333 // XIndexAccess 334 335 sal_Int32 SAL_CALL ScChartsObj::getCount() 336 { 337 ScUnoGuard aGuard; 338 sal_Int32 nCount = 0; 339 if ( pDocShell ) 340 { 341 ScDocument* pDoc = pDocShell->GetDocument(); 342 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 343 if (pDrawLayer) 344 { 345 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 346 DBG_ASSERT(pPage, "Page nicht gefunden"); 347 if (pPage) 348 { 349 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 350 SdrObject* pObject = aIter.Next(); 351 while (pObject) 352 { 353 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 354 ++nCount; 355 pObject = aIter.Next(); 356 } 357 } 358 } 359 } 360 return nCount; 361 } 362 363 uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex ) 364 { 365 ScUnoGuard aGuard; 366 uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex)); 367 if (xChart.is()) 368 return uno::makeAny(xChart); 369 else 370 throw lang::IndexOutOfBoundsException(); 371 // return uno::Any(); 372 } 373 374 uno::Type SAL_CALL ScChartsObj::getElementType() 375 { 376 ScUnoGuard aGuard; 377 return getCppuType((uno::Reference<table::XTableChart>*)0); 378 } 379 380 sal_Bool SAL_CALL ScChartsObj::hasElements() 381 { 382 ScUnoGuard aGuard; 383 return getCount() != 0; 384 } 385 386 uno::Any SAL_CALL ScChartsObj::getByName( const rtl::OUString& aName ) 387 { 388 ScUnoGuard aGuard; 389 uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName)); 390 if (xChart.is()) 391 return uno::makeAny(xChart); 392 else 393 throw container::NoSuchElementException(); 394 // return uno::Any(); 395 } 396 397 uno::Sequence<rtl::OUString> SAL_CALL ScChartsObj::getElementNames() 398 { 399 ScUnoGuard aGuard; 400 if (pDocShell) 401 { 402 ScDocument* pDoc = pDocShell->GetDocument(); 403 404 long nCount = getCount(); 405 uno::Sequence<rtl::OUString> aSeq(nCount); 406 rtl::OUString* pAry = aSeq.getArray(); 407 408 long nPos = 0; 409 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 410 if (pDrawLayer) 411 { 412 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 413 DBG_ASSERT(pPage, "Page nicht gefunden"); 414 if (pPage) 415 { 416 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 417 SdrObject* pObject = aIter.Next(); 418 while (pObject) 419 { 420 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 421 { 422 String aName; 423 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 424 if ( xObj.is() ) 425 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 426 427 DBG_ASSERT(nPos<nCount, "huch, verzaehlt?"); 428 pAry[nPos++] = aName; 429 } 430 pObject = aIter.Next(); 431 } 432 } 433 } 434 DBG_ASSERT(nPos==nCount, "nanu, verzaehlt?"); 435 436 return aSeq; 437 } 438 return uno::Sequence<rtl::OUString>(0); 439 } 440 441 sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName ) 442 { 443 ScUnoGuard aGuard; 444 String aNameString(aName); 445 return ( lcl_FindChartObj( pDocShell, nTab, aNameString ) != NULL ); 446 } 447 448 //------------------------------------------------------------------------ 449 450 ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) 451 :ScChartObj_Base( m_aMutex ) 452 ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) 453 ,pDocShell( pDocSh ) 454 ,nTab( nT ) 455 ,aChartName( rN ) 456 { 457 pDocShell->GetDocument()->AddUnoObject(*this); 458 SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName ); 459 if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) ) 460 aObjectName = pObject->GetName(); // #i121178#: keep the OLE object's name 461 uno::Sequence< table::CellRangeAddress > aInitialPropValue; 462 registerPropertyNoMember( ::rtl::OUString::createFromAscii( "RelatedCellRanges" ), 463 PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID, 464 ::getCppuType( &aInitialPropValue ), &aInitialPropValue ); 465 } 466 467 ScChartObj::~ScChartObj() 468 { 469 if (pDocShell) 470 pDocShell->GetDocument()->RemoveUnoObject(*this); 471 } 472 473 void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 474 { 475 //! Referenz-Update 476 477 if ( rHint.ISA( SfxSimpleHint ) && 478 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 479 { 480 pDocShell = NULL; // ungueltig geworden 481 } 482 } 483 484 void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const 485 { 486 bool bFound = false; 487 ScDocument* pDoc = (pDocShell? pDocShell->GetDocument(): 0); 488 489 if( pDoc ) 490 { 491 uno::Reference< chart2::XChartDocument > xChartDoc( pDoc->GetChartByName( aChartName ) ); 492 if( xChartDoc.is() ) 493 { 494 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); 495 uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); 496 if( xReceiver.is() && xProvider.is() ) 497 { 498 uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) ); 499 500 rtl::OUString aRanges; 501 chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; 502 bool bHasCategories=false; 503 bool bFirstCellAsLabel=false; 504 const beans::PropertyValue* pPropArray = aArgs.getConstArray(); 505 long nPropCount = aArgs.getLength(); 506 for (long i = 0; i < nPropCount; i++) 507 { 508 const beans::PropertyValue& rProp = pPropArray[i]; 509 String aPropName(rProp.Name); 510 511 if (aPropName.EqualsAscii( "CellRangeRepresentation" )) 512 rProp.Value >>= aRanges; 513 else if (aPropName.EqualsAscii( "DataRowSource" )) 514 eDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value ); 515 else if (aPropName.EqualsAscii( "HasCategories" )) 516 bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); 517 else if (aPropName.EqualsAscii( "FirstCellAsLabel" )) 518 bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); 519 } 520 521 if( chart::ChartDataRowSource_COLUMNS == eDataRowSource ) 522 { 523 rColHeaders=bFirstCellAsLabel; 524 rRowHeaders=bHasCategories; 525 } 526 else 527 { 528 rColHeaders=bHasCategories; 529 rRowHeaders=bFirstCellAsLabel; 530 } 531 rRanges->Parse( aRanges, pDoc); 532 } 533 bFound = true; 534 } 535 } 536 if( !bFound ) 537 { 538 rRanges = 0; 539 rColHeaders = false; 540 rRowHeaders = false; 541 } 542 } 543 544 void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders ) 545 { 546 if (pDocShell) 547 { 548 ScDocument* pDoc = pDocShell->GetDocument(); 549 sal_Bool bUndo(pDoc->IsUndoEnabled()); 550 551 if (bUndo) 552 { 553 pDocShell->GetUndoManager()->AddUndoAction( 554 new ScUndoChartData( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, sal_False ) ); 555 } 556 pDoc->UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, sal_False ); 557 } 558 } 559 560 // ::comphelper::OPropertySetHelper 561 562 ::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper() 563 { 564 return *ScChartObj_PABase::getArrayHelper(); 565 } 566 567 void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) 568 { 569 switch ( nHandle ) 570 { 571 case PROP_HANDLE_RELATED_CELLRANGES: 572 { 573 uno::Sequence< table::CellRangeAddress > aCellRanges; 574 if ( rValue >>= aCellRanges ) 575 { 576 ScRangeListRef rRangeList = new ScRangeList(); 577 const table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); 578 sal_Int32 nCount = aCellRanges.getLength(); 579 for ( sal_Int32 i = 0; i < nCount; ++i ) 580 { 581 table::CellRangeAddress aCellRange = pCellRanges[ i ]; 582 ScRange aRange; 583 ScUnoConversion::FillScRange( aRange, aCellRange ); 584 rRangeList->Append( aRange ); 585 } 586 ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); 587 ScChartListenerCollection* pCollection = ( pDoc ? pDoc->GetChartListenerCollection() : NULL ); 588 if ( pCollection ) 589 { 590 pCollection->ChangeListening( aChartName, rRangeList ); 591 } 592 } 593 } 594 break; 595 default: 596 { 597 } 598 break; 599 } 600 } 601 602 void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const 603 { 604 switch ( nHandle ) 605 { 606 case PROP_HANDLE_RELATED_CELLRANGES: 607 { 608 ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); 609 if ( pDoc ) 610 { 611 ScRange aEmptyRange; 612 sal_uInt16 nIndex = 0; 613 ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); 614 ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); 615 if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) 616 { 617 ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); 618 if ( pListener ) 619 { 620 const ScRangeListRef& rRangeList = pListener->GetRangeList(); 621 if ( rRangeList.Is() ) 622 { 623 sal_uLong nCount = rRangeList->Count(); 624 uno::Sequence< table::CellRangeAddress > aCellRanges( nCount ); 625 table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); 626 for ( sal_uInt16 i = 0; i < nCount; ++i ) 627 { 628 ScRange aRange( *rRangeList->GetObject( i ) ); 629 table::CellRangeAddress aCellRange; 630 ScUnoConversion::FillApiRange( aCellRange, aRange ); 631 pCellRanges[ i ] = aCellRange; 632 } 633 rValue <<= aCellRanges; 634 } 635 } 636 } 637 } 638 } 639 break; 640 default: 641 { 642 } 643 break; 644 } 645 } 646 647 // ::comphelper::OPropertyArrayUsageHelper 648 649 ::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const 650 { 651 uno::Sequence< beans::Property > aProps; 652 describeProperties( aProps ); 653 return new ::cppu::OPropertyArrayHelper( aProps ); 654 } 655 656 // XInterface 657 658 IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) 659 660 // XTypeProvider 661 662 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) 663 664 // XComponent 665 666 void ScChartObj::disposing() 667 { 668 ScChartObj_Base::disposing(); 669 } 670 671 // XTableChart 672 673 sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() 674 { 675 ScUnoGuard aGuard; 676 ScRangeListRef xRanges = new ScRangeList; 677 bool bColHeaders, bRowHeaders; 678 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 679 return bColHeaders; 680 } 681 682 void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders ) 683 { 684 ScUnoGuard aGuard; 685 ScRangeListRef xRanges = new ScRangeList; 686 bool bOldColHeaders, bOldRowHeaders; 687 GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); 688 if ( bOldColHeaders != (bHasColumnHeaders != sal_False) ) 689 Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders ); 690 } 691 692 sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() 693 { 694 ScUnoGuard aGuard; 695 ScRangeListRef xRanges = new ScRangeList; 696 bool bColHeaders, bRowHeaders; 697 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 698 return bRowHeaders; 699 } 700 701 void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders ) 702 { 703 ScUnoGuard aGuard; 704 ScRangeListRef xRanges = new ScRangeList; 705 bool bOldColHeaders, bOldRowHeaders; 706 GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); 707 if ( bOldRowHeaders != (bHasRowHeaders != sal_False) ) 708 Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders ); 709 } 710 711 uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() 712 { 713 ScUnoGuard aGuard; 714 ScRangeListRef xRanges = new ScRangeList; 715 bool bColHeaders, bRowHeaders; 716 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 717 if ( xRanges.Is() ) 718 { 719 sal_uLong nCount = xRanges->Count(); 720 721 table::CellRangeAddress aRangeAddress; 722 uno::Sequence<table::CellRangeAddress> aSeq(nCount); 723 table::CellRangeAddress* pAry = aSeq.getArray(); 724 for (sal_uInt16 i=0; i<nCount; i++) 725 { 726 ScRange aRange(*xRanges->GetObject(i)); 727 728 aRangeAddress.Sheet = aRange.aStart.Tab(); 729 aRangeAddress.StartColumn = aRange.aStart.Col(); 730 aRangeAddress.StartRow = aRange.aStart.Row(); 731 aRangeAddress.EndColumn = aRange.aEnd.Col(); 732 aRangeAddress.EndRow = aRange.aEnd.Row(); 733 734 pAry[i] = aRangeAddress; 735 } 736 return aSeq; 737 } 738 739 DBG_ERROR("ScChartObj::getRanges: keine Ranges"); 740 return uno::Sequence<table::CellRangeAddress>(); 741 } 742 743 void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges ) 744 { 745 ScUnoGuard aGuard; 746 ScRangeListRef xOldRanges = new ScRangeList; 747 bool bColHeaders, bRowHeaders; 748 GetData_Impl( xOldRanges, bColHeaders, bRowHeaders ); 749 750 ScRangeList* pList = new ScRangeList; 751 sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength(); 752 if (nRangeCount) 753 { 754 const table::CellRangeAddress* pAry = aRanges.getConstArray(); 755 for (sal_uInt16 i=0; i<nRangeCount; i++) 756 { 757 ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet, 758 static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet ); 759 pList->Append( aRange ); 760 } 761 } 762 ScRangeListRef xNewRanges( pList ); 763 764 if ( !xOldRanges.Is() || *xOldRanges != *xNewRanges ) 765 Update_Impl( xNewRanges, bColHeaders, bRowHeaders ); 766 } 767 768 // XEmbeddedObjectSupplier 769 770 uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() 771 { 772 ScUnoGuard aGuard; 773 SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName ); 774 if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) ) 775 { 776 //TODO/LATER: is it OK that something is returned for *all* objects, not only own objects? 777 return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY ); 778 } 779 780 return NULL; 781 } 782 783 // XNamed 784 785 rtl::OUString SAL_CALL ScChartObj::getName() 786 { 787 ScUnoGuard aGuard; 788 return aChartName; 789 } 790 791 void SAL_CALL ScChartObj::setName( const rtl::OUString& /* aName */ ) 792 { 793 ScUnoGuard aGuard; 794 throw uno::RuntimeException(); // name cannot be changed 795 } 796 797 // XNamedEx 798 799 rtl::OUString SAL_CALL ScChartObj::getDisplayName() 800 { 801 ScUnoGuard aGuard; 802 return aObjectName; 803 } 804 805 void SAL_CALL ScChartObj::setDisplayName( const rtl::OUString& aName ) 806 { 807 ScUnoGuard aGuard; 808 aObjectName = aName; 809 } 810 811 // XPropertySet 812 813 uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() 814 { 815 return createPropertySetInfo( getInfoHelper() ) ; 816 } 817 818 //------------------------------------------------------------------------ 819