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