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