Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / documen5.cxx
blobb769c4d684876d2a24294936b1183a82f36341a7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
35 #include "table.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();
63 if ( xProvider.is() )
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 )
90 if ( xReceiver.is() )
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 )
114 return;
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++)
124 if (maTabs[nTab])
126 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
127 OSL_ENSURE(pPage,"Page ?");
129 ScRange aRange;
130 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
131 SdrObject* pObject = aIter.Next();
132 while (pObject)
134 if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
136 uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
137 if ( xIPObj.is() )
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();
147 OUString sRangeStr;
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 );
160 if( xCompSupp.is())
161 xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
162 if( xReceiver.is())
164 // connect
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();
199 while (pObject)
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();
209 return true;
212 pObject = aIter.Next();
216 rName = OUString();
217 return false; // nothing found
220 void ScDocument::UpdateChartArea( const OUString& rChartName,
221 const ScRange& rNewArea, bool bColHeaders, bool bRowHeaders,
222 bool bAdd )
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;
233 if (pDrawLayer)
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();
244 while (pObject)
246 if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
247 OUString(((SdrOle2Obj*)pObject)->GetPersistName()) == rChartName )
249 xReturn.set( ScChartHelper::GetChartFromSdrObject( pObject ) );
250 return xReturn;
252 pObject = aIter.Next();
256 return xReturn;
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++ )
268 ScRangeList aRanges;
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] );
285 OUString sRangeStr;
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
298 if (!pDrawLayer)
299 return;
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();
309 while (pObject)
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;
320 OUString aRangesStr;
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;
329 else
331 rColHeaders = bHasCategories;
332 rRowHeaders = bFirstCellAsLabel;
335 return;
337 pObject = aIter.Next();
342 void ScDocument::UpdateChartArea( const OUString& rChartName,
343 const ScRangeListRef& rNewList, bool bColHeaders, bool bRowHeaders,
344 bool bAdd )
346 if (!pDrawLayer)
347 return;
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();
356 while (pObject)
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;
369 OUString aRangesStr;
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] );
384 else
386 // directly use new ranges (only eDataRowSource is used from old settings)
388 if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
390 bHasCategories = bRowHeaders;
391 bFirstCellAsLabel = bColHeaders;
393 else
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 );
411 OUString sRangeStr;
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)
429 return;
430 uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
431 if( xChartDoc.is() )
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 );
460 if ( xObject.is() )
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++ )
472 ScRange aRange;
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 )
488 if (!pDrawLayer)
489 return;
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,
512 nDx,nDy,nDz,
513 theCol1,theRow1,theTab1,
514 theCol2,theRow2,theTab2 );
515 if ( eRes != UR_NOTHING )
517 bChanged = true;
518 aNewRLR->Append( ScRange(
519 theCol1, theRow1, theTab1,
520 theCol2, theRow2, theTab2 ));
521 if ( eUpdateRefMode == URM_INSDEL
522 && !bDataChanged
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))) )
531 bDataChanged = true;
534 else
535 aNewRLR->Append( *pR );
537 if ( bChanged )
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
542 // reference change.
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;
553 if ( xIPObj.is() )
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 );
568 else
570 pChartListener->ChangeListening( new ScRangeList, bDataChanged );
578 void ScDocument::SetChartRangeList( const OUString& rChartName,
579 const ScRangeListRef& rNewRangeListRef )
581 // called from ChartListener
583 if (!pDrawLayer)
584 return;
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();
593 while (pObject)
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;
606 OUString aRangesStr;
607 lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
609 OUString sRangeStr;
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
615 return;
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 );
628 else
629 return false;
632 uno::Reference< embed::XEmbeddedObject >
633 ScDocument::FindOleObjectByName( const OUString& rName )
635 if (!pDrawLayer)
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();
650 while (pObject)
652 if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
654 SdrOle2Obj * pOleObject ( dynamic_cast< SdrOle2Obj * >( pObject ));
655 if( pOleObject &&
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;
673 if (!pDrawLayer)
674 return;
676 for (SCTAB nTab=0; nTab< static_cast<SCTAB>(maTabs.size()); nTab++)
678 if (!maTabs[nTab])
679 continue;
681 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
682 OSL_ENSURE(pPage,"Page ?");
684 if (!pPage)
685 continue;
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 )
694 continue;
696 OUString aObjName = ((SdrOle2Obj*)pObject)->GetPersistName();
697 ScChartListener* pListener = pChartListenerCollection->findByName(aObjName);
699 if (pListener)
700 pListener->SetUsed(true);
701 else if (rNonOleObjects.count(aObjName) > 0)
703 // non-chart OLE object -> don't touch
705 else
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 );
713 if( xCompSupp.is())
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.
725 // data provider
726 // number formats supplier
728 // data ?
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
733 if (!bIsChart)
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: */