Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/Aspects.hpp>
21 : #include <com/sun/star/awt/Size.hpp>
22 : #include <com/sun/star/beans/PropertyAttribute.hpp>
23 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
24 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
25 : #include <com/sun/star/chart2/XChartDocument.hpp>
26 : #include <com/sun/star/table/CellRangeAddress.hpp>
27 :
28 : #include <svx/svditer.hxx>
29 : #include <svx/svdoole2.hxx>
30 : #include <svx/svdpage.hxx>
31 : #include <svx/svdundo.hxx>
32 : #include <sfx2/app.hxx>
33 : #include <unotools/moduleoptions.hxx>
34 : #include <comphelper/classids.hxx>
35 : #include <toolkit/helper/vclunohelper.hxx>
36 : #include <svx/charthelper.hxx>
37 : #include <svtools/embedhlp.hxx>
38 :
39 : #include "chartuno.hxx"
40 : #include "miscuno.hxx"
41 : #include "docsh.hxx"
42 : #include "drwlayer.hxx"
43 : #include "undodat.hxx"
44 : #include "chartarr.hxx"
45 : #include "chartlis.hxx"
46 : #include "chart2uno.hxx"
47 : #include "convuno.hxx"
48 :
49 : using namespace com::sun::star;
50 :
51 : #define PROP_HANDLE_RELATED_CELLRANGES 1
52 :
53 0 : SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" )
54 0 : SC_SIMPLE_SERVICE_INFO( ScChartsObj, "ScChartsObj", "com.sun.star.table.TableCharts" )
55 :
56 82 : static SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
57 : {
58 82 : if (pDocShell)
59 : {
60 82 : ScDocument& rDoc = pDocShell->GetDocument();
61 82 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
62 82 : if (pDrawLayer)
63 : {
64 82 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
65 : OSL_ENSURE(pPage, "Page nicht gefunden");
66 82 : if (pPage)
67 : {
68 82 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
69 82 : SdrObject* pObject = aIter.Next();
70 169 : while (pObject)
71 : {
72 82 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
73 : {
74 82 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
75 82 : if ( xObj.is() )
76 : {
77 82 : OUString aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
78 82 : if ( aObjName == rName )
79 77 : return static_cast<SdrOle2Obj*>(pObject);
80 5 : }
81 : }
82 5 : pObject = aIter.Next();
83 5 : }
84 : }
85 : }
86 : }
87 5 : return NULL;
88 : }
89 :
90 72 : ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
91 : pDocShell( pDocSh ),
92 72 : nTab( nT )
93 : {
94 72 : pDocShell->GetDocument().AddUnoObject(*this);
95 72 : }
96 :
97 216 : ScChartsObj::~ScChartsObj()
98 : {
99 72 : SolarMutexGuard g;
100 :
101 72 : if (pDocShell)
102 66 : pDocShell->GetDocument().RemoveUnoObject(*this);
103 144 : }
104 :
105 6 : void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
106 : {
107 : //! Referenz-Update
108 :
109 6 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
110 6 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
111 : {
112 6 : pDocShell = NULL; // ungueltig geworden
113 : }
114 6 : }
115 :
116 72 : ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const
117 : {
118 72 : OUString aName;
119 72 : if ( pDocShell )
120 : {
121 72 : ScDocument& rDoc = pDocShell->GetDocument();
122 72 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
123 72 : if (pDrawLayer)
124 : {
125 72 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
126 : OSL_ENSURE(pPage, "Page nicht gefunden");
127 72 : if (pPage)
128 : {
129 72 : long nPos = 0;
130 72 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
131 72 : SdrObject* pObject = aIter.Next();
132 146 : while (pObject)
133 : {
134 72 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
135 : {
136 72 : if ( nPos == nIndex )
137 : {
138 70 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
139 70 : if ( xObj.is() )
140 70 : aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
141 70 : break; // nicht weitersuchen
142 : }
143 2 : ++nPos;
144 : }
145 2 : pObject = aIter.Next();
146 72 : }
147 : }
148 : }
149 : }
150 :
151 72 : if (!aName.isEmpty())
152 70 : return new ScChartObj( pDocShell, nTab, aName );
153 2 : return NULL;
154 : }
155 :
156 5 : ScChartObj* ScChartsObj::GetObjectByName_Impl(const OUString& aName) const
157 : {
158 5 : if ( lcl_FindChartObj( pDocShell, nTab, aName ) )
159 4 : return new ScChartObj( pDocShell, nTab, aName );
160 1 : return NULL;
161 : }
162 :
163 : // XTableCharts
164 :
165 7 : void SAL_CALL ScChartsObj::addNewByName( const OUString& rName,
166 : const awt::Rectangle& aRect,
167 : const uno::Sequence<table::CellRangeAddress>& aRanges,
168 : sal_Bool bColumnHeaders, sal_Bool bRowHeaders )
169 : throw(::com::sun::star::uno::RuntimeException,
170 : std::exception)
171 : {
172 7 : SolarMutexGuard aGuard;
173 7 : if (!pDocShell)
174 0 : return;
175 :
176 7 : ScDocument& rDoc = pDocShell->GetDocument();
177 7 : ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
178 7 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
179 : OSL_ENSURE(pPage,"addChart: keine Page");
180 7 : if (!pPage)
181 0 : return;
182 :
183 : // chart can't be inserted if any ole object with that name exists on any table
184 : // (empty string: generate valid name)
185 :
186 14 : OUString aName = rName;
187 : SCTAB nDummy;
188 7 : if ( !aName.isEmpty() && pModel->GetNamedObject( aName, OBJ_OLE2, nDummy ) )
189 : {
190 : // object exists - only RuntimeException is specified
191 0 : throw uno::RuntimeException();
192 : }
193 :
194 7 : ScRangeList* pList = new ScRangeList;
195 7 : sal_Int32 nRangeCount = aRanges.getLength();
196 7 : if (nRangeCount)
197 : {
198 7 : const table::CellRangeAddress* pAry = aRanges.getConstArray();
199 14 : for (sal_Int32 i=0; i<nRangeCount; i++)
200 : {
201 21 : ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
202 28 : static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
203 7 : pList->Append( aRange );
204 : }
205 : }
206 14 : ScRangeListRef xNewRanges( pList );
207 :
208 14 : uno::Reference < embed::XEmbeddedObject > xObj;
209 7 : if ( SvtModuleOptions().IsChart() )
210 7 : xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aName );
211 7 : if ( xObj.is() )
212 : {
213 : // Rechteck anpassen
214 : //! Fehler/Exception, wenn leer/ungueltig ???
215 7 : Point aRectPos( aRect.X, aRect.Y );
216 7 : bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
217 7 : if ( ( aRectPos.X() < 0 && !bLayoutRTL ) || ( aRectPos.X() > 0 && bLayoutRTL ) )
218 0 : aRectPos.X() = 0;
219 :
220 7 : if (aRectPos.Y() < 0)
221 0 : aRectPos.Y() = 0;
222 :
223 7 : Size aRectSize( aRect.Width, aRect.Height );
224 7 : if (aRectSize.Width() <= 0)
225 1 : aRectSize.Width() = 5000; // Default-Groesse
226 :
227 7 : if (aRectSize.Height() <= 0)
228 1 : aRectSize.Height() = 5000;
229 7 : Rectangle aInsRect( aRectPos, aRectSize );
230 :
231 7 : sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
232 7 : MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ));
233 7 : Size aSize(aInsRect.GetSize());
234 7 : aSize = vcl::Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
235 7 : awt::Size aSz;
236 7 : aSz.Width = aSize.Width();
237 7 : aSz.Height = aSize.Height();
238 :
239 : // Calc -> DataProvider
240 : uno::Reference< chart2::data::XDataProvider > xDataProvider = new
241 7 : ScChart2DataProvider( &rDoc );
242 : // Chart -> DataReceiver
243 14 : uno::Reference< chart2::data::XDataReceiver > xReceiver;
244 14 : uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
245 7 : if( xCompSupp.is())
246 7 : xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
247 7 : if( xReceiver.is())
248 : {
249 7 : OUString sRangeStr;
250 7 : xNewRanges->Format(sRangeStr, SCR_ABS_3D, &rDoc);
251 :
252 : // connect
253 7 : if( !sRangeStr.isEmpty() )
254 7 : xReceiver->attachDataProvider( xDataProvider );
255 : else
256 0 : sRangeStr = "all";
257 :
258 14 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
259 7 : xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
260 :
261 : // set arguments
262 14 : uno::Sequence< beans::PropertyValue > aArgs( 4 );
263 14 : aArgs[0] = beans::PropertyValue(
264 : OUString("CellRangeRepresentation"), -1,
265 7 : uno::makeAny( OUString( sRangeStr )), beans::PropertyState_DIRECT_VALUE );
266 14 : aArgs[1] = beans::PropertyValue(
267 : OUString("HasCategories"), -1,
268 7 : uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE );
269 14 : aArgs[2] = beans::PropertyValue(
270 : OUString("FirstCellAsLabel"), -1,
271 7 : uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE );
272 14 : aArgs[3] = beans::PropertyValue(
273 : OUString("DataRowSource"), -1,
274 7 : uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE );
275 14 : xReceiver->setArguments( aArgs );
276 : }
277 :
278 : ScChartListener* pChartListener =
279 7 : new ScChartListener( aName, &rDoc, xNewRanges );
280 7 : rDoc.GetChartListenerCollection()->insert( pChartListener );
281 7 : pChartListener->StartListeningTo();
282 :
283 7 : SdrOle2Obj* pObj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aName, aInsRect );
284 :
285 : // set VisArea
286 7 : if( xObj.is())
287 7 : xObj->setVisualAreaSize( nAspect, aSz );
288 :
289 : // #i121334# This call will change the chart's default background fill from white to transparent.
290 : // Add here again if this is wanted (see task description for details)
291 : // ChartHelper::AdaptDefaultsForChart( xObj );
292 :
293 7 : pPage->InsertObject( pObj );
294 14 : pModel->AddUndo( new SdrUndoInsertObj( *pObj ) );
295 7 : }
296 : }
297 :
298 1 : void SAL_CALL ScChartsObj::removeByName( const OUString& aName )
299 : throw(uno::RuntimeException, std::exception)
300 : {
301 1 : SolarMutexGuard aGuard;
302 1 : SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aName );
303 1 : if (pObj)
304 : {
305 1 : ScDocument& rDoc = pDocShell->GetDocument();
306 1 : rDoc.GetChartListenerCollection()->removeByName(aName);
307 1 : ScDrawLayer* pModel = rDoc.GetDrawLayer(); // ist nicht 0
308 1 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0
309 :
310 1 : pModel->AddUndo( new SdrUndoDelObj( *pObj ) );
311 1 : pPage->RemoveObject( pObj->GetOrdNum() );
312 :
313 : //! Notify etc.???
314 1 : }
315 1 : }
316 :
317 : // XEnumerationAccess
318 :
319 2 : uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration()
320 : throw(uno::RuntimeException, std::exception)
321 : {
322 2 : SolarMutexGuard aGuard;
323 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.table.TableChartsEnumeration"));
324 : }
325 :
326 : // XIndexAccess
327 :
328 5 : sal_Int32 SAL_CALL ScChartsObj::getCount() throw(uno::RuntimeException, std::exception)
329 : {
330 5 : SolarMutexGuard aGuard;
331 5 : sal_Int32 nCount = 0;
332 5 : if ( pDocShell )
333 : {
334 5 : ScDocument& rDoc = pDocShell->GetDocument();
335 5 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
336 5 : if (pDrawLayer)
337 : {
338 5 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
339 : OSL_ENSURE(pPage, "Page nicht gefunden");
340 5 : if (pPage)
341 : {
342 5 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
343 5 : SdrObject* pObject = aIter.Next();
344 15 : while (pObject)
345 : {
346 5 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
347 5 : ++nCount;
348 5 : pObject = aIter.Next();
349 5 : }
350 : }
351 : }
352 : }
353 5 : return nCount;
354 : }
355 :
356 72 : uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex )
357 : throw(lang::IndexOutOfBoundsException,
358 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
359 : {
360 72 : SolarMutexGuard aGuard;
361 144 : uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex));
362 72 : if (xChart.is())
363 140 : return uno::makeAny(xChart);
364 : else
365 74 : throw lang::IndexOutOfBoundsException();
366 : }
367 :
368 1 : uno::Type SAL_CALL ScChartsObj::getElementType() throw(uno::RuntimeException, std::exception)
369 : {
370 1 : SolarMutexGuard aGuard;
371 1 : return cppu::UnoType<table::XTableChart>::get();
372 : }
373 :
374 1 : sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException, std::exception)
375 : {
376 1 : SolarMutexGuard aGuard;
377 1 : return getCount() != 0;
378 : }
379 :
380 5 : uno::Any SAL_CALL ScChartsObj::getByName( const OUString& aName )
381 : throw(container::NoSuchElementException,
382 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
383 : {
384 5 : SolarMutexGuard aGuard;
385 10 : uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName));
386 5 : if (xChart.is())
387 8 : return uno::makeAny(xChart);
388 : else
389 6 : throw container::NoSuchElementException();
390 : }
391 :
392 1 : uno::Sequence<OUString> SAL_CALL ScChartsObj::getElementNames() throw(uno::RuntimeException, std::exception)
393 : {
394 1 : SolarMutexGuard aGuard;
395 1 : if (pDocShell)
396 : {
397 1 : ScDocument& rDoc = pDocShell->GetDocument();
398 :
399 1 : long nCount = getCount();
400 1 : uno::Sequence<OUString> aSeq(nCount);
401 1 : OUString* pAry = aSeq.getArray();
402 :
403 1 : long nPos = 0;
404 1 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
405 1 : if (pDrawLayer)
406 : {
407 1 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
408 : OSL_ENSURE(pPage, "Page nicht gefunden");
409 1 : if (pPage)
410 : {
411 1 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
412 1 : SdrObject* pObject = aIter.Next();
413 3 : while (pObject)
414 : {
415 1 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ScDocument::IsChart(pObject) )
416 : {
417 1 : OUString aName;
418 2 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
419 1 : if ( xObj.is() )
420 1 : aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
421 :
422 : OSL_ENSURE(nPos<nCount, "huch, verzaehlt?");
423 2 : pAry[nPos++] = aName;
424 : }
425 1 : pObject = aIter.Next();
426 1 : }
427 : }
428 : }
429 : OSL_ENSURE(nPos==nCount, "nanu, verzaehlt?");
430 :
431 1 : return aSeq;
432 : }
433 0 : return uno::Sequence<OUString>(0);
434 : }
435 :
436 7 : sal_Bool SAL_CALL ScChartsObj::hasByName( const OUString& aName )
437 : throw(uno::RuntimeException, std::exception)
438 : {
439 7 : SolarMutexGuard aGuard;
440 7 : return ( lcl_FindChartObj( pDocShell, nTab, aName ) != NULL );
441 : }
442 :
443 74 : ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN)
444 : :ScChartObj_Base( m_aMutex )
445 : ,ScChartObj_PBase( ScChartObj_Base::rBHelper )
446 : ,pDocShell( pDocSh )
447 : ,nTab( nT )
448 74 : ,aChartName( rN )
449 : {
450 74 : pDocShell->GetDocument().AddUnoObject(*this);
451 :
452 74 : uno::Sequence< table::CellRangeAddress > aInitialPropValue;
453 : registerPropertyNoMember( OUString( "RelatedCellRanges" ),
454 : PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID,
455 74 : cppu::UnoType<decltype(aInitialPropValue)>::get(), &aInitialPropValue );
456 74 : }
457 :
458 222 : ScChartObj::~ScChartObj()
459 : {
460 74 : SolarMutexGuard g;
461 :
462 74 : if (pDocShell)
463 66 : pDocShell->GetDocument().RemoveUnoObject(*this);
464 148 : }
465 :
466 8 : void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
467 : {
468 : //! Referenz-Update
469 :
470 8 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
471 8 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
472 : {
473 8 : pDocShell = NULL; // ungueltig geworden
474 : }
475 8 : }
476 :
477 13 : void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const
478 : {
479 13 : bool bFound = false;
480 :
481 13 : if( pDocShell )
482 : {
483 13 : ScDocument& rDoc = pDocShell->GetDocument();
484 13 : uno::Reference< chart2::XChartDocument > xChartDoc( rDoc.GetChartByName( aChartName ) );
485 13 : if( xChartDoc.is() )
486 : {
487 13 : uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
488 26 : uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
489 13 : if( xReceiver.is() && xProvider.is() )
490 : {
491 13 : uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) );
492 :
493 26 : OUString aRanges;
494 13 : chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
495 13 : bool bHasCategories=false;
496 13 : bool bFirstCellAsLabel=false;
497 13 : const beans::PropertyValue* pPropArray = aArgs.getConstArray();
498 13 : long nPropCount = aArgs.getLength();
499 78 : for (long i = 0; i < nPropCount; i++)
500 : {
501 65 : const beans::PropertyValue& rProp = pPropArray[i];
502 65 : OUString aPropName(rProp.Name);
503 :
504 65 : if (aPropName == "CellRangeRepresentation")
505 13 : rProp.Value >>= aRanges;
506 52 : else if (aPropName == "DataRowSource")
507 13 : eDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
508 39 : else if (aPropName == "HasCategories")
509 13 : bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
510 26 : else if (aPropName == "FirstCellAsLabel")
511 13 : bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
512 65 : }
513 :
514 13 : if( chart::ChartDataRowSource_COLUMNS == eDataRowSource )
515 : {
516 13 : rColHeaders=bFirstCellAsLabel;
517 13 : rRowHeaders=bHasCategories;
518 : }
519 : else
520 : {
521 0 : rColHeaders=bHasCategories;
522 0 : rRowHeaders=bFirstCellAsLabel;
523 : }
524 26 : rRanges->Parse( aRanges, &rDoc);
525 : }
526 26 : bFound = true;
527 13 : }
528 : }
529 13 : if( !bFound )
530 : {
531 0 : rRanges = 0;
532 0 : rColHeaders = false;
533 0 : rRowHeaders = false;
534 : }
535 13 : }
536 :
537 6 : void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders )
538 : {
539 6 : if (pDocShell)
540 : {
541 6 : ScDocument& rDoc = pDocShell->GetDocument();
542 6 : bool bUndo(rDoc.IsUndoEnabled());
543 :
544 6 : if (bUndo)
545 : {
546 6 : pDocShell->GetUndoManager()->AddUndoAction(
547 6 : new ScUndoChartData( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, false ) );
548 : }
549 6 : rDoc.UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, false );
550 : }
551 6 : }
552 :
553 : // ::comphelper::OPropertySetHelper
554 :
555 0 : ::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper()
556 : {
557 0 : return *ScChartObj_PABase::getArrayHelper();
558 : }
559 :
560 0 : void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue )
561 : throw (uno::Exception, std::exception)
562 : {
563 0 : switch ( nHandle )
564 : {
565 : case PROP_HANDLE_RELATED_CELLRANGES:
566 : {
567 0 : uno::Sequence< table::CellRangeAddress > aCellRanges;
568 0 : if ( rValue >>= aCellRanges )
569 : {
570 0 : ScRangeListRef rRangeList = new ScRangeList();
571 0 : const table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
572 0 : sal_Int32 nCount = aCellRanges.getLength();
573 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
574 : {
575 0 : table::CellRangeAddress aCellRange = pCellRanges[ i ];
576 0 : ScRange aRange;
577 0 : ScUnoConversion::FillScRange( aRange, aCellRange );
578 0 : rRangeList->Append( aRange );
579 : }
580 0 : if ( pDocShell )
581 : {
582 0 : ScChartListenerCollection* pCollection = pDocShell->GetDocument().GetChartListenerCollection();
583 0 : if ( pCollection )
584 : {
585 0 : pCollection->ChangeListening( aChartName, rRangeList );
586 : }
587 0 : }
588 0 : }
589 : }
590 0 : break;
591 : default:
592 0 : break;
593 : }
594 0 : }
595 :
596 0 : void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const
597 : {
598 0 : switch ( nHandle )
599 : {
600 : case PROP_HANDLE_RELATED_CELLRANGES:
601 : {
602 0 : if (!pDocShell)
603 0 : break;
604 0 : ScDocument& rDoc = pDocShell->GetDocument();
605 :
606 0 : ScChartListenerCollection* pCollection = rDoc.GetChartListenerCollection();
607 0 : if (!pCollection)
608 0 : break;
609 :
610 0 : ScChartListener* pListener = pCollection->findByName(aChartName);
611 0 : if (!pListener)
612 0 : break;
613 :
614 0 : const ScRangeListRef& rRangeList = pListener->GetRangeList();
615 0 : if (!rRangeList.Is())
616 0 : break;
617 :
618 0 : size_t nCount = rRangeList->size();
619 0 : uno::Sequence<table::CellRangeAddress> aCellRanges(nCount);
620 0 : table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
621 0 : for (size_t i = 0; i < nCount; ++i)
622 : {
623 0 : ScRange aRange(*(*rRangeList)[i]);
624 0 : table::CellRangeAddress aCellRange;
625 0 : ScUnoConversion::FillApiRange(aCellRange, aRange);
626 0 : pCellRanges[i] = aCellRange;
627 : }
628 0 : rValue <<= aCellRanges;
629 : }
630 0 : break;
631 : default:
632 : ;
633 : }
634 0 : }
635 :
636 : // ::comphelper::OPropertyArrayUsageHelper
637 :
638 0 : ::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const
639 : {
640 0 : uno::Sequence< beans::Property > aProps;
641 0 : describeProperties( aProps );
642 0 : return new ::cppu::OPropertyArrayHelper( aProps );
643 : }
644 :
645 : // XInterface
646 :
647 1086 : IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )
648 :
649 : // XTypeProvider
650 :
651 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase )
652 :
653 : // XComponent
654 :
655 74 : void ScChartObj::disposing()
656 : {
657 74 : ScChartObj_Base::disposing();
658 74 : }
659 :
660 : // XTableChart
661 :
662 2 : sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException, std::exception)
663 : {
664 2 : SolarMutexGuard aGuard;
665 4 : ScRangeListRef xRanges = new ScRangeList;
666 : bool bColHeaders, bRowHeaders;
667 2 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
668 4 : return bColHeaders;
669 : }
670 :
671 2 : void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders )
672 : throw(uno::RuntimeException,
673 : std::exception)
674 : {
675 2 : SolarMutexGuard aGuard;
676 4 : ScRangeListRef xRanges = new ScRangeList;
677 : bool bOldColHeaders, bOldRowHeaders;
678 2 : GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
679 2 : if ( bOldColHeaders != bool(bHasColumnHeaders) )
680 4 : Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders );
681 2 : }
682 :
683 2 : sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() throw(uno::RuntimeException, std::exception)
684 : {
685 2 : SolarMutexGuard aGuard;
686 4 : ScRangeListRef xRanges = new ScRangeList;
687 : bool bColHeaders, bRowHeaders;
688 2 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
689 4 : return bRowHeaders;
690 : }
691 :
692 2 : void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders )
693 : throw(uno::RuntimeException, std::exception)
694 : {
695 2 : SolarMutexGuard aGuard;
696 4 : ScRangeListRef xRanges = new ScRangeList;
697 : bool bOldColHeaders, bOldRowHeaders;
698 2 : GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
699 2 : if ( bOldRowHeaders != bool(bHasRowHeaders) )
700 4 : Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders );
701 2 : }
702 :
703 3 : uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() throw(uno::RuntimeException, std::exception)
704 : {
705 3 : SolarMutexGuard aGuard;
706 6 : ScRangeListRef xRanges = new ScRangeList;
707 : bool bColHeaders, bRowHeaders;
708 3 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
709 3 : if ( xRanges.Is() )
710 : {
711 3 : size_t nCount = xRanges->size();
712 :
713 3 : table::CellRangeAddress aRangeAddress;
714 3 : uno::Sequence<table::CellRangeAddress> aSeq(nCount);
715 3 : table::CellRangeAddress* pAry = aSeq.getArray();
716 6 : for (size_t i = 0; i < nCount; i++)
717 : {
718 3 : ScRange aRange( *(*xRanges)[i] );
719 :
720 3 : aRangeAddress.Sheet = aRange.aStart.Tab();
721 3 : aRangeAddress.StartColumn = aRange.aStart.Col();
722 3 : aRangeAddress.StartRow = aRange.aStart.Row();
723 3 : aRangeAddress.EndColumn = aRange.aEnd.Col();
724 3 : aRangeAddress.EndRow = aRange.aEnd.Row();
725 :
726 3 : pAry[i] = aRangeAddress;
727 : }
728 3 : return aSeq;
729 : }
730 :
731 : OSL_FAIL("ScChartObj::getRanges: keine Ranges");
732 3 : return uno::Sequence<table::CellRangeAddress>();
733 : }
734 :
735 2 : void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges )
736 : throw(uno::RuntimeException, std::exception)
737 : {
738 2 : SolarMutexGuard aGuard;
739 4 : ScRangeListRef xOldRanges = new ScRangeList;
740 : bool bColHeaders, bRowHeaders;
741 2 : GetData_Impl( xOldRanges, bColHeaders, bRowHeaders );
742 :
743 2 : ScRangeList* pList = new ScRangeList;
744 2 : sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
745 2 : if (nRangeCount)
746 : {
747 2 : const table::CellRangeAddress* pAry = aRanges.getConstArray();
748 4 : for (sal_uInt16 i=0; i<nRangeCount; i++)
749 : {
750 6 : ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
751 8 : static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
752 2 : pList->Append( aRange );
753 : }
754 : }
755 4 : ScRangeListRef xNewRanges( pList );
756 :
757 2 : if ( !xOldRanges.Is() || *xOldRanges != *xNewRanges )
758 4 : Update_Impl( xNewRanges, bColHeaders, bRowHeaders );
759 2 : }
760 :
761 : // XEmbeddedObjectSupplier
762 :
763 69 : uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() throw(uno::RuntimeException, std::exception)
764 : {
765 69 : SolarMutexGuard aGuard;
766 69 : SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName );
767 69 : if ( pObject && svt::EmbeddedObjectRef::TryRunningState( pObject->GetObjRef() ) )
768 : {
769 : //TODO/LATER: is it OK that something is returned for *all* objects, not only own objects?
770 69 : return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY );
771 : }
772 :
773 0 : return NULL;
774 : }
775 :
776 : // XNamed
777 :
778 2 : OUString SAL_CALL ScChartObj::getName() throw(uno::RuntimeException, std::exception)
779 : {
780 2 : SolarMutexGuard aGuard;
781 2 : return aChartName;
782 : }
783 :
784 0 : void SAL_CALL ScChartObj::setName( const OUString& /* aName */ ) throw(uno::RuntimeException, std::exception)
785 : {
786 0 : SolarMutexGuard aGuard;
787 0 : throw uno::RuntimeException(); // name cannot be changed
788 : }
789 :
790 : // XPropertySet
791 :
792 0 : uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
793 : {
794 0 : return createPropertySetInfo( getInfoHelper() ) ;
795 156 : }
796 :
797 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|