Coverage Report

Created: 2025-11-16 09:57

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