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