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 .
21 #include <com/sun/star/util/XModifiable.hpp>
22 #include <com/sun/star/chart/ChartDataRowSource.hpp>
23 #include <com/sun/star/chart2/XChartDocument.hpp>
24 #include <com/sun/star/chart2/data/XDataProvider.hpp>
25 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
26 #include <com/sun/star/embed/EmbedStates.hpp>
27 #include <com/sun/star/embed/XEmbeddedObject.hpp>
29 #include <sfx2/objsh.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <svx/svdpage.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 // -----------------------------------------------------------------------
52 static void lcl_GetChartParameters( const uno::Reference
< chart2::XChartDocument
>& xChartDoc
,
53 OUString
& rRanges
, chart::ChartDataRowSource
& rDataRowSource
,
54 bool& rHasCategories
, bool& rFirstCellAsLabel
)
56 rHasCategories
= rFirstCellAsLabel
= false; // default if not in sequence
58 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
60 uno::Reference
< chart2::data::XDataSource
> xDataSource
= xReceiver
->getUsedData();
61 uno::Reference
< chart2::data::XDataProvider
> xProvider
= xChartDoc
->getDataProvider();
65 uno::Sequence
< beans::PropertyValue
> aArgs( xProvider
->detectArguments( xDataSource
) );
67 const beans::PropertyValue
* pPropArray
= aArgs
.getConstArray();
68 long nPropCount
= aArgs
.getLength();
69 for (long i
= 0; i
< nPropCount
; i
++)
71 const beans::PropertyValue
& rProp
= pPropArray
[i
];
72 OUString
aPropName(rProp
.Name
);
74 if ( aPropName
== "CellRangeRepresentation" )
75 rProp
.Value
>>= rRanges
;
76 else if ( aPropName
== "DataRowSource" )
77 rDataRowSource
= (chart::ChartDataRowSource
)ScUnoHelpFunctions::GetEnumFromAny( rProp
.Value
);
78 else if ( aPropName
== "HasCategories" )
79 rHasCategories
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
80 else if ( aPropName
== "FirstCellAsLabel" )
81 rFirstCellAsLabel
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
86 static void lcl_SetChartParameters( const uno::Reference
< chart2::data::XDataReceiver
>& xReceiver
,
87 const OUString
& rRanges
, chart::ChartDataRowSource eDataRowSource
,
88 bool bHasCategories
, bool bFirstCellAsLabel
)
92 uno::Sequence
< beans::PropertyValue
> aArgs( 4 );
93 aArgs
[0] = beans::PropertyValue(
94 OUString("CellRangeRepresentation"), -1,
95 uno::makeAny( rRanges
), beans::PropertyState_DIRECT_VALUE
);
96 aArgs
[1] = beans::PropertyValue(
97 OUString("HasCategories"), -1,
98 uno::makeAny( bHasCategories
), beans::PropertyState_DIRECT_VALUE
);
99 aArgs
[2] = beans::PropertyValue(
100 OUString("FirstCellAsLabel"), -1,
101 uno::makeAny( bFirstCellAsLabel
), beans::PropertyState_DIRECT_VALUE
);
102 aArgs
[3] = beans::PropertyValue(
103 OUString("DataRowSource"), -1,
104 uno::makeAny( eDataRowSource
), beans::PropertyState_DIRECT_VALUE
);
105 xReceiver
->setArguments( aArgs
);
109 // update charts after loading old document
111 void ScDocument::UpdateAllCharts()
113 if ( !pDrawLayer
|| !pShell
)
116 if (pChartCollection
->empty())
117 return ; // nothing to do
119 size_t nDataCount
= pChartCollection
->size();
121 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
122 for (SCTAB nTab
=0; nTab
< nSize
; nTab
++)
126 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
127 OSL_ENSURE(pPage
,"Page ?");
130 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
131 SdrObject
* pObject
= aIter
.Next();
134 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
136 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
139 OUString aIPName
= ((SdrOle2Obj
*)pObject
)->GetPersistName();
141 for (size_t nPos
= 0; nPos
< nDataCount
; ++nPos
)
143 ScChartArray
* pChartObj
= (*pChartCollection
)[nPos
];
144 if (pChartObj
->GetName() == aIPName
)
146 ScRangeListRef aRanges
= pChartObj
->GetRangeList();
148 aRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
150 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
151 bool bHasCategories
= pChartObj
->HasRowHeaders();
152 bool bFirstCellAsLabel
= pChartObj
->HasColHeaders();
154 // Calc -> DataProvider
155 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
=
156 new ScChart2DataProvider( this );
157 // Chart -> DataReceiver
158 uno::Reference
< chart2::data::XDataReceiver
> xReceiver
;
159 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
161 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
165 xReceiver
->attachDataProvider( xDataProvider
);
166 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
167 pShell
->GetModel(), uno::UNO_QUERY
);
168 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
170 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
,
171 bHasCategories
, bFirstCellAsLabel
);
174 ScChartListener
* pCL
= new ScChartListener(
175 aIPName
, this, pChartObj
->GetRangeList() );
176 pChartListenerCollection
->insert( pCL
);
177 pCL
->StartListeningTo();
182 pObject
= aIter
.Next();
187 pChartCollection
->clear();
190 bool ScDocument::HasChartAtPoint( SCTAB nTab
, const Point
& rPos
, OUString
& rName
)
192 if (pDrawLayer
&& nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
194 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
195 OSL_ENSURE(pPage
,"Page ?");
197 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
198 SdrObject
* pObject
= aIter
.Next();
201 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
202 pObject
->GetCurrentBoundRect().IsInside(rPos
) )
204 // auch Chart-Objekte die nicht in der Collection sind
206 if (IsChart(pObject
))
208 rName
= (static_cast<SdrOle2Obj
*>(pObject
))->GetPersistName();
212 pObject
= aIter
.Next();
217 return false; // nothing found
220 void ScDocument::UpdateChartArea( const OUString
& rChartName
,
221 const ScRange
& rNewArea
, bool bColHeaders
, bool bRowHeaders
,
224 ScRangeListRef
aRLR( new ScRangeList
);
225 aRLR
->Append( rNewArea
);
226 UpdateChartArea( rChartName
, aRLR
, bColHeaders
, bRowHeaders
, bAdd
);
229 uno::Reference
< chart2::XChartDocument
> ScDocument::GetChartByName( const OUString
& rChartName
)
231 uno::Reference
< chart2::XChartDocument
> xReturn
;
235 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
236 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
237 for (sal_uInt16 nTab
=0; nTab
<nCount
&& nTab
< nSize
; nTab
++)
239 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
240 OSL_ENSURE(pPage
,"Page ?");
242 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
243 SdrObject
* pObject
= aIter
.Next();
246 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
247 OUString(((SdrOle2Obj
*)pObject
)->GetPersistName()) == rChartName
)
249 xReturn
.set( ScChartHelper::GetChartFromSdrObject( pObject
) );
252 pObject
= aIter
.Next();
258 void ScDocument::GetChartRanges( const OUString
& rChartName
, ::std::vector
< ScRangeList
>& rRangesVector
, ScDocument
* pSheetNameDoc
)
260 rRangesVector
.clear();
261 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
262 if ( xChartDoc
.is() )
264 uno::Sequence
< OUString
> aRangeStrings
;
265 ScChartHelper::GetChartRanges( xChartDoc
, aRangeStrings
);
266 for( sal_Int32 nN
=0; nN
<aRangeStrings
.getLength(); nN
++ )
269 aRanges
.Parse( aRangeStrings
[nN
], pSheetNameDoc
, SCA_VALID
, pSheetNameDoc
->GetAddressConvention() );
270 rRangesVector
.push_back(aRanges
);
275 void ScDocument::SetChartRanges( const OUString
& rChartName
, const ::std::vector
< ScRangeList
>& rRangesVector
)
277 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
278 if ( xChartDoc
.is() )
280 sal_Int32 nCount
= static_cast<sal_Int32
>( rRangesVector
.size() );
281 uno::Sequence
< OUString
> aRangeStrings(nCount
);
282 for( sal_Int32 nN
=0; nN
<nCount
; nN
++ )
284 ScRangeList
aScRangeList( rRangesVector
[nN
] );
286 aScRangeList
.Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
287 aRangeStrings
[nN
]=sRangeStr
;
289 ScChartHelper::SetChartRanges( xChartDoc
, aRangeStrings
);
293 void ScDocument::GetOldChartParameters( const OUString
& rName
,
294 ScRangeList
& rRanges
, bool& rColHeaders
, bool& rRowHeaders
)
296 // used for undo of changing chart source area
301 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
302 for (sal_uInt16 nTab
=0; nTab
<nCount
&& nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
304 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
305 OSL_ENSURE(pPage
,"Page ?");
307 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
308 SdrObject
* pObject
= aIter
.Next();
311 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
312 OUString(((SdrOle2Obj
*)pObject
)->GetPersistName()) == rName
)
314 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
315 if ( xChartDoc
.is() )
317 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
318 bool bHasCategories
= false;
319 bool bFirstCellAsLabel
= false;
321 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
323 rRanges
.Parse( aRangesStr
, this );
324 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
326 rRowHeaders
= bHasCategories
;
327 rColHeaders
= bFirstCellAsLabel
;
331 rColHeaders
= bHasCategories
;
332 rRowHeaders
= bFirstCellAsLabel
;
337 pObject
= aIter
.Next();
342 void ScDocument::UpdateChartArea( const OUString
& rChartName
,
343 const ScRangeListRef
& rNewList
, bool bColHeaders
, bool bRowHeaders
,
349 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
]; nTab
++)
351 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
352 OSL_ENSURE(pPage
,"Page ?");
354 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
355 SdrObject
* pObject
= aIter
.Next();
358 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
359 OUString(((SdrOle2Obj
*)pObject
)->GetPersistName()) == rChartName
)
361 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
362 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
363 if ( xChartDoc
.is() && xReceiver
.is() )
365 ScRangeListRef aNewRanges
;
366 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
367 bool bHasCategories
= false;
368 bool bFirstCellAsLabel
= false;
370 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
372 bool bInternalData
= xChartDoc
->hasInternalDataProvider();
374 if ( bAdd
&& !bInternalData
)
376 // append to old ranges, keep other settings
378 aNewRanges
= new ScRangeList
;
379 aNewRanges
->Parse( aRangesStr
, this );
381 for ( size_t nAdd
= 0, nAddCount
= rNewList
->size(); nAdd
< nAddCount
; ++nAdd
)
382 aNewRanges
->Append( *(*rNewList
)[nAdd
] );
386 // directly use new ranges (only eDataRowSource is used from old settings)
388 if ( eDataRowSource
== chart::ChartDataRowSource_COLUMNS
)
390 bHasCategories
= bRowHeaders
;
391 bFirstCellAsLabel
= bColHeaders
;
395 bHasCategories
= bColHeaders
;
396 bFirstCellAsLabel
= bRowHeaders
;
398 aNewRanges
= rNewList
;
401 if ( bInternalData
&& pShell
)
403 // Calc -> DataProvider
404 uno::Reference
< chart2::data::XDataProvider
> xDataProvider
= new ScChart2DataProvider( this );
405 xReceiver
->attachDataProvider( xDataProvider
);
406 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier(
407 pShell
->GetModel(), uno::UNO_QUERY
);
408 xReceiver
->attachNumberFormatsSupplier( xNumberFormatsSupplier
);
412 aNewRanges
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
414 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
416 pChartListenerCollection
->ChangeListening( rChartName
, aNewRanges
);
418 return; // do not search anymore
421 pObject
= aIter
.Next();
426 void ScDocument::UpdateChart( const OUString
& rChartName
)
428 if (!pDrawLayer
|| bInDtorClear
)
430 uno::Reference
< chart2::XChartDocument
> xChartDoc( GetChartByName( rChartName
) );
435 uno::Reference
< util::XModifiable
> xModif( xChartDoc
, uno::UNO_QUERY_THROW
);
436 if( apTemporaryChartLock
.get() )
437 apTemporaryChartLock
->AlsoLockThisChart( uno::Reference
< frame::XModel
>( xModif
, uno::UNO_QUERY
) );
438 xModif
->setModified( true );
440 catch ( uno::Exception
& )
445 // After the update, chart keeps track of its own data source ranges,
446 // the listener doesn't need to listen anymore, except the chart has
447 // an internal data provider.
448 if ( !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() ) && pChartListenerCollection
)
450 pChartListenerCollection
->ChangeListening( rChartName
, new ScRangeList
);
454 void ScDocument::RestoreChartListener( const OUString
& rName
)
456 // Read the data ranges from the chart object, and start listening to those ranges again
457 // (called when a chart is saved, because then it might be swapped out and stop listening itself).
459 uno::Reference
< embed::XEmbeddedObject
> xObject
= FindOleObjectByName( rName
);
462 uno::Reference
< util::XCloseable
> xComponent
= xObject
->getComponent();
463 uno::Reference
< chart2::XChartDocument
> xChartDoc( xComponent
, uno::UNO_QUERY
);
464 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xComponent
, uno::UNO_QUERY
);
465 if ( xChartDoc
.is() && xReceiver
.is() && !xChartDoc
->hasInternalDataProvider())
467 uno::Sequence
<OUString
> aRepresentations( xReceiver
->getUsedRangeRepresentations() );
468 ScRangeListRef aRanges
= new ScRangeList
;
469 sal_Int32 nRangeCount
= aRepresentations
.getLength();
470 for ( sal_Int32 i
=0; i
<nRangeCount
; i
++ )
473 ScAddress::Details
aDetails(GetAddressConvention(), 0, 0);
474 if ( aRange
.ParseAny( aRepresentations
[i
], this, aDetails
) & SCA_VALID
)
475 aRanges
->Append( aRange
);
478 pChartListenerCollection
->ChangeListening( rName
, aRanges
);
483 void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode
,
484 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
485 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
486 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
491 ScChartListenerCollection::ListenersType
& rListeners
= pChartListenerCollection
->getListeners();
492 ScChartListenerCollection::ListenersType::iterator it
= rListeners
.begin(), itEnd
= rListeners
.end();
493 for (; it
!= itEnd
; ++it
)
495 ScChartListener
* pChartListener
= it
->second
;
496 ScRangeListRef
aRLR( pChartListener
->GetRangeList() );
497 ScRangeListRef
aNewRLR( new ScRangeList
);
498 bool bChanged
= false;
499 bool bDataChanged
= false;
500 for ( size_t i
= 0, nListSize
= aRLR
->size(); i
< nListSize
; ++i
)
502 ScRange
* pR
= (*aRLR
)[i
];
503 SCCOL theCol1
= pR
->aStart
.Col();
504 SCROW theRow1
= pR
->aStart
.Row();
505 SCTAB theTab1
= pR
->aStart
.Tab();
506 SCCOL theCol2
= pR
->aEnd
.Col();
507 SCROW theRow2
= pR
->aEnd
.Row();
508 SCTAB theTab2
= pR
->aEnd
.Tab();
509 ScRefUpdateRes eRes
= ScRefUpdate::Update(
510 this, eUpdateRefMode
,
511 nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
513 theCol1
,theRow1
,theTab1
,
514 theCol2
,theRow2
,theTab2
);
515 if ( eRes
!= UR_NOTHING
)
518 aNewRLR
->Append( ScRange(
519 theCol1
, theRow1
, theTab1
,
520 theCol2
, theRow2
, theTab2
));
521 if ( eUpdateRefMode
== URM_INSDEL
523 && (eRes
== UR_INVALID
||
524 ((pR
->aEnd
.Col() - pR
->aStart
.Col()
525 != theCol2
- theCol1
)
526 || (pR
->aEnd
.Row() - pR
->aStart
.Row()
527 != theRow2
- theRow1
)
528 || (pR
->aEnd
.Tab() - pR
->aStart
.Tab()
529 != theTab2
- theTab1
))) )
535 aNewRLR
->Append( *pR
);
540 // Force the chart to be loaded now, so it registers itself for UNO events.
541 // UNO broadcasts are done after UpdateChartRef, so the chart will get this
544 uno::Reference
<embed::XEmbeddedObject
> xIPObj
=
545 FindOleObjectByName(pChartListener
->GetName());
547 svt::EmbeddedObjectRef::TryRunningState( xIPObj
);
549 // After the change, chart keeps track of its own data source ranges,
550 // the listener doesn't need to listen anymore, except the chart has
551 // an internal data provider.
552 bool bInternalDataProvider
= false;
557 uno::Reference
< chart2::XChartDocument
> xChartDoc( xIPObj
->getComponent(), uno::UNO_QUERY_THROW
);
558 bInternalDataProvider
= xChartDoc
->hasInternalDataProvider();
560 catch ( uno::Exception
& )
564 if ( bInternalDataProvider
)
566 pChartListener
->ChangeListening( aNewRLR
, bDataChanged
);
570 pChartListener
->ChangeListening( new ScRangeList
, bDataChanged
);
578 void ScDocument::SetChartRangeList( const OUString
& rChartName
,
579 const ScRangeListRef
& rNewRangeListRef
)
581 // called from ChartListener
586 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
]; nTab
++)
588 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
589 OSL_ENSURE(pPage
,"Page ?");
591 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
592 SdrObject
* pObject
= aIter
.Next();
595 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
&&
596 OUString(((SdrOle2Obj
*)pObject
)->GetPersistName()) == rChartName
)
598 uno::Reference
< chart2::XChartDocument
> xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject
) );
599 uno::Reference
< chart2::data::XDataReceiver
> xReceiver( xChartDoc
, uno::UNO_QUERY
);
600 if ( xChartDoc
.is() && xReceiver
.is() )
602 ScRangeListRef aNewRanges
;
603 chart::ChartDataRowSource eDataRowSource
= chart::ChartDataRowSource_COLUMNS
;
604 bool bHasCategories
= false;
605 bool bFirstCellAsLabel
= false;
607 lcl_GetChartParameters( xChartDoc
, aRangesStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
610 rNewRangeListRef
->Format( sRangeStr
, SCR_ABS_3D
, this, GetAddressConvention() );
612 lcl_SetChartParameters( xReceiver
, sRangeStr
, eDataRowSource
, bHasCategories
, bFirstCellAsLabel
);
614 // don't modify pChartListenerCollection here, called from there
618 pObject
= aIter
.Next();
624 bool ScDocument::HasData( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
626 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
627 return maTabs
[nTab
]->HasData( nCol
, nRow
);
632 uno::Reference
< embed::XEmbeddedObject
>
633 ScDocument::FindOleObjectByName( const OUString
& rName
)
636 return uno::Reference
< embed::XEmbeddedObject
>();
638 // die Seiten hier vom Draw-Layer nehmen,
639 // weil sie evtl. nicht mit den Tabellen uebereinstimmen
640 // (z.B. Redo von Tabelle loeschen, Draw-Redo passiert vor DeleteTab).
642 sal_uInt16 nCount
= pDrawLayer
->GetPageCount();
643 for (sal_uInt16 nTab
=0; nTab
<nCount
; nTab
++)
645 SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
646 OSL_ENSURE(pPage
,"Page ?");
648 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
649 SdrObject
* pObject
= aIter
.Next();
652 if ( pObject
->GetObjIdentifier() == OBJ_OLE2
)
654 SdrOle2Obj
* pOleObject ( dynamic_cast< SdrOle2Obj
* >( pObject
));
656 OUString(pOleObject
->GetPersistName()) == rName
)
658 return pOleObject
->GetObjRef();
661 pObject
= aIter
.Next();
665 return uno::Reference
< embed::XEmbeddedObject
>();
668 void ScDocument::UpdateChartListenerCollection()
670 OSL_ASSERT(pChartListenerCollection
);
672 bChartListenerCollectionNeedsUpdate
= false;
676 for (SCTAB nTab
=0; nTab
< static_cast<SCTAB
>(maTabs
.size()); nTab
++)
681 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
682 OSL_ENSURE(pPage
,"Page ?");
687 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
688 ScChartListenerCollection::StringSetType
& rNonOleObjects
=
689 pChartListenerCollection
->getNonOleObjectNames();
691 for (SdrObject
* pObject
= aIter
.Next(); pObject
; pObject
= aIter
.Next())
693 if ( pObject
->GetObjIdentifier() != OBJ_OLE2
)
696 OUString aObjName
= ((SdrOle2Obj
*)pObject
)->GetPersistName();
697 ScChartListener
* pListener
= pChartListenerCollection
->findByName(aObjName
);
700 pListener
->SetUsed(true);
701 else if (rNonOleObjects
.count(aObjName
) > 0)
703 // non-chart OLE object -> don't touch
707 bool bIsChart
= false;
709 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pObject
)->GetObjRef();
710 OSL_ENSURE( xIPObj
.is(), "No embedded object is given!");
711 uno::Reference
< ::com::sun::star::chart2::data::XDataReceiver
> xReceiver
;
712 uno::Reference
< embed::XComponentSupplier
> xCompSupp( xIPObj
, uno::UNO_QUERY
);
714 xReceiver
.set( xCompSupp
->getComponent(), uno::UNO_QUERY
);
716 // if the object is a chart2::XDataReceiver, we must attach as XDataProvider
717 if( xReceiver
.is() &&
718 !PastingDrawFromOtherDoc())
720 // NOTE: this currently does not work as we are
721 // unable to set the data. So a chart from the
722 // same document is treated like a chart with
723 // own data for the time being.
726 // number formats supplier
729 // how to set?? Defined in XML-file, which is already loaded!!!
730 // => we have to do this stuff here, BEFORE the chart is actually loaded
735 // put into list of other ole objects, so the object doesn't have to
736 // be swapped in the next time UpdateChartListenerCollection is called
737 //! remove names when objects are no longer there?
738 // (object names aren't used again before reloading the document)
740 rNonOleObjects
.insert(aObjName
);
745 // alle nicht auf SetUsed gesetzten loeschen
746 pChartListenerCollection
->FreeUnused();
749 void ScDocument::AddOLEObjectToCollection(const OUString
& rName
)
751 OSL_ASSERT(pChartListenerCollection
);
752 ScChartListenerCollection::StringSetType
& rNonOleObjects
=
753 pChartListenerCollection
->getNonOleObjectNames();
755 rNonOleObjects
.insert(rName
);
759 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */