1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 #include <com/sun/star/embed/Aspects.hpp> 33 #include <com/sun/star/awt/Size.hpp> 34 #include <com/sun/star/beans/PropertyAttribute.hpp> 35 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 36 #include <com/sun/star/chart/ChartDataRowSource.hpp> 37 #include <com/sun/star/chart2/XChartDocument.hpp> 38 #include <com/sun/star/embed/Aspects.hpp> 39 #include <com/sun/star/table/CellRangeAddress.hpp> 40 41 #include <svx/svditer.hxx> 42 #include <svx/svdoole2.hxx> 43 #include <svx/svdpage.hxx> 44 #include <svx/svdundo.hxx> 45 #include <sfx2/app.hxx> 46 #include <unotools/moduleoptions.hxx> 47 #include <sot/clsids.hxx> 48 #include <toolkit/helper/vclunohelper.hxx> 49 50 #include "chartuno.hxx" 51 #include "miscuno.hxx" 52 #include "docsh.hxx" 53 #include "drwlayer.hxx" 54 #include "undodat.hxx" 55 #include "chartarr.hxx" 56 #include "chartlis.hxx" 57 #include "unoguard.hxx" 58 #include "chart2uno.hxx" 59 #include "convuno.hxx" 60 61 using namespace com::sun::star; 62 63 #define PROP_HANDLE_RELATED_CELLRANGES 1 64 65 //------------------------------------------------------------------------ 66 67 SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" ) 68 SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" ) 69 70 //------------------------------------------------------------------------ 71 72 SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const String& rName ) 73 { 74 if (pDocShell) 75 { 76 ScDocument* pDoc = pDocShell->GetDocument(); 77 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 78 if (pDrawLayer) 79 { 80 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 81 DBG_ASSERT(pPage, "Page nicht gefunden"); 82 if (pPage) 83 { 84 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 85 SdrObject* pObject = aIter.Next(); 86 while (pObject) 87 { 88 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 89 { 90 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 91 if ( xObj.is() ) 92 { 93 String aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 94 if ( aObjName == rName ) 95 return (SdrOle2Obj*)pObject; 96 } 97 } 98 pObject = aIter.Next(); 99 } 100 } 101 } 102 } 103 return NULL; 104 } 105 106 //------------------------------------------------------------------------ 107 108 ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) : 109 pDocShell( pDocSh ), 110 nTab( nT ) 111 { 112 pDocShell->GetDocument()->AddUnoObject(*this); 113 } 114 115 ScChartsObj::~ScChartsObj() 116 { 117 if (pDocShell) 118 pDocShell->GetDocument()->RemoveUnoObject(*this); 119 } 120 121 void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 122 { 123 //! Referenz-Update 124 125 if ( rHint.ISA( SfxSimpleHint ) && 126 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 127 { 128 pDocShell = NULL; // ungueltig geworden 129 } 130 } 131 132 ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const 133 { 134 String aName; 135 if ( pDocShell ) 136 { 137 ScDocument* pDoc = pDocShell->GetDocument(); 138 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 139 if (pDrawLayer) 140 { 141 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 142 DBG_ASSERT(pPage, "Page nicht gefunden"); 143 if (pPage) 144 { 145 long nPos = 0; 146 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 147 SdrObject* pObject = aIter.Next(); 148 while (pObject) 149 { 150 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 151 { 152 if ( nPos == nIndex ) 153 { 154 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 155 if ( xObj.is() ) 156 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 157 break; // nicht weitersuchen 158 } 159 ++nPos; 160 } 161 pObject = aIter.Next(); 162 } 163 } 164 } 165 } 166 167 if (aName.Len()) 168 return new ScChartObj( pDocShell, nTab, aName ); 169 return NULL; 170 } 171 172 ScChartObj* ScChartsObj::GetObjectByName_Impl(const rtl::OUString& aName) const 173 { 174 String aNameString(aName); 175 if ( lcl_FindChartObj( pDocShell, nTab, aNameString ) ) 176 return new ScChartObj( pDocShell, nTab, aNameString ); 177 return NULL; 178 } 179 180 // XTableCharts 181 182 void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName, 183 const awt::Rectangle& aRect, 184 const uno::Sequence<table::CellRangeAddress>& aRanges, 185 sal_Bool bColumnHeaders, sal_Bool bRowHeaders ) 186 throw(::com::sun::star::uno::RuntimeException) 187 { 188 ScUnoGuard aGuard; 189 if (!pDocShell) 190 return; 191 192 ScDocument* pDoc = pDocShell->GetDocument(); 193 ScDrawLayer* pModel = pDocShell->MakeDrawLayer(); 194 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); 195 DBG_ASSERT(pPage,"addChart: keine Page"); 196 if (!pPage || !pDoc) 197 return; 198 199 // chart can't be inserted if any ole object with that name exists on any table 200 // (empty string: generate valid name) 201 202 String aNameString(aName); 203 SCTAB nDummy; 204 if ( aNameString.Len() && pModel->GetNamedObject( aNameString, OBJ_OLE2, nDummy ) ) 205 { 206 // object exists - only RuntimeException is specified 207 throw uno::RuntimeException(); 208 } 209 210 ScRangeList* pList = new ScRangeList; 211 sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength(); 212 if (nRangeCount) 213 { 214 const table::CellRangeAddress* pAry = aRanges.getConstArray(); 215 for (sal_uInt16 i=0; i<nRangeCount; i++) 216 { 217 ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet, 218 static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet ); 219 pList->Append( aRange ); 220 } 221 } 222 ScRangeListRef xNewRanges( pList ); 223 224 uno::Reference < embed::XEmbeddedObject > xObj; 225 ::rtl::OUString aTmp( aNameString ); 226 if ( SvtModuleOptions().IsChart() ) 227 xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aTmp ); 228 if ( xObj.is() ) 229 { 230 String aObjName = aTmp; // wirklich eingefuegter Name... 231 232 // Rechteck anpassen 233 //! Fehler/Exception, wenn leer/ungueltig ??? 234 Point aRectPos( aRect.X, aRect.Y ); 235 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 236 if ( ( aRectPos.X() < 0 && !bLayoutRTL ) || ( aRectPos.X() > 0 && bLayoutRTL ) ) aRectPos.X() = 0; 237 if (aRectPos.Y() < 0) aRectPos.Y() = 0; 238 Size aRectSize( aRect.Width, aRect.Height ); 239 if (aRectSize.Width() <= 0) aRectSize.Width() = 5000; // Default-Groesse 240 if (aRectSize.Height() <= 0) aRectSize.Height() = 5000; 241 Rectangle aInsRect( aRectPos, aRectSize ); 242 243 sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT); 244 MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) )); 245 Size aSize(aInsRect.GetSize()); 246 aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) ); 247 awt::Size aSz; 248 aSz.Width = aSize.Width(); 249 aSz.Height = aSize.Height(); 250 251 // Calc -> DataProvider 252 uno::Reference< chart2::data::XDataProvider > xDataProvider = new 253 ScChart2DataProvider( pDoc ); 254 // Chart -> DataReceiver 255 uno::Reference< chart2::data::XDataReceiver > xReceiver; 256 uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY ); 257 if( xCompSupp.is()) 258 xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY ); 259 if( xReceiver.is()) 260 { 261 String sRangeStr; 262 xNewRanges->Format(sRangeStr, SCR_ABS_3D, pDoc); 263 264 // connect 265 if( sRangeStr.Len() ) 266 xReceiver->attachDataProvider( xDataProvider ); 267 else 268 sRangeStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "all" ) ); 269 270 uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY ); 271 xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); 272 273 // set arguments 274 uno::Sequence< beans::PropertyValue > aArgs( 4 ); 275 aArgs[0] = beans::PropertyValue( 276 ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1, 277 uno::makeAny( ::rtl::OUString( sRangeStr )), beans::PropertyState_DIRECT_VALUE ); 278 aArgs[1] = beans::PropertyValue( 279 ::rtl::OUString::createFromAscii("HasCategories"), -1, 280 uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE ); 281 aArgs[2] = beans::PropertyValue( 282 ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1, 283 uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE ); 284 aArgs[3] = beans::PropertyValue( 285 ::rtl::OUString::createFromAscii("DataRowSource"), -1, 286 uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE ); 287 xReceiver->setArguments( aArgs ); 288 } 289 290 ScChartListener* pChartListener = 291 new ScChartListener( aObjName, pDoc, xNewRanges ); 292 pDoc->GetChartListenerCollection()->Insert( pChartListener ); 293 pChartListener->StartListeningTo(); 294 295 SdrOle2Obj* pObj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aObjName, aInsRect ); 296 297 // set VisArea 298 if( xObj.is()) 299 xObj->setVisualAreaSize( nAspect, aSz ); 300 301 pPage->InsertObject( pObj ); 302 pModel->AddUndo( new SdrUndoNewObj( *pObj ) ); 303 304 // Dies veranlaesst Chart zum sofortigen Update 305 //SvData aEmpty; 306 //aIPObj->SendDataChanged( aEmpty ); 307 } 308 } 309 310 void SAL_CALL ScChartsObj::removeByName( const rtl::OUString& aName ) 311 throw(uno::RuntimeException) 312 { 313 ScUnoGuard aGuard; 314 String aNameString(aName); 315 SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aNameString ); 316 if (pObj) 317 { 318 ScDocument* pDoc = pDocShell->GetDocument(); 319 ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0 320 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0 321 322 pModel->AddUndo( new SdrUndoDelObj( *pObj ) ); 323 pPage->RemoveObject( pObj->GetOrdNum() ); 324 325 //! Notify etc.??? 326 } 327 } 328 329 // XEnumerationAccess 330 331 uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration() 332 throw(uno::RuntimeException) 333 { 334 ScUnoGuard aGuard; 335 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableChartsEnumeration"))); 336 } 337 338 // XIndexAccess 339 340 sal_Int32 SAL_CALL ScChartsObj::getCount() throw(uno::RuntimeException) 341 { 342 ScUnoGuard aGuard; 343 sal_Int32 nCount = 0; 344 if ( pDocShell ) 345 { 346 ScDocument* pDoc = pDocShell->GetDocument(); 347 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 348 if (pDrawLayer) 349 { 350 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 351 DBG_ASSERT(pPage, "Page nicht gefunden"); 352 if (pPage) 353 { 354 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 355 SdrObject* pObject = aIter.Next(); 356 while (pObject) 357 { 358 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 359 ++nCount; 360 pObject = aIter.Next(); 361 } 362 } 363 } 364 } 365 return nCount; 366 } 367 368 uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex ) 369 throw(lang::IndexOutOfBoundsException, 370 lang::WrappedTargetException, uno::RuntimeException) 371 { 372 ScUnoGuard aGuard; 373 uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex)); 374 if (xChart.is()) 375 return uno::makeAny(xChart); 376 else 377 throw lang::IndexOutOfBoundsException(); 378 // return uno::Any(); 379 } 380 381 uno::Type SAL_CALL ScChartsObj::getElementType() throw(uno::RuntimeException) 382 { 383 ScUnoGuard aGuard; 384 return getCppuType((uno::Reference<table::XTableChart>*)0); 385 } 386 387 sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException) 388 { 389 ScUnoGuard aGuard; 390 return getCount() != 0; 391 } 392 393 uno::Any SAL_CALL ScChartsObj::getByName( const rtl::OUString& aName ) 394 throw(container::NoSuchElementException, 395 lang::WrappedTargetException, uno::RuntimeException) 396 { 397 ScUnoGuard aGuard; 398 uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName)); 399 if (xChart.is()) 400 return uno::makeAny(xChart); 401 else 402 throw container::NoSuchElementException(); 403 // return uno::Any(); 404 } 405 406 uno::Sequence<rtl::OUString> SAL_CALL ScChartsObj::getElementNames() throw(uno::RuntimeException) 407 { 408 ScUnoGuard aGuard; 409 if (pDocShell) 410 { 411 ScDocument* pDoc = pDocShell->GetDocument(); 412 413 long nCount = getCount(); 414 uno::Sequence<rtl::OUString> aSeq(nCount); 415 rtl::OUString* pAry = aSeq.getArray(); 416 417 long nPos = 0; 418 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); 419 if (pDrawLayer) 420 { 421 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 422 DBG_ASSERT(pPage, "Page nicht gefunden"); 423 if (pPage) 424 { 425 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 426 SdrObject* pObject = aIter.Next(); 427 while (pObject) 428 { 429 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart(pObject) ) 430 { 431 String aName; 432 uno::Reference < embed::XEmbeddedObject > xObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 433 if ( xObj.is() ) 434 aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj ); 435 436 DBG_ASSERT(nPos<nCount, "huch, verzaehlt?"); 437 pAry[nPos++] = aName; 438 } 439 pObject = aIter.Next(); 440 } 441 } 442 } 443 DBG_ASSERT(nPos==nCount, "nanu, verzaehlt?"); 444 445 return aSeq; 446 } 447 return uno::Sequence<rtl::OUString>(0); 448 } 449 450 sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName ) 451 throw(uno::RuntimeException) 452 { 453 ScUnoGuard aGuard; 454 String aNameString(aName); 455 return ( lcl_FindChartObj( pDocShell, nTab, aNameString ) != NULL ); 456 } 457 458 //------------------------------------------------------------------------ 459 460 ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) 461 :ScChartObj_Base( m_aMutex ) 462 ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) 463 ,pDocShell( pDocSh ) 464 ,nTab( nT ) 465 ,aChartName( rN ) 466 { 467 pDocShell->GetDocument()->AddUnoObject(*this); 468 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 // XPropertySet 809 810 uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException) 811 { 812 return createPropertySetInfo( getInfoHelper() ) ; 813 } 814 815 //------------------------------------------------------------------------ 816 817 818 819