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 43 #include "chartuno.hxx" 44 #include "miscuno.hxx" 45 #include "docsh.hxx" 46 #include "drwlayer.hxx" 47 #include "undodat.hxx" 48 #include "chartarr.hxx" 49 #include "chartlis.hxx" 50 #include "unoguard.hxx" 51 #include "chart2uno.hxx" 52 #include "convuno.hxx" 53 54 using namespace com::sun::star; 55 56 #define PROP_HANDLE_RELATED_CELLRANGES 1 57 58 //------------------------------------------------------------------------ 59 60 SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" ) 61 SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" ) 62 63 //------------------------------------------------------------------------ 64 65 SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const String& rName ) 66 { 67 if (pDocShell) 68 { 69 ScDocument* pDoc = pDocShell->GetDocument(); 70 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 71 if (pDrawLayer) 72 { 73 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 74 DBG_ASSERT(pPage, "Page nicht gefunden"); 75 if (pPage) 76 { 77 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 78 SdrObject* pObject = aIter.Next(); 79 while (pObject) 80 { 81 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 82 { 83 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 84 if ( xObj.is() ) 85 { 86 String aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 87 if ( aObjName == rName ) 88 return (SdrOle2Obj*)pObject; 89 } 90 } 91 pObject = aIter.Next(); 92 } 93 } 94 } 95 } 96 return NULL; 97 } 98 99 //------------------------------------------------------------------------ 100 101 ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) : 102 pDocShell( pDocSh ), 103 nTab( nT ) 104 { 105 pDocShell->GetDocument()->AddUnoObject(*this); 106 } 107 108 ScChartsObj::~ScChartsObj() 109 { 110 if (pDocShell) 111 pDocShell->GetDocument()->RemoveUnoObject(*this); 112 } 113 114 void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 115 { 116 //! Referenz-Update 117 118 if ( rHint.ISA( SfxSimpleHint ) && 119 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 120 { 121 pDocShell = NULL; // ungueltig geworden 122 } 123 } 124 125 ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const 126 { 127 String aName; 128 if ( pDocShell ) 129 { 130 ScDocument* pDoc = pDocShell->GetDocument(); 131 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 132 if (pDrawLayer) 133 { 134 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 135 DBG_ASSERT(pPage, "Page nicht gefunden"); 136 if (pPage) 137 { 138 long nPos = 0; 139 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 140 SdrObject* pObject = aIter.Next(); 141 while (pObject) 142 { 143 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 144 { 145 if ( nPos == nIndex ) 146 { 147 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 148 if ( xObj.is() ) 149 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 150 break; // nicht weitersuchen 151 } 152 ++nPos; 153 } 154 pObject = aIter.Next(); 155 } 156 } 157 } 158 } 159 160 if (aName.Len()) 161 return new ScChartObj( pDocShell, nTab, aName ); 162 return NULL; 163 } 164 165 ScChartObj* ScChartsObj::GetObjectByName_Impl(const rtl::OUString& aName) const 166 { 167 String aNameString(aName); 168 if ( lcl_FindChartObj( pDocShell, nTab, aNameString ) ) 169 return new ScChartObj( pDocShell, nTab, aNameString ); 170 return NULL; 171 } 172 173 // XTableCharts 174 175 void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName, 176 const awt::Rectangle& aRect, 177 const uno::Sequence<table::CellRangeAddress>& aRanges, 178 sal_Bool bColumnHeaders, sal_Bool bRowHeaders ) 179 throw(::com::sun::star::uno::RuntimeException) 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 pPage->InsertObject( pObj ); 295 pModel->AddUndo( new SdrUndoNewObj( *pObj ) ); 296 297 // Dies veranlaesst Chart zum sofortigen Update 298 //SvData aEmpty; 299 //aIPObj->SendDataChanged( aEmpty ); 300 } 301 } 302 303 void SAL_CALL ScChartsObj::removeByName( const rtl::OUString& aName ) 304 throw(uno::RuntimeException) 305 { 306 ScUnoGuard aGuard; 307 String aNameString(aName); 308 SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aNameString ); 309 if (pObj) 310 { 311 ScDocument* pDoc = pDocShell->GetDocument(); 312 ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0 313 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0 314 315 pModel->AddUndo( new SdrUndoDelObj( *pObj ) ); 316 pPage->RemoveObject( pObj->GetOrdNum() ); 317 318 //! Notify etc.??? 319 } 320 } 321 322 // XEnumerationAccess 323 324 uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration() 325 throw(uno::RuntimeException) 326 { 327 ScUnoGuard aGuard; 328 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableChartsEnumeration"))); 329 } 330 331 // XIndexAccess 332 333 sal_Int32 SAL_CALL ScChartsObj::getCount() throw(uno::RuntimeException) 334 { 335 ScUnoGuard aGuard; 336 sal_Int32 nCount = 0; 337 if ( pDocShell ) 338 { 339 ScDocument* pDoc = pDocShell->GetDocument(); 340 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 341 if (pDrawLayer) 342 { 343 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 344 DBG_ASSERT(pPage, "Page nicht gefunden"); 345 if (pPage) 346 { 347 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 348 SdrObject* pObject = aIter.Next(); 349 while (pObject) 350 { 351 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 352 ++nCount; 353 pObject = aIter.Next(); 354 } 355 } 356 } 357 } 358 return nCount; 359 } 360 361 uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex ) 362 throw(lang::IndexOutOfBoundsException, 363 lang::WrappedTargetException, uno::RuntimeException) 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() throw(uno::RuntimeException) 375 { 376 ScUnoGuard aGuard; 377 return getCppuType((uno::Reference<table::XTableChart>*)0); 378 } 379 380 sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException) 381 { 382 ScUnoGuard aGuard; 383 return getCount() != 0; 384 } 385 386 uno::Any SAL_CALL ScChartsObj::getByName( const rtl::OUString& aName ) 387 throw(container::NoSuchElementException, 388 lang::WrappedTargetException, uno::RuntimeException) 389 { 390 ScUnoGuard aGuard; 391 uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName)); 392 if (xChart.is()) 393 return uno::makeAny(xChart); 394 else 395 throw container::NoSuchElementException(); 396 // return uno::Any(); 397 } 398 399 uno::Sequence<rtl::OUString> SAL_CALL ScChartsObj::getElementNames() throw(uno::RuntimeException) 400 { 401 ScUnoGuard aGuard; 402 if (pDocShell) 403 { 404 ScDocument* pDoc = pDocShell->GetDocument(); 405 406 long nCount = getCount(); 407 uno::Sequence<rtl::OUString> aSeq(nCount); 408 rtl::OUString* pAry = aSeq.getArray(); 409 410 long nPos = 0; 411 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 412 if (pDrawLayer) 413 { 414 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 415 DBG_ASSERT(pPage, "Page nicht gefunden"); 416 if (pPage) 417 { 418 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 419 SdrObject* pObject = aIter.Next(); 420 while (pObject) 421 { 422 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 423 { 424 String aName; 425 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 426 if ( xObj.is() ) 427 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 428 429 DBG_ASSERT(nPos<nCount, "huch, verzaehlt?"); 430 pAry[nPos++] = aName; 431 } 432 pObject = aIter.Next(); 433 } 434 } 435 } 436 DBG_ASSERT(nPos==nCount, "nanu, verzaehlt?"); 437 438 return aSeq; 439 } 440 return uno::Sequence<rtl::OUString>(0); 441 } 442 443 sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName ) 444 throw(uno::RuntimeException) 445 { 446 ScUnoGuard aGuard; 447 String aNameString(aName); 448 return ( lcl_FindChartObj( pDocShell, nTab, aNameString ) != NULL ); 449 } 450 451 //------------------------------------------------------------------------ 452 453 ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) 454 :ScChartObj_Base( m_aMutex ) 455 ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) 456 ,pDocShell( pDocSh ) 457 ,nTab( nT ) 458 ,aChartName( rN ) 459 { 460 pDocShell->GetDocument()->AddUnoObject(*this); 461 SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName ); 462 if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) ) 463 aObjectName = pObject->GetName(); // #i121178#: keep the OLE object's name 464 uno::Sequence< table::CellRangeAddress > aInitialPropValue; 465 registerPropertyNoMember( ::rtl::OUString::createFromAscii( "RelatedCellRanges" ), 466 PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID, 467 ::getCppuType( &aInitialPropValue ), &aInitialPropValue ); 468 } 469 470 ScChartObj::~ScChartObj() 471 { 472 if (pDocShell) 473 pDocShell->GetDocument()->RemoveUnoObject(*this); 474 } 475 476 void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 477 { 478 //! Referenz-Update 479 480 if ( rHint.ISA( SfxSimpleHint ) && 481 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 482 { 483 pDocShell = NULL; // ungueltig geworden 484 } 485 } 486 487 void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const 488 { 489 bool bFound = false; 490 ScDocument* pDoc = (pDocShell? pDocShell->GetDocument(): 0); 491 492 if( pDoc ) 493 { 494 uno::Reference< chart2::XChartDocument > xChartDoc( pDoc->GetChartByName( aChartName ) ); 495 if( xChartDoc.is() ) 496 { 497 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); 498 uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); 499 if( xReceiver.is() && xProvider.is() ) 500 { 501 uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) ); 502 503 rtl::OUString aRanges; 504 chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; 505 bool bHasCategories=false; 506 bool bFirstCellAsLabel=false; 507 const beans::PropertyValue* pPropArray = aArgs.getConstArray(); 508 long nPropCount = aArgs.getLength(); 509 for (long i = 0; i < nPropCount; i++) 510 { 511 const beans::PropertyValue& rProp = pPropArray[i]; 512 String aPropName(rProp.Name); 513 514 if (aPropName.EqualsAscii( "CellRangeRepresentation" )) 515 rProp.Value >>= aRanges; 516 else if (aPropName.EqualsAscii( "DataRowSource" )) 517 eDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value ); 518 else if (aPropName.EqualsAscii( "HasCategories" )) 519 bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); 520 else if (aPropName.EqualsAscii( "FirstCellAsLabel" )) 521 bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value ); 522 } 523 524 if( chart::ChartDataRowSource_COLUMNS == eDataRowSource ) 525 { 526 rColHeaders=bFirstCellAsLabel; 527 rRowHeaders=bHasCategories; 528 } 529 else 530 { 531 rColHeaders=bHasCategories; 532 rRowHeaders=bFirstCellAsLabel; 533 } 534 rRanges->Parse( aRanges, pDoc); 535 } 536 bFound = true; 537 } 538 } 539 if( !bFound ) 540 { 541 rRanges = 0; 542 rColHeaders = false; 543 rRowHeaders = false; 544 } 545 } 546 547 void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders ) 548 { 549 if (pDocShell) 550 { 551 ScDocument* pDoc = pDocShell->GetDocument(); 552 sal_Bool bUndo(pDoc->IsUndoEnabled()); 553 554 if (bUndo) 555 { 556 pDocShell->GetUndoManager()->AddUndoAction( 557 new ScUndoChartData( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, sal_False ) ); 558 } 559 pDoc->UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, sal_False ); 560 } 561 } 562 563 // ::comphelper::OPropertySetHelper 564 565 ::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper() 566 { 567 return *ScChartObj_PABase::getArrayHelper(); 568 } 569 570 void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) throw (uno::Exception) 571 { 572 switch ( nHandle ) 573 { 574 case PROP_HANDLE_RELATED_CELLRANGES: 575 { 576 uno::Sequence< table::CellRangeAddress > aCellRanges; 577 if ( rValue >>= aCellRanges ) 578 { 579 ScRangeListRef rRangeList = new ScRangeList(); 580 const table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); 581 sal_Int32 nCount = aCellRanges.getLength(); 582 for ( sal_Int32 i = 0; i < nCount; ++i ) 583 { 584 table::CellRangeAddress aCellRange = pCellRanges[ i ]; 585 ScRange aRange; 586 ScUnoConversion::FillScRange( aRange, aCellRange ); 587 rRangeList->Append( aRange ); 588 } 589 ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); 590 ScChartListenerCollection* pCollection = ( pDoc ? pDoc->GetChartListenerCollection() : NULL ); 591 if ( pCollection ) 592 { 593 pCollection->ChangeListening( aChartName, rRangeList ); 594 } 595 } 596 } 597 break; 598 default: 599 { 600 } 601 break; 602 } 603 } 604 605 void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const 606 { 607 switch ( nHandle ) 608 { 609 case PROP_HANDLE_RELATED_CELLRANGES: 610 { 611 ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); 612 if ( pDoc ) 613 { 614 ScRange aEmptyRange; 615 sal_uInt16 nIndex = 0; 616 ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); 617 ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); 618 if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) 619 { 620 ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); 621 if ( pListener ) 622 { 623 const ScRangeListRef& rRangeList = pListener->GetRangeList(); 624 if ( rRangeList.Is() ) 625 { 626 sal_uLong nCount = rRangeList->Count(); 627 uno::Sequence< table::CellRangeAddress > aCellRanges( nCount ); 628 table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); 629 for ( sal_uInt16 i = 0; i < nCount; ++i ) 630 { 631 ScRange aRange( *rRangeList->GetObject( i ) ); 632 table::CellRangeAddress aCellRange; 633 ScUnoConversion::FillApiRange( aCellRange, aRange ); 634 pCellRanges[ i ] = aCellRange; 635 } 636 rValue <<= aCellRanges; 637 } 638 } 639 } 640 } 641 } 642 break; 643 default: 644 { 645 } 646 break; 647 } 648 } 649 650 // ::comphelper::OPropertyArrayUsageHelper 651 652 ::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const 653 { 654 uno::Sequence< beans::Property > aProps; 655 describeProperties( aProps ); 656 return new ::cppu::OPropertyArrayHelper( aProps ); 657 } 658 659 // XInterface 660 661 IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) 662 663 // XTypeProvider 664 665 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) 666 667 // XComponent 668 669 void ScChartObj::disposing() 670 { 671 ScChartObj_Base::disposing(); 672 } 673 674 // XTableChart 675 676 sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException) 677 { 678 ScUnoGuard aGuard; 679 ScRangeListRef xRanges = new ScRangeList; 680 bool bColHeaders, bRowHeaders; 681 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 682 return bColHeaders; 683 } 684 685 void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders ) 686 throw(uno::RuntimeException) 687 { 688 ScUnoGuard aGuard; 689 ScRangeListRef xRanges = new ScRangeList; 690 bool bOldColHeaders, bOldRowHeaders; 691 GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); 692 if ( bOldColHeaders != (bHasColumnHeaders != sal_False) ) 693 Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders ); 694 } 695 696 sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() throw(uno::RuntimeException) 697 { 698 ScUnoGuard aGuard; 699 ScRangeListRef xRanges = new ScRangeList; 700 bool bColHeaders, bRowHeaders; 701 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 702 return bRowHeaders; 703 } 704 705 void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders ) 706 throw(uno::RuntimeException) 707 { 708 ScUnoGuard aGuard; 709 ScRangeListRef xRanges = new ScRangeList; 710 bool bOldColHeaders, bOldRowHeaders; 711 GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders ); 712 if ( bOldRowHeaders != (bHasRowHeaders != sal_False) ) 713 Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders ); 714 } 715 716 uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() throw(uno::RuntimeException) 717 { 718 ScUnoGuard aGuard; 719 ScRangeListRef xRanges = new ScRangeList; 720 bool bColHeaders, bRowHeaders; 721 GetData_Impl( xRanges, bColHeaders, bRowHeaders ); 722 if ( xRanges.Is() ) 723 { 724 sal_uLong nCount = xRanges->Count(); 725 726 table::CellRangeAddress aRangeAddress; 727 uno::Sequence<table::CellRangeAddress> aSeq(nCount); 728 table::CellRangeAddress* pAry = aSeq.getArray(); 729 for (sal_uInt16 i=0; i<nCount; i++) 730 { 731 ScRange aRange(*xRanges->GetObject(i)); 732 733 aRangeAddress.Sheet = aRange.aStart.Tab(); 734 aRangeAddress.StartColumn = aRange.aStart.Col(); 735 aRangeAddress.StartRow = aRange.aStart.Row(); 736 aRangeAddress.EndColumn = aRange.aEnd.Col(); 737 aRangeAddress.EndRow = aRange.aEnd.Row(); 738 739 pAry[i] = aRangeAddress; 740 } 741 return aSeq; 742 } 743 744 DBG_ERROR("ScChartObj::getRanges: keine Ranges"); 745 return uno::Sequence<table::CellRangeAddress>(); 746 } 747 748 void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges ) 749 throw(uno::RuntimeException) 750 { 751 ScUnoGuard aGuard; 752 ScRangeListRef xOldRanges = new ScRangeList; 753 bool bColHeaders, bRowHeaders; 754 GetData_Impl( xOldRanges, bColHeaders, bRowHeaders ); 755 756 ScRangeList* pList = new ScRangeList; 757 sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength(); 758 if (nRangeCount) 759 { 760 const table::CellRangeAddress* pAry = aRanges.getConstArray(); 761 for (sal_uInt16 i=0; i<nRangeCount; i++) 762 { 763 ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet, 764 static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet ); 765 pList->Append( aRange ); 766 } 767 } 768 ScRangeListRef xNewRanges( pList ); 769 770 if ( !xOldRanges.Is() || *xOldRanges != *xNewRanges ) 771 Update_Impl( xNewRanges, bColHeaders, bRowHeaders ); 772 } 773 774 // XEmbeddedObjectSupplier 775 776 uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() throw(uno::RuntimeException) 777 { 778 ScUnoGuard aGuard; 779 SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName ); 780 if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) ) 781 { 782 //TODO/LATER: is it OK that something is returned for *all* objects, not only own objects? 783 return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY ); 784 } 785 786 return NULL; 787 } 788 789 // XNamed 790 791 rtl::OUString SAL_CALL ScChartObj::getName() throw(uno::RuntimeException) 792 { 793 ScUnoGuard aGuard; 794 return aChartName; 795 } 796 797 void SAL_CALL ScChartObj::setName( const rtl::OUString& /* aName */ ) throw(uno::RuntimeException) 798 { 799 ScUnoGuard aGuard; 800 throw uno::RuntimeException(); // name cannot be changed 801 } 802 803 // XNamedEx 804 805 rtl::OUString SAL_CALL ScChartObj::getDisplayName() throw(uno::RuntimeException) 806 { 807 ScUnoGuard aGuard; 808 return aObjectName; 809 } 810 811 void SAL_CALL ScChartObj::setDisplayName( const rtl::OUString& aName ) throw(uno::RuntimeException) 812 { 813 ScUnoGuard aGuard; 814 aObjectName = aName; 815 } 816 817 // XPropertySet 818 819 uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException) 820 { 821 return createPropertySetInfo( getInfoHelper() ) ; 822 } 823 824 //------------------------------------------------------------------------ 825 826 827 828