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