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