xref: /AOO41X/main/sc/source/ui/unoobj/chartuno.cxx (revision 464f741a4e34271b74e354ea0806aa11a3e0eda9)
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 
lcl_FindChartObj(ScDocShell * pDocShell,SCTAB nTab,const String & rName)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 
ScChartsObj(ScDocShell * pDocSh,SCTAB nT)102 ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
103     pDocShell( pDocSh ),
104     nTab( nT )
105 {
106     pDocShell->GetDocument()->AddUnoObject(*this);
107 }
108 
~ScChartsObj()109 ScChartsObj::~ScChartsObj()
110 {
111     if (pDocShell)
112         pDocShell->GetDocument()->RemoveUnoObject(*this);
113 }
114 
Notify(SfxBroadcaster &,const SfxHint & rHint)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 
GetObjectByIndex_Impl(long nIndex) const126 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 
GetObjectByName_Impl(const rtl::OUString & aName) const166 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 
addNewByName(const rtl::OUString & aName,const awt::Rectangle & aRect,const uno::Sequence<table::CellRangeAddress> & aRanges,sal_Bool bColumnHeaders,sal_Bool bRowHeaders)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 
removeByName(const rtl::OUString & aName)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 
createEnumeration()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 
getCount()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 
getByIndex(sal_Int32 nIndex)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 
getElementType()379 uno::Type SAL_CALL ScChartsObj::getElementType() throw(uno::RuntimeException)
380 {
381     ScUnoGuard aGuard;
382     return getCppuType((uno::Reference<table::XTableChart>*)0);
383 }
384 
hasElements()385 sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException)
386 {
387     ScUnoGuard aGuard;
388     return getCount() != 0;
389 }
390 
getByName(const rtl::OUString & aName)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 
getElementNames()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 
hasByName(const rtl::OUString & aName)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 
ScChartObj(ScDocShell * pDocSh,SCTAB nT,const String & rN)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 
~ScChartObj()475 ScChartObj::~ScChartObj()
476 {
477     if (pDocShell)
478         pDocShell->GetDocument()->RemoveUnoObject(*this);
479 }
480 
Notify(SfxBroadcaster &,const SfxHint & rHint)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 
GetData_Impl(ScRangeListRef & rRanges,bool & rColHeaders,bool & rRowHeaders) const492 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 
Update_Impl(const ScRangeListRef & rRanges,bool bColHeaders,bool bRowHeaders)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 
getInfoHelper()570 ::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper()
571 {
572     return *ScChartObj_PABase::getArrayHelper();
573 }
574 
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const uno::Any & rValue)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 
getFastPropertyValue(uno::Any & rValue,sal_Int32 nHandle) const610 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 
createArrayHelper() const657 ::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 
IMPLEMENT_FORWARD_XINTERFACE2(ScChartObj,ScChartObj_Base,ScChartObj_PBase)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 
getHasColumnHeaders()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 
setHasColumnHeaders(sal_Bool bHasColumnHeaders)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 
getHasRowHeaders()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 
setHasRowHeaders(sal_Bool bHasRowHeaders)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 
getRanges()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 
setRanges(const uno::Sequence<table::CellRangeAddress> & aRanges)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 
getEmbeddedObject()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 
getName()796 rtl::OUString SAL_CALL ScChartObj::getName() throw(uno::RuntimeException)
797 {
798     ScUnoGuard aGuard;
799     return aChartName;
800 }
801 
setName(const rtl::OUString &)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 
getDisplayName()810 rtl::OUString SAL_CALL ScChartObj::getDisplayName() throw(uno::RuntimeException)
811 {
812     ScUnoGuard aGuard;
813     return aObjectName;
814 }
815 
setDisplayName(const rtl::OUString & aName)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 
getPropertySetInfo()824 uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException)
825 {
826     return createPropertySetInfo( getInfoHelper() ) ;
827 }
828 
829 //------------------------------------------------------------------------
830 
831 
832 
833