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