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