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 124 : static SdrOle2Obj* lcl_FindChartObj( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
57 : {
58 124 : if (pDocShell)
59 : {
60 124 : ScDocument& rDoc = pDocShell->GetDocument();
61 124 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
62 124 : if (pDrawLayer)
63 : {
64 124 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
65 : OSL_ENSURE(pPage, "Page nicht gefunden");
66 124 : if (pPage)
67 : {
68 124 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
69 124 : SdrObject* pObject = aIter.Next();
70 258 : while (pObject)
71 : {
72 124 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && rDoc.IsChart(pObject) )
73 : {
74 124 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
75 124 : if ( xObj.is() )
76 : {
77 124 : OUString aObjName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
78 124 : if ( aObjName == rName )
79 114 : return static_cast<SdrOle2Obj*>(pObject);
80 10 : }
81 : }
82 10 : pObject = aIter.Next();
83 10 : }
84 : }
85 : }
86 : }
87 10 : return NULL;
88 : }
89 :
90 104 : ScChartsObj::ScChartsObj(ScDocShell* pDocSh, SCTAB nT) :
91 : pDocShell( pDocSh ),
92 104 : nTab( nT )
93 : {
94 104 : pDocShell->GetDocument().AddUnoObject(*this);
95 104 : }
96 :
97 312 : ScChartsObj::~ScChartsObj()
98 : {
99 104 : SolarMutexGuard g;
100 :
101 104 : if (pDocShell)
102 92 : pDocShell->GetDocument().RemoveUnoObject(*this);
103 208 : }
104 :
105 12 : void ScChartsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
106 : {
107 : //! Referenz-Update
108 :
109 12 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
110 12 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
111 : {
112 12 : pDocShell = NULL; // ungueltig geworden
113 : }
114 12 : }
115 :
116 104 : ScChartObj* ScChartsObj::GetObjectByIndex_Impl(long nIndex) const
117 : {
118 104 : OUString aName;
119 104 : if ( pDocShell )
120 : {
121 104 : ScDocument& rDoc = pDocShell->GetDocument();
122 104 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
123 104 : if (pDrawLayer)
124 : {
125 104 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
126 : OSL_ENSURE(pPage, "Page nicht gefunden");
127 104 : if (pPage)
128 : {
129 104 : long nPos = 0;
130 104 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
131 104 : SdrObject* pObject = aIter.Next();
132 212 : while (pObject)
133 : {
134 104 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && rDoc.IsChart(pObject) )
135 : {
136 104 : if ( nPos == nIndex )
137 : {
138 100 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
139 100 : if ( xObj.is() )
140 100 : aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
141 100 : break; // nicht weitersuchen
142 : }
143 4 : ++nPos;
144 : }
145 4 : pObject = aIter.Next();
146 104 : }
147 : }
148 : }
149 : }
150 :
151 104 : if (!aName.isEmpty())
152 100 : return new ScChartObj( pDocShell, nTab, aName );
153 4 : return NULL;
154 : }
155 :
156 10 : ScChartObj* ScChartsObj::GetObjectByName_Impl(const OUString& aName) const
157 : {
158 10 : if ( lcl_FindChartObj( pDocShell, nTab, aName ) )
159 8 : return new ScChartObj( pDocShell, nTab, aName );
160 2 : return NULL;
161 : }
162 :
163 : // XTableCharts
164 :
165 14 : 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 14 : SolarMutexGuard aGuard;
173 14 : if (!pDocShell)
174 0 : return;
175 :
176 14 : ScDocument& rDoc = pDocShell->GetDocument();
177 14 : ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
178 14 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
179 : OSL_ENSURE(pPage,"addChart: keine Page");
180 14 : 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 28 : OUString aName = rName;
187 : SCTAB nDummy;
188 14 : 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 14 : ScRangeList* pList = new ScRangeList;
195 14 : sal_Int32 nRangeCount = aRanges.getLength();
196 14 : if (nRangeCount)
197 : {
198 14 : const table::CellRangeAddress* pAry = aRanges.getConstArray();
199 28 : for (sal_Int32 i=0; i<nRangeCount; i++)
200 : {
201 42 : ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
202 56 : static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
203 14 : pList->Append( aRange );
204 : }
205 : }
206 28 : ScRangeListRef xNewRanges( pList );
207 :
208 28 : uno::Reference < embed::XEmbeddedObject > xObj;
209 14 : if ( SvtModuleOptions().IsChart() )
210 14 : xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aName );
211 14 : if ( xObj.is() )
212 : {
213 : // Rechteck anpassen
214 : //! Fehler/Exception, wenn leer/ungueltig ???
215 14 : Point aRectPos( aRect.X, aRect.Y );
216 14 : bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
217 14 : if ( ( aRectPos.X() < 0 && !bLayoutRTL ) || ( aRectPos.X() > 0 && bLayoutRTL ) )
218 0 : aRectPos.X() = 0;
219 :
220 14 : if (aRectPos.Y() < 0)
221 0 : aRectPos.Y() = 0;
222 :
223 14 : Size aRectSize( aRect.Width, aRect.Height );
224 14 : if (aRectSize.Width() <= 0)
225 2 : aRectSize.Width() = 5000; // Default-Groesse
226 :
227 14 : if (aRectSize.Height() <= 0)
228 2 : aRectSize.Height() = 5000;
229 14 : Rectangle aInsRect( aRectPos, aRectSize );
230 :
231 14 : sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
232 14 : MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ));
233 14 : Size aSize(aInsRect.GetSize());
234 14 : aSize = vcl::Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
235 14 : awt::Size aSz;
236 14 : aSz.Width = aSize.Width();
237 14 : aSz.Height = aSize.Height();
238 :
239 : // Calc -> DataProvider
240 : uno::Reference< chart2::data::XDataProvider > xDataProvider = new
241 14 : ScChart2DataProvider( &rDoc );
242 : // Chart -> DataReceiver
243 28 : uno::Reference< chart2::data::XDataReceiver > xReceiver;
244 28 : uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
245 14 : if( xCompSupp.is())
246 14 : xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
247 14 : if( xReceiver.is())
248 : {
249 14 : OUString sRangeStr;
250 14 : xNewRanges->Format(sRangeStr, SCR_ABS_3D, &rDoc);
251 :
252 : // connect
253 14 : if( !sRangeStr.isEmpty() )
254 14 : xReceiver->attachDataProvider( xDataProvider );
255 : else
256 0 : sRangeStr = "all";
257 :
258 28 : uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
259 14 : xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
260 :
261 : // set arguments
262 28 : uno::Sequence< beans::PropertyValue > aArgs( 4 );
263 28 : aArgs[0] = beans::PropertyValue(
264 : OUString("CellRangeRepresentation"), -1,
265 14 : uno::makeAny( OUString( sRangeStr )), beans::PropertyState_DIRECT_VALUE );
266 28 : aArgs[1] = beans::PropertyValue(
267 : OUString("HasCategories"), -1,
268 14 : uno::makeAny( bRowHeaders ), beans::PropertyState_DIRECT_VALUE );
269 28 : aArgs[2] = beans::PropertyValue(
270 : OUString("FirstCellAsLabel"), -1,
271 14 : uno::makeAny( bColumnHeaders ), beans::PropertyState_DIRECT_VALUE );
272 28 : aArgs[3] = beans::PropertyValue(
273 : OUString("DataRowSource"), -1,
274 14 : uno::makeAny( chart::ChartDataRowSource_COLUMNS ), beans::PropertyState_DIRECT_VALUE );
275 28 : xReceiver->setArguments( aArgs );
276 : }
277 :
278 : ScChartListener* pChartListener =
279 14 : new ScChartListener( aName, &rDoc, xNewRanges );
280 14 : rDoc.GetChartListenerCollection()->insert( pChartListener );
281 14 : pChartListener->StartListeningTo();
282 :
283 14 : SdrOle2Obj* pObj = new SdrOle2Obj( ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), aName, aInsRect );
284 :
285 : // set VisArea
286 14 : if( xObj.is())
287 14 : 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 14 : pPage->InsertObject( pObj );
294 28 : pModel->AddUndo( new SdrUndoInsertObj( *pObj ) );
295 14 : }
296 : }
297 :
298 2 : void SAL_CALL ScChartsObj::removeByName( const OUString& aName )
299 : throw(uno::RuntimeException, std::exception)
300 : {
301 2 : SolarMutexGuard aGuard;
302 2 : SdrOle2Obj* pObj = lcl_FindChartObj( pDocShell, nTab, aName );
303 2 : if (pObj)
304 : {
305 2 : ScDocument& rDoc = pDocShell->GetDocument();
306 2 : rDoc.GetChartListenerCollection()->removeByName(aName);
307 2 : ScDrawLayer* pModel = rDoc.GetDrawLayer(); // ist nicht 0
308 2 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab)); // ist nicht 0
309 :
310 2 : pModel->AddUndo( new SdrUndoDelObj( *pObj ) );
311 2 : pPage->RemoveObject( pObj->GetOrdNum() );
312 :
313 : //! Notify etc.???
314 2 : }
315 2 : }
316 :
317 : // XEnumerationAccess
318 :
319 4 : uno::Reference<container::XEnumeration> SAL_CALL ScChartsObj::createEnumeration()
320 : throw(uno::RuntimeException, std::exception)
321 : {
322 4 : SolarMutexGuard aGuard;
323 4 : return new ScIndexEnumeration(this, OUString("com.sun.star.table.TableChartsEnumeration"));
324 : }
325 :
326 : // XIndexAccess
327 :
328 10 : sal_Int32 SAL_CALL ScChartsObj::getCount() throw(uno::RuntimeException, std::exception)
329 : {
330 10 : SolarMutexGuard aGuard;
331 10 : sal_Int32 nCount = 0;
332 10 : if ( pDocShell )
333 : {
334 10 : ScDocument& rDoc = pDocShell->GetDocument();
335 10 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
336 10 : if (pDrawLayer)
337 : {
338 10 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
339 : OSL_ENSURE(pPage, "Page nicht gefunden");
340 10 : if (pPage)
341 : {
342 10 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
343 10 : SdrObject* pObject = aIter.Next();
344 30 : while (pObject)
345 : {
346 10 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && rDoc.IsChart(pObject) )
347 10 : ++nCount;
348 10 : pObject = aIter.Next();
349 10 : }
350 : }
351 : }
352 : }
353 10 : return nCount;
354 : }
355 :
356 104 : uno::Any SAL_CALL ScChartsObj::getByIndex( sal_Int32 nIndex )
357 : throw(lang::IndexOutOfBoundsException,
358 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
359 : {
360 104 : SolarMutexGuard aGuard;
361 208 : uno::Reference<table::XTableChart> xChart(GetObjectByIndex_Impl(nIndex));
362 104 : if (xChart.is())
363 200 : return uno::makeAny(xChart);
364 : else
365 108 : throw lang::IndexOutOfBoundsException();
366 : }
367 :
368 2 : uno::Type SAL_CALL ScChartsObj::getElementType() throw(uno::RuntimeException, std::exception)
369 : {
370 2 : SolarMutexGuard aGuard;
371 2 : return cppu::UnoType<table::XTableChart>::get();
372 : }
373 :
374 2 : sal_Bool SAL_CALL ScChartsObj::hasElements() throw(uno::RuntimeException, std::exception)
375 : {
376 2 : SolarMutexGuard aGuard;
377 2 : return getCount() != 0;
378 : }
379 :
380 10 : uno::Any SAL_CALL ScChartsObj::getByName( const OUString& aName )
381 : throw(container::NoSuchElementException,
382 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
383 : {
384 10 : SolarMutexGuard aGuard;
385 20 : uno::Reference<table::XTableChart> xChart(GetObjectByName_Impl(aName));
386 10 : if (xChart.is())
387 16 : return uno::makeAny(xChart);
388 : else
389 12 : throw container::NoSuchElementException();
390 : }
391 :
392 2 : uno::Sequence<OUString> SAL_CALL ScChartsObj::getElementNames() throw(uno::RuntimeException, std::exception)
393 : {
394 2 : SolarMutexGuard aGuard;
395 2 : if (pDocShell)
396 : {
397 2 : ScDocument& rDoc = pDocShell->GetDocument();
398 :
399 2 : long nCount = getCount();
400 2 : uno::Sequence<OUString> aSeq(nCount);
401 2 : OUString* pAry = aSeq.getArray();
402 :
403 2 : long nPos = 0;
404 2 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
405 2 : if (pDrawLayer)
406 : {
407 2 : SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
408 : OSL_ENSURE(pPage, "Page nicht gefunden");
409 2 : if (pPage)
410 : {
411 2 : SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
412 2 : SdrObject* pObject = aIter.Next();
413 6 : while (pObject)
414 : {
415 2 : if ( pObject->GetObjIdentifier() == OBJ_OLE2 && rDoc.IsChart(pObject) )
416 : {
417 2 : OUString aName;
418 4 : uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObject)->GetObjRef();
419 2 : if ( xObj.is() )
420 2 : aName = pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xObj );
421 :
422 : OSL_ENSURE(nPos<nCount, "huch, verzaehlt?");
423 4 : pAry[nPos++] = aName;
424 : }
425 2 : pObject = aIter.Next();
426 2 : }
427 : }
428 : }
429 : OSL_ENSURE(nPos==nCount, "nanu, verzaehlt?");
430 :
431 2 : return aSeq;
432 : }
433 0 : return uno::Sequence<OUString>(0);
434 : }
435 :
436 14 : sal_Bool SAL_CALL ScChartsObj::hasByName( const OUString& aName )
437 : throw(uno::RuntimeException, std::exception)
438 : {
439 14 : SolarMutexGuard aGuard;
440 14 : return ( lcl_FindChartObj( pDocShell, nTab, aName ) != NULL );
441 : }
442 :
443 108 : 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 108 : ,aChartName( rN )
449 : {
450 108 : pDocShell->GetDocument().AddUnoObject(*this);
451 :
452 108 : uno::Sequence< table::CellRangeAddress > aInitialPropValue;
453 : registerPropertyNoMember( OUString( "RelatedCellRanges" ),
454 : PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID,
455 108 : ::getCppuType( &aInitialPropValue ), &aInitialPropValue );
456 108 : }
457 :
458 324 : ScChartObj::~ScChartObj()
459 : {
460 108 : SolarMutexGuard g;
461 :
462 108 : if (pDocShell)
463 92 : pDocShell->GetDocument().RemoveUnoObject(*this);
464 216 : }
465 :
466 16 : void ScChartObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
467 : {
468 : //! Referenz-Update
469 :
470 16 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
471 16 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
472 : {
473 16 : pDocShell = NULL; // ungueltig geworden
474 : }
475 16 : }
476 :
477 26 : void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const
478 : {
479 26 : bool bFound = false;
480 :
481 26 : if( pDocShell )
482 : {
483 26 : ScDocument& rDoc = pDocShell->GetDocument();
484 26 : uno::Reference< chart2::XChartDocument > xChartDoc( rDoc.GetChartByName( aChartName ) );
485 26 : if( xChartDoc.is() )
486 : {
487 26 : uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY );
488 52 : uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider();
489 26 : if( xReceiver.is() && xProvider.is() )
490 : {
491 26 : uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) );
492 :
493 52 : OUString aRanges;
494 26 : chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
495 26 : bool bHasCategories=false;
496 26 : bool bFirstCellAsLabel=false;
497 26 : const beans::PropertyValue* pPropArray = aArgs.getConstArray();
498 26 : long nPropCount = aArgs.getLength();
499 156 : for (long i = 0; i < nPropCount; i++)
500 : {
501 130 : const beans::PropertyValue& rProp = pPropArray[i];
502 130 : OUString aPropName(rProp.Name);
503 :
504 130 : if (aPropName.equalsAscii( "CellRangeRepresentation" ))
505 26 : rProp.Value >>= aRanges;
506 104 : else if (aPropName.equalsAscii( "DataRowSource" ))
507 26 : eDataRowSource = (chart::ChartDataRowSource)ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
508 78 : else if (aPropName.equalsAscii( "HasCategories" ))
509 26 : bHasCategories = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
510 52 : else if (aPropName.equalsAscii( "FirstCellAsLabel" ))
511 26 : bFirstCellAsLabel = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
512 130 : }
513 :
514 26 : if( chart::ChartDataRowSource_COLUMNS == eDataRowSource )
515 : {
516 26 : rColHeaders=bFirstCellAsLabel;
517 26 : rRowHeaders=bHasCategories;
518 : }
519 : else
520 : {
521 0 : rColHeaders=bHasCategories;
522 0 : rRowHeaders=bFirstCellAsLabel;
523 : }
524 52 : rRanges->Parse( aRanges, &rDoc);
525 : }
526 52 : bFound = true;
527 26 : }
528 : }
529 26 : if( !bFound )
530 : {
531 0 : rRanges = 0;
532 0 : rColHeaders = false;
533 0 : rRowHeaders = false;
534 : }
535 26 : }
536 :
537 12 : void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders )
538 : {
539 12 : if (pDocShell)
540 : {
541 12 : ScDocument& rDoc = pDocShell->GetDocument();
542 12 : bool bUndo(rDoc.IsUndoEnabled());
543 :
544 12 : if (bUndo)
545 : {
546 12 : pDocShell->GetUndoManager()->AddUndoAction(
547 12 : new ScUndoChartData( pDocShell, aChartName, rRanges, bColHeaders, bRowHeaders, false ) );
548 : }
549 12 : rDoc.UpdateChartArea( aChartName, rRanges, bColHeaders, bRowHeaders, false );
550 : }
551 12 : }
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 1612 : 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 108 : void ScChartObj::disposing()
656 : {
657 108 : ScChartObj_Base::disposing();
658 108 : }
659 :
660 : // XTableChart
661 :
662 4 : sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException, std::exception)
663 : {
664 4 : SolarMutexGuard aGuard;
665 8 : ScRangeListRef xRanges = new ScRangeList;
666 : bool bColHeaders, bRowHeaders;
667 4 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
668 8 : return bColHeaders;
669 : }
670 :
671 4 : void SAL_CALL ScChartObj::setHasColumnHeaders( sal_Bool bHasColumnHeaders )
672 : throw(uno::RuntimeException,
673 : std::exception)
674 : {
675 4 : SolarMutexGuard aGuard;
676 8 : ScRangeListRef xRanges = new ScRangeList;
677 : bool bOldColHeaders, bOldRowHeaders;
678 4 : GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
679 4 : if ( bOldColHeaders != bool(bHasColumnHeaders) )
680 8 : Update_Impl( xRanges, bHasColumnHeaders, bOldRowHeaders );
681 4 : }
682 :
683 4 : sal_Bool SAL_CALL ScChartObj::getHasRowHeaders() throw(uno::RuntimeException, std::exception)
684 : {
685 4 : SolarMutexGuard aGuard;
686 8 : ScRangeListRef xRanges = new ScRangeList;
687 : bool bColHeaders, bRowHeaders;
688 4 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
689 8 : return bRowHeaders;
690 : }
691 :
692 4 : void SAL_CALL ScChartObj::setHasRowHeaders( sal_Bool bHasRowHeaders )
693 : throw(uno::RuntimeException, std::exception)
694 : {
695 4 : SolarMutexGuard aGuard;
696 8 : ScRangeListRef xRanges = new ScRangeList;
697 : bool bOldColHeaders, bOldRowHeaders;
698 4 : GetData_Impl( xRanges, bOldColHeaders, bOldRowHeaders );
699 4 : if ( bOldRowHeaders != bool(bHasRowHeaders) )
700 8 : Update_Impl( xRanges, bOldColHeaders, bHasRowHeaders );
701 4 : }
702 :
703 6 : uno::Sequence<table::CellRangeAddress> SAL_CALL ScChartObj::getRanges() throw(uno::RuntimeException, std::exception)
704 : {
705 6 : SolarMutexGuard aGuard;
706 12 : ScRangeListRef xRanges = new ScRangeList;
707 : bool bColHeaders, bRowHeaders;
708 6 : GetData_Impl( xRanges, bColHeaders, bRowHeaders );
709 6 : if ( xRanges.Is() )
710 : {
711 6 : size_t nCount = xRanges->size();
712 :
713 6 : table::CellRangeAddress aRangeAddress;
714 6 : uno::Sequence<table::CellRangeAddress> aSeq(nCount);
715 6 : table::CellRangeAddress* pAry = aSeq.getArray();
716 12 : for (size_t i = 0; i < nCount; i++)
717 : {
718 6 : ScRange aRange( *(*xRanges)[i] );
719 :
720 6 : aRangeAddress.Sheet = aRange.aStart.Tab();
721 6 : aRangeAddress.StartColumn = aRange.aStart.Col();
722 6 : aRangeAddress.StartRow = aRange.aStart.Row();
723 6 : aRangeAddress.EndColumn = aRange.aEnd.Col();
724 6 : aRangeAddress.EndRow = aRange.aEnd.Row();
725 :
726 6 : pAry[i] = aRangeAddress;
727 : }
728 6 : return aSeq;
729 : }
730 :
731 : OSL_FAIL("ScChartObj::getRanges: keine Ranges");
732 6 : return uno::Sequence<table::CellRangeAddress>();
733 : }
734 :
735 4 : void SAL_CALL ScChartObj::setRanges( const uno::Sequence<table::CellRangeAddress>& aRanges )
736 : throw(uno::RuntimeException, std::exception)
737 : {
738 4 : SolarMutexGuard aGuard;
739 8 : ScRangeListRef xOldRanges = new ScRangeList;
740 : bool bColHeaders, bRowHeaders;
741 4 : GetData_Impl( xOldRanges, bColHeaders, bRowHeaders );
742 :
743 4 : ScRangeList* pList = new ScRangeList;
744 4 : sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
745 4 : if (nRangeCount)
746 : {
747 4 : const table::CellRangeAddress* pAry = aRanges.getConstArray();
748 8 : for (sal_uInt16 i=0; i<nRangeCount; i++)
749 : {
750 12 : ScRange aRange( static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow, pAry[i].Sheet,
751 16 : static_cast<SCCOL>(pAry[i].EndColumn), pAry[i].EndRow, pAry[i].Sheet );
752 4 : pList->Append( aRange );
753 : }
754 : }
755 8 : ScRangeListRef xNewRanges( pList );
756 :
757 4 : if ( !xOldRanges.Is() || *xOldRanges != *xNewRanges )
758 8 : Update_Impl( xNewRanges, bColHeaders, bRowHeaders );
759 4 : }
760 :
761 : // XEmbeddedObjectSupplier
762 :
763 98 : uno::Reference<lang::XComponent> SAL_CALL ScChartObj::getEmbeddedObject() throw(uno::RuntimeException, std::exception)
764 : {
765 98 : SolarMutexGuard aGuard;
766 98 : SdrOle2Obj* pObject = lcl_FindChartObj( pDocShell, nTab, aChartName );
767 98 : 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 98 : return uno::Reference < lang::XComponent > ( pObject->GetObjRef()->getComponent(), uno::UNO_QUERY );
771 : }
772 :
773 0 : return NULL;
774 : }
775 :
776 : // XNamed
777 :
778 4 : OUString SAL_CALL ScChartObj::getName() throw(uno::RuntimeException, std::exception)
779 : {
780 4 : SolarMutexGuard aGuard;
781 4 : 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 228 : }
796 :
797 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|