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