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