1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/util/XModifiable.hpp>
21 #include <com/sun/star/chart/ChartDataRowSource.hpp>
22 #include <com/sun/star/chart2/XChartDocument.hpp>
23 #include <com/sun/star/chart2/data/XDataProvider.hpp>
24 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
25 #include <com/sun/star/embed/EmbedStates.hpp>
26 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <sfx2/objsh.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdoole2.hxx>
31 #include <svx/svdpage.hxx>
32 #include <svtools/embedhlp.hxx>
34 #include "document.hxx"
36 #include "drwlayer.hxx"
37 #include "chartarr.hxx"
38 #include "chartlis.hxx"
39 #include "chartlock.hxx"
40 #include "refupdat.hxx"
41 #include <tools/globname.hxx>
42 #include <sot/exchange.hxx>
44 #include "miscuno.hxx"
45 #include "chart2uno.hxx"
46 #include "charthelper.hxx"
48 using namespace ::com::sun::star
;
50 static void lcl_GetChartParameters( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
51 OUString
& rRanges
, chart::ChartDataRowSource
& rDataRowSource
,
52 bool& rHasCategories
, bool& rFirstCellAsLabel
)
54 rHasCategories
= rFirstCellAsLabel
= false; // default if not in sequence
56 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
58 uno::Reference
< chart2::data::XDataSource
> xDataSource
= xReceiver
->getUsedData();
59 uno::Reference
< chart2::data::XDataProvider
> xProvider
= xChartDoc
->getDataProvider();
63 uno::Sequence
< beans::PropertyValue
> aArgs( xProvider
->detectArguments( xDataSource
) );
65 const beans::PropertyValue
* pPropArray
= aArgs
.getConstArray();
66 long nPropCount
= aArgs
.getLength();
67 for (long i
= 0; i
< nPropCount
; i
++)
69 const beans::PropertyValue
& rProp
= pPropArray
[i
];
70 OUString
aPropName(rProp
.Name
);
72 if ( aPropName
== "CellRangeRepresentation" )
73 rProp
.Value
>>= rRanges
;
74 else if ( aPropName
== "DataRowSource" )
75 rDataRowSource
= (chart::ChartDataRowSource
)ScUnoHelpFunctions::GetEnumFromAny( rProp
.Value
);
76 else if ( aPropName
== "HasCategories" )
77 rHasCategories
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
78 else if ( aPropName
== "FirstCellAsLabel" )
79 rFirstCellAsLabel
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
84 static void lcl_SetChartParameters( const uno::Reference
< chart2::data::XDataReceiver
>& xReceiver
,
85 const OUString
& rRanges
, chart::ChartDataRowSource eDataRowSource
,
86 bool bHasCategories
, bool bFirstCellAsLabel
)
90 uno::Sequence
< beans::PropertyValue
> aArgs( 4 );
91 aArgs
[0] = beans::PropertyValue(
92 OUString("CellRangeRepresentation"), -1,
93 uno::makeAny( rRanges
), beans::PropertyState_DIRECT_VALUE
);
94 aArgs
[1] = beans::PropertyValue(
95 OUString("HasCategories"), -1,
96 uno::makeAny( bHasCategories
), beans::PropertyState_DIRECT_VALUE
);
97 aArgs
[2] = beans::PropertyValue(
98 OUString("FirstCellAsLabel"), -1,
99 uno::makeAny( bFirstCellAsLabel
), beans::PropertyState_DIRECT_VALUE
);
100 aArgs
[3] = beans::PropertyValue(
101 OUString("DataRowSource"), -1,
102 uno::makeAny( eDataRowSource
), beans::PropertyState_DIRECT_VALUE
);
103 xReceiver
->setArguments( aArgs
);
107 // update charts after loading old document
109 void ScDocument::UpdateAllCharts()
111 if ( !pDrawLayer
|| !pShell
)
114 if (pChartCollection
->empty())
115 return ; // nothing to do
117 size_t nDataCount
= pChartCollection
->size();
119 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
120 for (SCTAB nTab
=0; nTab
< nSize
; nTab
++)
124 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
125 OSL_ENSURE(pPage
,"Page ?");
128 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
129 SdrObject
* pObject
= aIter
.Next();
132 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
134 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= static_cast<SdrOle2Obj
*>(pObject
)->GetObjRef();
137 OUString aIPName
= static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName();
139 for (size_t nPos
= 0; nPos
< nDataCount
; ++nPos
)
141 ScChartArray
* pChartObj
= (*pChartCollection
)[nPos
];
142 if (pChartObj
->GetName() == aIPName
)
144 ScRangeListRef aRanges
= pChartObj
->GetRangeList();
146 aRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
148 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
149 bool bHasCategories
= pChartObj
->HasRowHeaders();
150 bool bFirstCellAsLabel
= pChartObj
->HasColHeaders();
152 // Calc -> DataProvider
153 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
=
154 new ScChart2DataProvider( this );
155 // Chart -> DataReceiver
156 uno::Reference
< chart2::data::XDataReceiver
> xReceiver
;
157 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
159 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
163 xReceiver
->attachDataProvider( xDataProvider
);
164 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
165 pShell
->GetModel(), uno::UNO_QUERY
);
166 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
168 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
,
169 bHasCategories
, bFirstCellAsLabel
);
172 ScChartListener
* pCL
= new ScChartListener(
173 aIPName
, this, pChartObj
->GetRangeList() );
174 pChartListenerCollection
->insert( pCL
);
175 pCL
->StartListeningTo();
180 pObject
= aIter
.Next();
185 pChartCollection
->clear();
188 bool ScDocument::HasChartAtPoint( SCTAB nTab
, const Point
& rPos
, OUString
& rName
)
190 if (pDrawLayer
&& nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
192 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
193 OSL_ENSURE(pPage
,"Page ?");
195 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
196 SdrObject
* pObject
= aIter
.Next();
199 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
200 pObject
->GetCurrentBoundRect().IsInside(rPos
) )
202 // also Chart-Objects that are not in the Collection
204 if (IsChart(pObject
))
206 rName
= (static_cast<SdrOle2Obj
*>(pObject
))->GetPersistName();
210 pObject
= aIter
.Next();
215 return false; // nothing found
218 void ScDocument::UpdateChartArea( const OUString
& rChartName
,
219 const ScRange
& rNewArea
, bool bColHeaders
, bool bRowHeaders
,
222 ScRangeListRef
aRLR( new ScRangeList
);
223 aRLR
->Append( rNewArea
);
224 UpdateChartArea( rChartName
, aRLR
, bColHeaders
, bRowHeaders
, bAdd
);
227 uno::Reference
< chart2::XChartDocument
> ScDocument::GetChartByName( const OUString
& rChartName
)
229 uno::Reference
< chart2::XChartDocument
> xReturn
;
233 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
234 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
235 for (sal_uInt16 nTab
=0; nTab
<nCount
&& nTab
< nSize
; nTab
++)
237 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
238 OSL_ENSURE(pPage
,"Page ?");
240 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
241 SdrObject
* pObject
= aIter
.Next();
244 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
245 OUString(static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName()) == rChartName
)
247 xReturn
.set( ScChartHelper::GetChartFromSdrObject( pObject
) );
250 pObject
= aIter
.Next();
256 void ScDocument::GetChartRanges( const OUString
& rChartName
, ::std::vector
< ScRangeList
>& rRangesVector
, ScDocument
* pSheetNameDoc
)
258 rRangesVector
.clear();
259 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
260 if ( xChartDoc
.is() )
262 uno::Sequence
< OUString
> aRangeStrings
;
263 ScChartHelper::GetChartRanges( xChartDoc
, aRangeStrings
);
264 for( sal_Int32 nN
=0; nN
<aRangeStrings
.getLength(); nN
++ )
267 aRanges
.Parse( aRangeStrings
[nN
], pSheetNameDoc
, SCA_VALID
, pSheetNameDoc
->GetAddressConvention() );
268 rRangesVector
.push_back(aRanges
);
273 void ScDocument::SetChartRanges( const OUString
& rChartName
, const ::std::vector
< ScRangeList
>& rRangesVector
)
275 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
276 if ( xChartDoc
.is() )
278 sal_Int32 nCount
= static_cast<sal_Int32
>( rRangesVector
.size() );
279 uno::Sequence
< OUString
> aRangeStrings(nCount
);
280 for( sal_Int32 nN
=0; nN
<nCount
; nN
++ )
282 ScRangeList
aScRangeList( rRangesVector
[nN
] );
284 aScRangeList
.Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
285 aRangeStrings
[nN
]=sRangeStr
;
287 ScChartHelper::SetChartRanges( xChartDoc
, aRangeStrings
);
291 void ScDocument::GetOldChartParameters( const OUString
& rName
,
292 ScRangeList
& rRanges
, bool& rColHeaders
, bool& rRowHeaders
)
294 // used for undo of changing chart source area
299 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
300 for (sal_uInt16 nTab
=0; nTab
<nCount
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
302 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
303 OSL_ENSURE(pPage
,"Page ?");
305 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
306 SdrObject
* pObject
= aIter
.Next();
309 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
310 OUString(static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName()) == rName
)
312 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
313 if ( xChartDoc
.is() )
315 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
316 bool bHasCategories
= false;
317 bool bFirstCellAsLabel
= false;
319 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
321 rRanges
.Parse( aRangesStr
, this );
322 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
324 rRowHeaders
= bHasCategories
;
325 rColHeaders
= bFirstCellAsLabel
;
329 rColHeaders
= bHasCategories
;
330 rRowHeaders
= bFirstCellAsLabel
;
335 pObject
= aIter
.Next();
340 void ScDocument::UpdateChartArea( const OUString
& rChartName
,
341 const ScRangeListRef
& rNewList
, bool bColHeaders
, bool bRowHeaders
,
347 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
]; nTab
++)
349 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
350 OSL_ENSURE(pPage
,"Page ?");
352 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
353 SdrObject
* pObject
= aIter
.Next();
356 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
357 OUString(static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName()) == rChartName
)
359 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
360 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
361 if ( xChartDoc
.is() && xReceiver
.is() )
363 ScRangeListRef aNewRanges
;
364 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
365 bool bHasCategories
= false;
366 bool bFirstCellAsLabel
= false;
368 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
370 bool bInternalData
= xChartDoc
->hasInternalDataProvider();
372 if ( bAdd
&& !bInternalData
)
374 // append to old ranges, keep other settings
376 aNewRanges
= new ScRangeList
;
377 aNewRanges
->Parse( aRangesStr
, this );
379 for ( size_t nAdd
= 0, nAddCount
= rNewList
->size(); nAdd
< nAddCount
; ++nAdd
)
380 aNewRanges
->Append( *(*rNewList
)[nAdd
] );
384 // directly use new ranges (only eDataRowSource is used from old settings)
386 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
388 bHasCategories
= bRowHeaders
;
389 bFirstCellAsLabel
= bColHeaders
;
393 bHasCategories
= bColHeaders
;
394 bFirstCellAsLabel
= bRowHeaders
;
396 aNewRanges
= rNewList
;
399 if ( bInternalData
&& pShell
)
401 // Calc -> DataProvider
402 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= new ScChart2DataProvider( this );
403 xReceiver
->attachDataProvider( xDataProvider
);
404 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
405 pShell
->GetModel(), uno::UNO_QUERY
);
406 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
410 aNewRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
412 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
414 pChartListenerCollection
->ChangeListening( rChartName
, aNewRanges
);
416 return; // do not search anymore
419 pObject
= aIter
.Next();
424 void ScDocument::UpdateChart( const OUString
& rChartName
)
426 if (!pDrawLayer
|| bInDtorClear
)
428 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
433 uno::Reference
< util::XModifiable
> xModif( xChartDoc
, uno::UNO_QUERY_THROW
);
434 if( apTemporaryChartLock
.get() )
435 apTemporaryChartLock
->AlsoLockThisChart( uno::Reference
< frame::XModel
>( xModif
, uno::UNO_QUERY
) );
436 xModif
->setModified( true );
438 catch ( uno::Exception
& )
443 // After the update, chart keeps track of its own data source ranges,
444 // the listener doesn't need to listen anymore, except the chart has
445 // an internal data provider.
446 if ( !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() ) && pChartListenerCollection
)
448 pChartListenerCollection
->ChangeListening( rChartName
, new ScRangeList
);
452 void ScDocument::RestoreChartListener( const OUString
& rName
)
454 // Read the data ranges from the chart object, and start listening to those ranges again
455 // (called when a chart is saved, because then it might be swapped out and stop listening itself).
457 uno::Reference
< embed::XEmbeddedObject
> xObject
= FindOleObjectByName( rName
);
460 uno::Reference
< util::XCloseable
> xComponent
= xObject
->getComponent();
461 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
462 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xComponent
, uno::UNO_QUERY
);
463 if ( xChartDoc
.is() && xReceiver
.is() && !xChartDoc
->hasInternalDataProvider())
465 uno::Sequence
<OUString
> aRepresentations( xReceiver
->getUsedRangeRepresentations() );
466 ScRangeListRef aRanges
= new ScRangeList
;
467 sal_Int32 nRangeCount
= aRepresentations
.getLength();
468 for ( sal_Int32 i
=0; i
<nRangeCount
; i
++ )
471 ScAddress::Details
aDetails(GetAddressConvention(), 0, 0);
472 if ( aRange
.ParseAny( aRepresentations
[i
], this, aDetails
) & SCA_VALID
)
473 aRanges
->Append( aRange
);
476 pChartListenerCollection
->ChangeListening( rName
, aRanges
);
481 void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode
,
482 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
483 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
484 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
489 ScChartListenerCollection::ListenersType
& rListeners
= pChartListenerCollection
->getListeners();
490 ScChartListenerCollection::ListenersType::iterator it
= rListeners
.begin(), itEnd
= rListeners
.end();
491 for (; it
!= itEnd
; ++it
)
493 ScChartListener
* pChartListener
= it
->second
;
494 ScRangeListRef
aRLR( pChartListener
->GetRangeList() );
495 ScRangeListRef
aNewRLR( new ScRangeList
);
496 bool bChanged
= false;
497 bool bDataChanged
= false;
498 for ( size_t i
= 0, nListSize
= aRLR
->size(); i
< nListSize
; ++i
)
500 ScRange
* pR
= (*aRLR
)[i
];
501 SCCOL theCol1
= pR
->aStart
.Col();
502 SCROW theRow1
= pR
->aStart
.Row();
503 SCTAB theTab1
= pR
->aStart
.Tab();
504 SCCOL theCol2
= pR
->aEnd
.Col();
505 SCROW theRow2
= pR
->aEnd
.Row();
506 SCTAB theTab2
= pR
->aEnd
.Tab();
507 ScRefUpdateRes eRes
= ScRefUpdate::Update(
508 this, eUpdateRefMode
,
509 nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
511 theCol1
,theRow1
,theTab1
,
512 theCol2
,theRow2
,theTab2
);
513 if ( eRes
!= UR_NOTHING
)
516 aNewRLR
->Append( ScRange(
517 theCol1
, theRow1
, theTab1
,
518 theCol2
, theRow2
, theTab2
));
519 if ( eUpdateRefMode
== URM_INSDEL
521 && (eRes
== UR_INVALID
||
522 ((pR
->aEnd
.Col() - pR
->aStart
.Col()
523 != theCol2
- theCol1
)
524 || (pR
->aEnd
.Row() - pR
->aStart
.Row()
525 != theRow2
- theRow1
)
526 || (pR
->aEnd
.Tab() - pR
->aStart
.Tab()
527 != theTab2
- theTab1
))) )
533 aNewRLR
->Append( *pR
);
538 // Force the chart to be loaded now, so it registers itself for UNO events.
539 // UNO broadcasts are done after UpdateChartRef, so the chart will get this
542 uno::Reference
<embed::XEmbeddedObject
> xIPObj
=
543 FindOleObjectByName(pChartListener
->GetName());
545 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
547 // After the change, chart keeps track of its own data source ranges,
548 // the listener doesn't need to listen anymore, except the chart has
549 // an internal data provider.
550 bool bInternalDataProvider
= false;
555 uno::Reference
< chart2::XChartDocument
> xChartDoc( xIPObj
->getComponent(), uno::UNO_QUERY_THROW
);
556 bInternalDataProvider
= xChartDoc
->hasInternalDataProvider();
558 catch ( uno::Exception
& )
562 if ( bInternalDataProvider
)
564 pChartListener
->ChangeListening( aNewRLR
, bDataChanged
);
568 pChartListener
->ChangeListening( new ScRangeList
, bDataChanged
);
575 void ScDocument::SetChartRangeList( const OUString
& rChartName
,
576 const ScRangeListRef
& rNewRangeListRef
)
578 // called from ChartListener
583 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
]; nTab
++)
585 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
586 OSL_ENSURE(pPage
,"Page ?");
588 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
589 SdrObject
* pObject
= aIter
.Next();
592 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
593 OUString(static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName()) == rChartName
)
595 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
596 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
597 if ( xChartDoc
.is() && xReceiver
.is() )
599 ScRangeListRef aNewRanges
;
600 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
601 bool bHasCategories
= false;
602 bool bFirstCellAsLabel
= false;
604 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
607 rNewRangeListRef
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
609 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
611 // don't modify pChartListenerCollection here, called from there
615 pObject
= aIter
.Next();
620 bool ScDocument::HasData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
622 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
623 return maTabs
[nTab
]->HasData( nCol
, nRow
);
628 uno::Reference
< embed::XEmbeddedObject
>
629 ScDocument::FindOleObjectByName( const OUString
& rName
)
632 return uno::Reference
< embed::XEmbeddedObject
>();
634 // take the pages here from Draw-Layer, as they might not match with the tables
635 // (e.g. delete Redo of table; Draw-Redo happens before DeleteTab)
637 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
638 for (sal_uInt16 nTab
=0; nTab
<nCount
; nTab
++)
640 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
641 OSL_ENSURE(pPage
,"Page ?");
643 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
644 SdrObject
* pObject
= aIter
.Next();
647 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
649 SdrOle2Obj
* pOleObject ( dynamic_cast< SdrOle2Obj
* >( pObject
));
651 OUString(pOleObject
->GetPersistName()) == rName
)
653 return pOleObject
->GetObjRef();
656 pObject
= aIter
.Next();
660 return uno::Reference
< embed::XEmbeddedObject
>();
663 void ScDocument::UpdateChartListenerCollection()
665 OSL_ASSERT(pChartListenerCollection
);
667 bChartListenerCollectionNeedsUpdate
= false;
671 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
676 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
677 OSL_ENSURE(pPage
,"Page ?");
682 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
683 ScChartListenerCollection::StringSetType
& rNonOleObjects
=
684 pChartListenerCollection
->getNonOleObjectNames();
686 for (SdrObject
* pObject
= aIter
.Next(); pObject
; pObject
= aIter
.Next())
688 if ( pObject
->GetObjIdentifier() != OBJ_OLE2
)
691 OUString aObjName
= static_cast<SdrOle2Obj
*>(pObject
)->GetPersistName();
692 ScChartListener
* pListener
= pChartListenerCollection
->findByName(aObjName
);
695 pListener
->SetUsed(true);
696 else if (rNonOleObjects
.count(aObjName
) > 0)
698 // non-chart OLE object -> don't touch
702 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= static_cast<SdrOle2Obj
*>(pObject
)->GetObjRef();
703 OSL_ENSURE( xIPObj
.is(), "No embedded object is given!");
704 uno::Reference
< ::com::sun::star::chart2::data::XDataReceiver
> xReceiver
;
705 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
707 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
709 // if the object is a chart2::XDataReceiver, we must attach as XDataProvider
710 if( xReceiver
.is() &&
711 !PastingDrawFromOtherDoc())
713 // NOTE: this currently does not work as we are
714 // unable to set the data. So a chart from the
715 // same document is treated like a chart with
716 // own data for the time being.
719 // number formats supplier
722 // how to set?? Defined in XML-file, which is already loaded!!!
723 // => we have to do this stuff here, BEFORE the chart is actually loaded
726 // put into list of other ole objects, so the object doesn't have to
727 // be swapped in the next time UpdateChartListenerCollection is called
728 //TODO: remove names when objects are no longer there?
729 // (object names aren't used again before reloading the document)
731 rNonOleObjects
.insert(aObjName
);
735 // delete all that are not set SetUsed
736 pChartListenerCollection
->FreeUnused();
739 void ScDocument::AddOLEObjectToCollection(const OUString
& rName
)
741 OSL_ASSERT(pChartListenerCollection
);
742 ScChartListenerCollection::StringSetType
& rNonOleObjects
=
743 pChartListenerCollection
->getNonOleObjectNames();
745 rNonOleObjects
.insert(rName
);
748 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */