xref: /trunk/main/sc/source/core/data/documen5.cxx (revision b3f79822)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 #include <com/sun/star/util/XModifiable.hpp>
28 #include <com/sun/star/chart/ChartDataRowSource.hpp>
29 #include <com/sun/star/chart2/XChartDocument.hpp>
30 #include <com/sun/star/chart2/data/XDataProvider.hpp>
31 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
32 #include <com/sun/star/embed/EmbedStates.hpp>
33 #include <com/sun/star/embed/XEmbeddedObject.hpp>
34 
35 
36 #ifdef _MSC_VER
37 #pragma optimize("",off)
38 #endif
39 
40 // INCLUDE ---------------------------------------------------------------
41 
42 #include <sfx2/objsh.hxx>
43 #include <svx/svditer.hxx>
44 #include <svx/svdoole2.hxx>
45 #include <svx/svdpage.hxx>
46 
47 //REMOVE	#ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED
48 //REMOVE	#define SO2_DECL_SVINPLACEOBJECT_DEFINED
49 //REMOVE	SO2_DECL_REF(SvInPlaceObject)
50 //REMOVE	#endif
51 
52 #include "document.hxx"
53 #include "drwlayer.hxx"
54 #include "chartarr.hxx"
55 #include "chartlis.hxx"
56 #include "chartlock.hxx"
57 #include "refupdat.hxx"
58 #include <tools/globname.hxx>
59 #include <sot/exchange.hxx>
60 
61 #include "miscuno.hxx"
62 #include "chart2uno.hxx"
63 #include "charthelper.hxx"
64 
65 using namespace ::com::sun::star;
66 
67 // -----------------------------------------------------------------------
68 
lcl_GetChartParameters(const uno::Reference<chart2::XChartDocument> & xChartDoc,rtl::OUString & rRanges,chart::ChartDataRowSource & rDataRowSource,bool & rHasCategories,bool & rFirstCellAsLabel)69 void lcl_GetChartParameters( const uno::Reference< chart2::XChartDocument >& xChartDoc,
70             rtl::OUString& rRanges, chart::ChartDataRowSource& rDataRowSource,
71             bool& rHasCategories, bool& rFirstCellAsLabel )
72 {
73     rHasCategories = rFirstCellAsLabel = false;     // default if not in sequence
74 
75     uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
76 
77     uno::Reference< chart2::data::XDataSource > xDataSource = xReceiver->getUsedData();
78     uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
79 
80     if ( xProvider.is() )
81     {
82         uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xDataSource ) );
83 
84         const beans::PropertyValue* pPropArray = aArgs.getConstArray();
85         long nPropCount = aArgs.getLength();
86         for (long i = 0; i < nPropCount; i++)
87         {
88             const beans::PropertyValue& rProp = pPropArray[i];
89             String aPropName(rProp.Name);
90 
91             if (aPropName.EqualsAscii( "CellRangeRepresentation" ))
92                 rProp.Value >>= rRanges;
93             else if (aPropName.EqualsAscii( "DataRowSource" ))
94                 rDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
95             else if (aPropName.EqualsAscii( "HasCategories" ))
96                 rHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
97             else if (aPropName.EqualsAscii( "FirstCellAsLabel" ))
98                 rFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
99         }
100     }
101 }
102 
lcl_SetChartParameters(const uno::Reference<chart2::data::XDataReceiver> & xReceiver,const rtl::OUString & rRanges,chart::ChartDataRowSource eDataRowSource,bool bHasCategories,bool bFirstCellAsLabel)103 void lcl_SetChartParameters( const uno::Reference< chart2::data::XDataReceiver >& xReceiver,
104             const rtl::OUString& rRanges, chart::ChartDataRowSource eDataRowSource,
105             bool bHasCategories, bool bFirstCellAsLabel )
106 {
107     if ( xReceiver.is() )
108     {
109         uno::Sequence< beans::PropertyValue > aArgs( 4 );
110         aArgs[0] = beans::PropertyValue(
111             ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
112             uno::makeAny( rRanges ), beans::PropertyState_DIRECT_VALUE );
113         aArgs[1] = beans::PropertyValue(
114             ::rtl::OUString::createFromAscii("HasCategories"), -1,
115             uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
116         aArgs[2] = beans::PropertyValue(
117             ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
118             uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
119         aArgs[3] = beans::PropertyValue(
120             ::rtl::OUString::createFromAscii("DataRowSource"), -1,
121             uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
122         xReceiver->setArguments( aArgs );
123     }
124 }
125 
126 // update charts after loading old document
127 
UpdateAllCharts()128 void ScDocument::UpdateAllCharts()
129 {
130     if ( !pDrawLayer || !pShell )
131 		return;
132 
133 	sal_uInt16 nDataCount = pChartCollection->GetCount();
134 	if ( !nDataCount )
135 		return ;		// nothing to do
136 
137 	sal_uInt16 nPos;
138 
139 	for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
140 	{
141 		if (pTab[nTab])
142 		{
143 			SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
144 			DBG_ASSERT(pPage,"Page ?");
145 
146 			ScRange aRange;
147 			SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
148 			SdrObject* pObject = aIter.Next();
149 			while (pObject)
150 			{
151 				if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
152 				{
153 					uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
154 					if ( xIPObj.is() )
155 					{
156 						String aIPName = ((SdrOle2Obj*)pObject)->GetPersistName();
157 
158 						for (nPos=0; nPos<nDataCount; nPos++)
159 						{
160 							ScChartArray* pChartObj = (*pChartCollection)[nPos];
161 							if (pChartObj->GetName() == aIPName)
162 							{
163                                 ScRangeListRef aRanges = pChartObj->GetRangeList();
164                                 String sRangeStr;
165                                 aRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
166 
167                                 chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
168                                 bool bHasCategories = pChartObj->HasRowHeaders();
169                                 bool bFirstCellAsLabel = pChartObj->HasColHeaders();
170 
171                                 // Calc -> DataProvider
172                                 uno::Reference< chart2::data::XDataProvider > xDataProvider =
173                                         new ScChart2DataProvider( this );
174                                 // Chart -> DataReceiver
175                                 uno::Reference< chart2::data::XDataReceiver > xReceiver;
176                                 uno::Reference< embed::XComponentSupplier > xCompSupp( xIPObj, uno::UNO_QUERY );
177                                 if( xCompSupp.is())
178                                     xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
179                                 if( xReceiver.is())
180                                 {
181                                     // connect
182                                     xReceiver->attachDataProvider( xDataProvider );
183                                     uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier(
184                                             pShell->GetModel(), uno::UNO_QUERY );
185                                     xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
186 
187                                     lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource,
188                                                             bHasCategories, bFirstCellAsLabel );
189                                 }
190 
191 								ScChartListener* pCL = new ScChartListener(
192 									aIPName, this, pChartObj->GetRangeList() );
193 								pChartListenerCollection->Insert( pCL );
194 								pCL->StartListeningTo();
195 							}
196 						}
197 					}
198 				}
199 				pObject = aIter.Next();
200 			}
201 		}
202 	}
203 
204 	pChartCollection->FreeAll();
205 }
206 
HasChartAtPoint(SCTAB nTab,const Point & rPos,String * pName)207 sal_Bool ScDocument::HasChartAtPoint( SCTAB nTab, const Point& rPos, String* pName )
208 {
209 	if (pDrawLayer && pTab[nTab])
210 	{
211 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
212 		DBG_ASSERT(pPage,"Page ?");
213 
214 		SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
215 		SdrObject* pObject = aIter.Next();
216 		while (pObject)
217 		{
218 			if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
219 				 pObject->GetCurrentBoundRect().IsInside(rPos) )
220 			{
221 						// auch Chart-Objekte die nicht in der Collection sind
222 
223 				if (IsChart(pObject))
224 				{
225 					if (pName)
226 						*pName = ((SdrOle2Obj*)pObject)->GetPersistName();
227 					return sal_True;
228 				}
229 			}
230 			pObject = aIter.Next();
231 		}
232 	}
233 
234 	if (pName)
235 		pName->Erase();
236 	return sal_False;					// nix gefunden
237 }
238 
UpdateChartArea(const String & rChartName,const ScRange & rNewArea,sal_Bool bColHeaders,sal_Bool bRowHeaders,sal_Bool bAdd)239 void ScDocument::UpdateChartArea( const String& rChartName,
240 			const ScRange& rNewArea, sal_Bool bColHeaders, sal_Bool bRowHeaders,
241 			sal_Bool bAdd )
242 {
243 	ScRangeListRef aRLR( new ScRangeList );
244 	aRLR->Append( rNewArea );
245 	UpdateChartArea( rChartName, aRLR, bColHeaders, bRowHeaders, bAdd );
246 }
247 
GetChartByName(const String & rChartName)248 uno::Reference< chart2::XChartDocument > ScDocument::GetChartByName( const String& rChartName )
249 {
250     uno::Reference< chart2::XChartDocument > xReturn;
251 
252     if (pDrawLayer)
253     {
254         sal_uInt16 nCount = pDrawLayer->GetPageCount();
255         for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
256         {
257             SdrPage* pPage = pDrawLayer->GetPage(nTab);
258             DBG_ASSERT(pPage,"Page ?");
259 
260             SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
261             SdrObject* pObject = aIter.Next();
262             while (pObject)
263             {
264                 if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
265                         ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
266                 {
267                     xReturn.set( ScChartHelper::GetChartFromSdrObject( pObject ) );
268                     return xReturn;
269                 }
270                 pObject = aIter.Next();
271             }
272         }
273     }
274     return xReturn;
275 }
GetChartRanges(const String & rChartName,::std::vector<ScRangeList> & rRangesVector,ScDocument * pSheetNameDoc)276 void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRangeList >& rRangesVector, ScDocument* pSheetNameDoc )
277 {
278     rRangesVector.clear();
279     uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
280     if ( xChartDoc.is() )
281     {
282         uno::Sequence< rtl::OUString > aRangeStrings;
283         ScChartHelper::GetChartRanges( xChartDoc, aRangeStrings );
284         for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ )
285         {
286             ScRangeList aRanges;
287             aRanges.Parse( aRangeStrings[nN], pSheetNameDoc, SCA_VALID, pSheetNameDoc->GetAddressConvention() );
288             rRangesVector.push_back(aRanges);
289         }
290     }
291 }
292 
SetChartRanges(const String & rChartName,const::std::vector<ScRangeList> & rRangesVector)293 void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector< ScRangeList >& rRangesVector )
294 {
295     uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
296     if ( xChartDoc.is() )
297     {
298         sal_Int32 nCount = static_cast<sal_Int32>( rRangesVector.size() );
299         uno::Sequence< rtl::OUString > aRangeStrings(nCount);
300         for( sal_Int32 nN=0; nN<nCount; nN++ )
301         {
302             ScRangeList aScRangeList( rRangesVector[nN] );
303             String sRangeStr; // This range must be in Calc A1 format.
304             aScRangeList.Format( sRangeStr, SCR_ABS_3D, this );
305             aRangeStrings[nN]=sRangeStr;
306         }
307         ScChartHelper::SetChartRanges( xChartDoc, aRangeStrings );
308     }
309 }
310 
GetOldChartParameters(const String & rName,ScRangeList & rRanges,sal_Bool & rColHeaders,sal_Bool & rRowHeaders)311 void ScDocument::GetOldChartParameters( const String& rName,
312             ScRangeList& rRanges, sal_Bool& rColHeaders, sal_Bool& rRowHeaders )
313 {
314     // used for undo of changing chart source area
315 
316     if (!pDrawLayer)
317         return;
318 
319     sal_uInt16 nCount = pDrawLayer->GetPageCount();
320     for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
321     {
322         SdrPage* pPage = pDrawLayer->GetPage(nTab);
323         DBG_ASSERT(pPage,"Page ?");
324 
325         SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
326         SdrObject* pObject = aIter.Next();
327         while (pObject)
328         {
329             if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
330                     ((SdrOle2Obj*)pObject)->GetPersistName() == rName )
331             {
332                 uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
333                 if ( xChartDoc.is() )
334                 {
335                     chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
336                     bool bHasCategories = false;
337                     bool bFirstCellAsLabel = false;
338                     rtl::OUString aRangesStr;
339                     lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
340 
341                     rRanges.Parse( aRangesStr, this );
342                     if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
343                     {
344                         rRowHeaders = bHasCategories;
345                         rColHeaders = bFirstCellAsLabel;
346                     }
347                     else
348                     {
349                         rColHeaders = bHasCategories;
350                         rRowHeaders = bFirstCellAsLabel;
351                     }
352                 }
353                 return;
354             }
355             pObject = aIter.Next();
356         }
357     }
358 }
359 
UpdateChartArea(const String & rChartName,const ScRangeListRef & rNewList,sal_Bool bColHeaders,sal_Bool bRowHeaders,sal_Bool bAdd)360 void ScDocument::UpdateChartArea( const String& rChartName,
361 			const ScRangeListRef& rNewList, sal_Bool bColHeaders, sal_Bool bRowHeaders,
362 			sal_Bool bAdd )
363 {
364 	if (!pDrawLayer)
365 		return;
366 
367 	for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
368 	{
369 		SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
370 		DBG_ASSERT(pPage,"Page ?");
371 
372 		SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
373 		SdrObject* pObject = aIter.Next();
374 		while (pObject)
375 		{
376 			if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
377 					((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
378 			{
379                 uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
380                 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
381                 if ( xChartDoc.is() && xReceiver.is() )
382                 {
383                     ScRangeListRef aNewRanges;
384                     chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
385                     bool bHasCategories = false;
386                     bool bFirstCellAsLabel = false;
387                     rtl::OUString aRangesStr;
388                     lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
389 
390                     sal_Bool bInternalData = xChartDoc->hasInternalDataProvider();
391 
392                     if ( bAdd && !bInternalData )
393                     {
394                         // append to old ranges, keep other settings
395 
396                         aNewRanges = new ScRangeList;
397                         aNewRanges->Parse( aRangesStr, this );
398 
399                         sal_uLong nAddCount = rNewList->Count();
400                         for ( sal_uLong nAdd=0; nAdd<nAddCount; nAdd++ )
401                             aNewRanges->Append( *rNewList->GetObject(nAdd) );
402                     }
403                     else
404                     {
405                         // directly use new ranges (only eDataRowSource is used from old settings)
406 
407                         if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
408                         {
409                             bHasCategories = bRowHeaders;
410                             bFirstCellAsLabel = bColHeaders;
411                         }
412                         else
413                         {
414                             bHasCategories = bColHeaders;
415                             bFirstCellAsLabel = bRowHeaders;
416                         }
417                         aNewRanges = rNewList;
418                     }
419 
420                     if ( bInternalData && pShell )
421                     {
422                         // Calc -> DataProvider
423                         uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this );
424                         xReceiver->attachDataProvider( xDataProvider );
425                         uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier(
426                                 pShell->GetModel(), uno::UNO_QUERY );
427                         xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
428                     }
429 
430                     String sRangeStr;
431                     aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
432 
433                     lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
434 
435                     pChartListenerCollection->ChangeListening( rChartName, aNewRanges );
436 
437                     // ((SdrOle2Obj*)pObject)->GetNewReplacement();
438                     // pObject->ActionChanged();
439 
440 					return;			// nicht weitersuchen
441 				}
442 			}
443 			pObject = aIter.Next();
444 		}
445 	}
446 }
447 
UpdateChart(const String & rChartName)448 void ScDocument::UpdateChart( const String& rChartName )
449 {
450 	if (!pDrawLayer || bInDtorClear)
451 		return;
452     uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) );
453     if( xChartDoc.is() )
454     {
455         try
456         {
457             uno::Reference< util::XModifiable > xModif( xChartDoc, uno::UNO_QUERY_THROW );
458             if( apTemporaryChartLock.get() )
459                 apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) );
460             xModif->setModified( sal_True );
461         }
462         catch ( uno::Exception& )
463         {
464         }
465     }
466 
467     // After the update, chart keeps track of its own data source ranges,
468     // the listener doesn't need to listen anymore, except the chart has
469     // an internal data provider.
470     if ( !( xChartDoc.is() && xChartDoc->hasInternalDataProvider() ) && pChartListenerCollection )
471     {
472         pChartListenerCollection->ChangeListening( rChartName, new ScRangeList );
473 	}
474 }
475 
RestoreChartListener(const String & rName)476 void ScDocument::RestoreChartListener( const String& rName )
477 {
478     // Read the data ranges from the chart object, and start listening to those ranges again
479     // (called when a chart is saved, because then it might be swapped out and stop listening itself).
480 
481     uno::Reference< embed::XEmbeddedObject > xObject = FindOleObjectByName( rName );
482     if ( xObject.is() )
483     {
484         uno::Reference< util::XCloseable > xComponent = xObject->getComponent();
485         uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY );
486         uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY );
487         if ( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider())
488         {
489             uno::Sequence<rtl::OUString> aRepresentations( xReceiver->getUsedRangeRepresentations() );
490             ScRangeListRef aRanges = new ScRangeList;
491             sal_Int32 nRangeCount = aRepresentations.getLength();
492             for ( sal_Int32 i=0; i<nRangeCount; i++ )
493             {
494                 ScRange aRange;
495                 ScAddress::Details aDetails(GetAddressConvention(), 0, 0);
496                 if ( aRange.ParseAny( aRepresentations[i], this, aDetails ) & SCA_VALID )
497                     aRanges->Append( aRange );
498             }
499 
500             pChartListenerCollection->ChangeListening( rName, aRanges );
501         }
502     }
503 }
504 
UpdateChartRef(UpdateRefMode eUpdateRefMode,SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)505 void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode,
506 									SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
507 									SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
508 									SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
509 {
510 	if (!pDrawLayer)
511 		return;
512 
513 	sal_uInt16 nChartCount = pChartListenerCollection->GetCount();
514 	for ( sal_uInt16 nIndex = 0; nIndex < nChartCount; nIndex++ )
515 	{
516 		ScChartListener* pChartListener =
517 			(ScChartListener*) (pChartListenerCollection->At(nIndex));
518 		ScRangeListRef aRLR( pChartListener->GetRangeList() );
519 		ScRangeListRef aNewRLR( new ScRangeList );
520 		sal_Bool bChanged = sal_False;
521 		sal_Bool bDataChanged = sal_False;
522 		for ( ScRangePtr pR = aRLR->First(); pR; pR = aRLR->Next() )
523 		{
524 			SCCOL theCol1 = pR->aStart.Col();
525 			SCROW theRow1 = pR->aStart.Row();
526 			SCTAB theTab1 = pR->aStart.Tab();
527 			SCCOL theCol2 = pR->aEnd.Col();
528 			SCROW theRow2 = pR->aEnd.Row();
529 			SCTAB theTab2 = pR->aEnd.Tab();
530 			ScRefUpdateRes eRes = ScRefUpdate::Update(
531 				this, eUpdateRefMode,
532 				nCol1,nRow1,nTab1, nCol2,nRow2,nTab2,
533 				nDx,nDy,nDz,
534 				theCol1,theRow1,theTab1,
535 				theCol2,theRow2,theTab2 );
536 			if ( eRes != UR_NOTHING )
537 			{
538 				bChanged = sal_True;
539 				aNewRLR->Append( ScRange(
540 					theCol1, theRow1, theTab1,
541 					theCol2, theRow2, theTab2 ));
542 				if ( eUpdateRefMode == URM_INSDEL
543 					&& !bDataChanged
544 					&& (eRes == UR_INVALID ||
545 						((pR->aEnd.Col() - pR->aStart.Col()
546 						!= theCol2 - theCol1)
547 					|| (pR->aEnd.Row() - pR->aStart.Row()
548 						!= theRow2 - theRow1)
549 					|| (pR->aEnd.Tab() - pR->aStart.Tab()
550 						!= theTab2 - theTab1))) )
551 				{
552 					bDataChanged = sal_True;
553 				}
554 			}
555 			else
556 				aNewRLR->Append( *pR );
557 		}
558 		if ( bChanged )
559 		{
560 #if 0
561 			if ( nDz != 0 )
562 			{	// #81844# sheet to be deleted or inserted or moved
563 				// => no valid sheet names for references right now
564 				pChartListener->ChangeListening( aNewRLR, bDataChanged );
565 				pChartListener->ScheduleSeriesRanges();
566 			}
567 			else
568 #endif
569 			{
570 //				SetChartRangeList( pChartListener->GetString(), aNewRLR );
571 //				pChartListener->ChangeListening( aNewRLR, bDataChanged );
572 
573                 // Force the chart to be loaded now, so it registers itself for UNO events.
574                 // UNO broadcasts are done after UpdateChartRef, so the chart will get this
575                 // reference change.
576 
577                 uno::Reference< embed::XEmbeddedObject > xIPObj = FindOleObjectByName( pChartListener->GetString() );
578                 svt::EmbeddedObjectRef::TryRunningState( xIPObj );
579 
580                 // After the change, chart keeps track of its own data source ranges,
581                 // the listener doesn't need to listen anymore, except the chart has
582                 // an internal data provider.
583                 bool bInternalDataProvider = false;
584                 if ( xIPObj.is() )
585                 {
586                     try
587                     {
588                         uno::Reference< chart2::XChartDocument > xChartDoc( xIPObj->getComponent(), uno::UNO_QUERY_THROW );
589                         bInternalDataProvider = xChartDoc->hasInternalDataProvider();
590                     }
591                     catch ( uno::Exception& )
592                     {
593                     }
594                 }
595                 if ( bInternalDataProvider )
596                 {
597                     pChartListener->ChangeListening( aNewRLR, bDataChanged );
598                 }
599                 else
600                 {
601                     pChartListener->ChangeListening( new ScRangeList, bDataChanged );
602                 }
603 			}
604 		}
605 	}
606 }
607 
608 
SetChartRangeList(const String & rChartName,const ScRangeListRef & rNewRangeListRef)609 void ScDocument::SetChartRangeList( const String& rChartName,
610 			const ScRangeListRef& rNewRangeListRef )
611 {
612     // called from ChartListener
613 
614     if (!pDrawLayer)
615         return;
616 
617     for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++)
618     {
619         SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
620         DBG_ASSERT(pPage,"Page ?");
621 
622         SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
623         SdrObject* pObject = aIter.Next();
624         while (pObject)
625         {
626             if ( pObject->GetObjIdentifier() == OBJ_OLE2 &&
627                     ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName )
628             {
629                 uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) );
630                 uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
631                 if ( xChartDoc.is() && xReceiver.is() )
632                 {
633                     ScRangeListRef aNewRanges;
634                     chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
635                     bool bHasCategories = false;
636                     bool bFirstCellAsLabel = false;
637                     rtl::OUString aRangesStr;
638                     lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
639 
640                     String sRangeStr;
641                     rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() );
642 
643                     lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel );
644 
645                     // don't modify pChartListenerCollection here, called from there
646                     return;
647                 }
648             }
649             pObject = aIter.Next();
650         }
651     }
652 }
653 
654 
HasData(SCCOL nCol,SCROW nRow,SCTAB nTab)655 sal_Bool ScDocument::HasData( SCCOL nCol, SCROW nRow, SCTAB nTab )
656 {
657 	if (pTab[nTab])
658 		return pTab[nTab]->HasData( nCol, nRow );
659 	else
660 		return sal_False;
661 }
662 
663 uno::Reference< embed::XEmbeddedObject >
FindOleObjectByName(const String & rName)664     ScDocument::FindOleObjectByName( const String& rName )
665 {
666     if (!pDrawLayer)
667 		return uno::Reference< embed::XEmbeddedObject >();
668 
669 	//	die Seiten hier vom Draw-Layer nehmen,
670 	//	weil sie evtl. nicht mit den Tabellen uebereinstimmen
671 	//	(z.B. Redo von Tabelle loeschen, Draw-Redo passiert vor DeleteTab).
672 
673 	sal_uInt16 nCount = pDrawLayer->GetPageCount();
674 	for (sal_uInt16 nTab=0; nTab<nCount; nTab++)
675 	{
676 		SdrPage* pPage = pDrawLayer->GetPage(nTab);
677 		DBG_ASSERT(pPage,"Page ?");
678 
679 		SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
680 		SdrObject* pObject = aIter.Next();
681 		while (pObject)
682 		{
683 			if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
684             {
685                 SdrOle2Obj * pOleObject ( dynamic_cast< SdrOle2Obj * >( pObject ));
686                 if( pOleObject &&
687 					pOleObject->GetPersistName() == rName )
688                 {
689                     return pOleObject->GetObjRef();
690                 }
691             }
692 			pObject = aIter.Next();
693         }
694     }
695 
696     return uno::Reference< embed::XEmbeddedObject >();
697 }
698 
lcl_StringInCollection(const ScStrCollection * pColl,const String & rStr)699 sal_Bool lcl_StringInCollection( const ScStrCollection* pColl, const String& rStr )
700 {
701 	if ( !pColl )
702 		return sal_False;
703 
704 	StrData aData( rStr );
705 	sal_uInt16 nDummy;
706 	return pColl->Search( &aData, nDummy );
707 }
708 
UpdateChartListenerCollection()709 void ScDocument::UpdateChartListenerCollection()
710 {
711 	bChartListenerCollectionNeedsUpdate = sal_False;
712 	if (!pDrawLayer)
713 		return;
714 	else
715 	{
716 		ScRange aRange;
717 		// Range fuer Suche unwichtig
718 		ScChartListener aCLSearcher( EMPTY_STRING, this, aRange );
719 		for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
720 		{
721 			if (pTab[nTab])
722 			{
723 				SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
724 				DBG_ASSERT(pPage,"Page ?");
725 
726                 if (!pPage)
727                     continue;
728 
729 				SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
730 				SdrObject* pObject = aIter.Next();
731 				while (pObject)
732 				{
733 					if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
734 					{
735 						String aObjName = ((SdrOle2Obj*)pObject)->GetPersistName();
736 						aCLSearcher.SetString( aObjName );
737 						sal_uInt16 nIndex;
738 						if ( pChartListenerCollection->Search( &aCLSearcher, nIndex ) )
739 						{
740 							((ScChartListener*) (pChartListenerCollection->
741 								At( nIndex )))->SetUsed( sal_True );
742 						}
743 						else if ( lcl_StringInCollection( pOtherObjects, aObjName ) )
744 						{
745 							// non-chart OLE object -> don't touch
746 						}
747 						else
748 						{
749 						    bool bIsChart = false;
750 
751 							uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
752                             DBG_ASSERT( xIPObj.is(), "No embedded object is given!");
753                             uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
754                             uno::Reference< embed::XComponentSupplier > xCompSupp( xIPObj, uno::UNO_QUERY );
755                             if( xCompSupp.is())
756                                 xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
757 
758                             // if the object is a chart2::XDataReceiver, we must attach as XDataProvider
759                             if( xReceiver.is() &&
760                                 !PastingDrawFromOtherDoc())
761                             {
762                                 // NOTE: this currently does not work as we are
763                                 // unable to set the data. So a chart from the
764                                 // same document is treated like a chart with
765                                 // own data for the time being.
766 #if 0
767                                 // data provider
768                                 uno::Reference< chart2::data::XDataProvider > xDataProvider = new
769                                     ScChart2DataProvider( this );
770                                 xReceiver->attachDataProvider( xDataProvider );
771                                 // number formats supplier
772                                 uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pShell->GetModel(), uno::UNO_QUERY );
773                                 xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
774                                 // data ?
775                                 // how to set?? Defined in XML-file, which is already loaded!!!
776                                 // => we have to do this stuff here, BEFORE the chart is actually loaded
777 
778                                 bIsChart = true;
779 #endif
780                             }
781 
782 						    if (!bIsChart)
783 						    {
784 							    //	put into list of other ole objects, so the object doesn't have to
785 							    //	be swapped in the next time UpdateChartListenerCollection is called
786 							    //!	remove names when objects are no longer there?
787 							    //	(object names aren't used again before reloading the document)
788 
789 							    if (!pOtherObjects)
790 								    pOtherObjects = new ScStrCollection;
791 							    pOtherObjects->Insert( new StrData( aObjName ) );
792 						    }
793 						}
794 					}
795 					pObject = aIter.Next();
796 				}
797 			}
798 		}
799 		// alle nicht auf SetUsed gesetzten loeschen
800 		pChartListenerCollection->FreeUnused();
801 	}
802 }
803 
AddOLEObjectToCollection(const String & rName)804 void ScDocument::AddOLEObjectToCollection(const String& rName)
805 {
806 	if (!pOtherObjects)
807 		pOtherObjects = new ScStrCollection;
808 	pOtherObjects->Insert( new StrData( rName ) );
809 }
810 
811 
812 
813