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