Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/controller/itemsetwrapper/SeriesOptionsItemConverter.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 <SeriesOptionsItemConverter.hxx>
21
#include "SchWhichPairs.hxx"
22
23
#include <ChartType.hxx>
24
#include <Axis.hxx>
25
#include <AxisHelper.hxx>
26
#include <Diagram.hxx>
27
#include <ChartTypeHelper.hxx>
28
#include <DataSeriesHelper.hxx>
29
#include <ChartModel.hxx>
30
#include <BaseCoordinateSystem.hxx>
31
32
#include <svl/eitem.hxx>
33
#include <svl/intitem.hxx>
34
#include <svl/ilstitem.hxx>
35
#include <svx/sdangitm.hxx>
36
#include <utility>
37
#include <comphelper/diagnose_ex.hxx>
38
39
using namespace ::com::sun::star;
40
using namespace ::com::sun::star::chart2;
41
42
namespace chart::wrapper
43
{
44
45
SeriesOptionsItemConverter::SeriesOptionsItemConverter(
46
        const rtl::Reference<::chart::ChartModel>& xChartModel
47
        , uno::Reference< uno::XComponentContext > xContext
48
        , const rtl::Reference< ::chart::DataSeries >& xDataSeries
49
        , SfxItemPool& rItemPool )
50
0
        : ItemConverter( xDataSeries, rItemPool )
51
0
        , m_xChartModel(xChartModel)
52
0
        , m_xCC(std::move(xContext))
53
0
        , m_bAttachToMainAxis(true)
54
0
        , m_bSupportingOverlapAndGapWidthProperties(false)
55
0
        , m_bSupportingBarConnectors(false)
56
0
        , m_nBarOverlap(0)
57
0
        , m_nGapWidth(100)
58
0
        , m_bConnectBars(false)
59
0
        , m_bSupportingAxisSideBySide(false)
60
0
        , m_bGroupBarsPerAxis(true)
61
0
        , m_bSupportingStartingAngle(false)
62
0
        , m_nStartingAngle(90)
63
0
        , m_bClockwise(false)
64
0
        , m_nMissingValueTreatment(0)
65
0
        , m_bSupportingPlottingOfHiddenCells(false)
66
0
        , m_bIncludeHiddenCells(true)
67
0
        , m_bHideLegendEntry(false)
68
0
{
69
0
    try
70
0
    {
71
0
        m_bAttachToMainAxis = xDataSeries->isAttachedToMainAxis();
72
73
0
        rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
74
0
        rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xDataSeries ) );
75
76
0
        m_xCooSys = DataSeriesHelper::getCoordinateSystemOfSeries( xDataSeries, xDiagram );
77
0
        if( m_xCooSys.is() )
78
0
        {
79
0
            rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1, 0, m_xCooSys );
80
0
            chart2::ScaleData aScale( xAxis->getScaleData() );
81
0
            m_bClockwise = (aScale.Orientation == chart2::AxisOrientation_REVERSE);
82
0
        }
83
84
0
        sal_Int32 nDimensionCount = xDiagram->getDimension();
85
0
        m_bSupportingOverlapAndGapWidthProperties = xChartType.is() ?
86
0
            xChartType->isSupportingOverlapAndGapWidthProperties(nDimensionCount) : false;
87
88
0
        if( m_bSupportingOverlapAndGapWidthProperties )
89
0
        {
90
91
0
            sal_Int32 nAxisIndex = xDataSeries->getAttachedAxisIndex();
92
93
0
            uno::Sequence< sal_Int32 > aBarPositionSequence;
94
0
            if( xChartType.is() )
95
0
            {
96
0
                if( xChartType->getPropertyValue( u"OverlapSequence"_ustr ) >>= aBarPositionSequence )
97
0
                {
98
0
                    if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() )
99
0
                        m_nBarOverlap = aBarPositionSequence[nAxisIndex];
100
0
                }
101
0
                if( xChartType->getPropertyValue( u"GapwidthSequence"_ustr ) >>= aBarPositionSequence )
102
0
                {
103
0
                    if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() )
104
0
                        m_nGapWidth = aBarPositionSequence[nAxisIndex];
105
0
                }
106
0
            }
107
0
        }
108
109
0
        m_bSupportingBarConnectors = xChartType.is() ? xChartType->isSupportingBarConnectors(nDimensionCount) : false;
110
0
        if( m_bSupportingBarConnectors && xDiagram.is() )
111
0
        {
112
0
            xDiagram->getPropertyValue( u"ConnectBars"_ustr ) >>= m_bConnectBars;
113
0
        }
114
115
0
        m_bSupportingAxisSideBySide = xChartType.is() ? xChartType->isSupportingAxisSideBySide(nDimensionCount) : false;
116
0
        if( m_bSupportingAxisSideBySide && xDiagram.is() )
117
0
        {
118
0
            xDiagram->getPropertyValue( u"GroupBarsPerAxis"_ustr ) >>= m_bGroupBarsPerAxis;
119
0
        }
120
121
0
        m_bSupportingStartingAngle = xChartType.is() ? xChartType->isSupportingStartingAngle() : false;
122
0
        if( m_bSupportingStartingAngle )
123
0
        {
124
0
            xDiagram->getPropertyValue( u"StartingAngle"_ustr ) >>= m_nStartingAngle;
125
0
        }
126
127
0
        m_aSupportedMissingValueTreatments = ChartTypeHelper::getSupportedMissingValueTreatments( xChartType );
128
0
        m_nMissingValueTreatment = xDiagram->getCorrectedMissingValueTreatment( xChartType );
129
130
0
        uno::Reference< beans::XPropertySet > xProp( m_xChartModel->getDataProvider(), uno::UNO_QUERY );
131
0
        if( xProp.is() )
132
0
        {
133
0
            try
134
0
            {
135
                //test whether the data provider offers this property
136
0
                xProp->getPropertyValue( u"IncludeHiddenCells"_ustr );
137
                //if not exception is thrown the property is offered
138
0
                m_bSupportingPlottingOfHiddenCells = true;
139
0
                xDiagram->getPropertyValue( u"IncludeHiddenCells"_ustr ) >>= m_bIncludeHiddenCells;
140
0
            }
141
0
            catch( const beans::UnknownPropertyException& )
142
0
            {
143
0
            }
144
0
        }
145
146
0
        m_bHideLegendEntry = !xDataSeries->getPropertyValue(u"ShowLegendEntry"_ustr).get<bool>();
147
0
    }
148
0
    catch( const uno::Exception & )
149
0
    {
150
0
        DBG_UNHANDLED_EXCEPTION("chart2");
151
0
    }
152
0
}
153
154
SeriesOptionsItemConverter::~SeriesOptionsItemConverter()
155
0
{
156
0
}
157
158
const WhichRangesContainer& SeriesOptionsItemConverter::GetWhichPairs() const
159
0
{
160
    // must span all used items!
161
0
    return nSeriesOptionsWhichPairs;
162
0
}
163
164
bool SeriesOptionsItemConverter::GetItemProperty( tWhichIdType /*nWhichId*/, tPropertyNameWithMemberId & /*rOutProperty*/ ) const
165
0
{
166
0
    return false;
167
0
}
168
169
bool SeriesOptionsItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet & rItemSet )
170
0
{
171
0
    bool bChanged = false;
172
0
    switch( nWhichId )
173
0
    {
174
0
        case SCHATTR_AXIS:
175
0
        {
176
0
            sal_Int32 nItemValue = static_cast< const SfxInt32Item & >(
177
0
                    rItemSet.Get( nWhichId )).GetValue();
178
0
            bool bAttachToMainAxis = nItemValue == AFAxix(AxisAtr::PrimaryY);
179
0
            if( bAttachToMainAxis != m_bAttachToMainAxis )
180
0
            {
181
                //change model:
182
0
                rtl::Reference<DataSeries> xDataSeries = dynamic_cast<DataSeries*>( GetPropertySet().get() );
183
0
                bChanged = m_xChartModel->getFirstChartDiagram()->attachSeriesToAxis( bAttachToMainAxis, xDataSeries
184
0
                    , m_xCC );
185
186
0
                if( bChanged )
187
0
                    m_bAttachToMainAxis = bAttachToMainAxis;
188
0
            }
189
0
        }
190
0
        break;
191
192
0
        case SCHATTR_BAR_OVERLAP:
193
0
        case SCHATTR_BAR_GAPWIDTH:
194
0
        {
195
0
            if( m_bSupportingOverlapAndGapWidthProperties )
196
0
            {
197
0
                sal_Int32& rBarPosition = ( nWhichId == SCHATTR_BAR_OVERLAP ) ? m_nBarOverlap : m_nGapWidth;
198
0
                rBarPosition = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
199
200
0
                OUString aPropName(u"GapwidthSequence"_ustr );
201
0
                if( nWhichId == SCHATTR_BAR_OVERLAP )
202
0
                    aPropName = "OverlapSequence";
203
204
0
                rtl::Reference< DataSeries > xDataSeries( dynamic_cast<DataSeries*>(GetPropertySet().get()) );
205
0
                rtl::Reference< Diagram > xDiagram( m_xChartModel->getFirstChartDiagram() );
206
0
                rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xDataSeries ) );
207
0
                if( xChartType.is() )
208
0
                {
209
0
                    sal_Int32 nAxisIndex = xDataSeries->getAttachedAxisIndex();
210
0
                    uno::Sequence< sal_Int32 > aBarPositionSequence;
211
0
                    if( xChartType->getPropertyValue( aPropName ) >>= aBarPositionSequence )
212
0
                    {
213
0
                        bool bGroupBarsPerAxis =  rItemSet.Get( SCHATTR_GROUP_BARS_PER_AXIS ).GetValue();
214
0
                        if(!bGroupBarsPerAxis)
215
0
                        {
216
                            //set the same value for all axes
217
0
                            for( auto & pos : asNonConstRange(aBarPositionSequence) )
218
0
                                pos = rBarPosition;
219
0
                        }
220
0
                        else if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() )
221
0
                            aBarPositionSequence.getArray()[nAxisIndex] = rBarPosition;
222
223
0
                        xChartType->setPropertyValue( aPropName, uno::Any(aBarPositionSequence) );
224
0
                        bChanged = true;
225
0
                    }
226
0
                }
227
0
            }
228
0
        }
229
0
        break;
230
231
0
        case SCHATTR_BAR_CONNECT:
232
0
        {
233
0
            m_bConnectBars = static_cast< const SfxBoolItem & >(
234
0
                rItemSet.Get( nWhichId )).GetValue();
235
0
            if( m_bSupportingBarConnectors )
236
0
            {
237
0
                bool bOldConnectBars = false;
238
0
                rtl::Reference< Diagram > xDiagramProperties( m_xChartModel->getFirstChartDiagram() );
239
0
                if( xDiagramProperties.is() &&
240
0
                    (xDiagramProperties->getPropertyValue( u"ConnectBars"_ustr ) >>= bOldConnectBars) &&
241
0
                    bOldConnectBars != m_bConnectBars )
242
0
                {
243
0
                    xDiagramProperties->setPropertyValue( u"ConnectBars"_ustr , uno::Any(m_bConnectBars) );
244
0
                    bChanged = true;
245
0
                }
246
0
            }
247
0
        }
248
0
        break;
249
250
0
        case SCHATTR_GROUP_BARS_PER_AXIS:
251
0
        {
252
0
            m_bGroupBarsPerAxis = static_cast< const SfxBoolItem & >(
253
0
                rItemSet.Get( nWhichId )).GetValue();
254
0
            if( m_bSupportingAxisSideBySide )
255
0
            {
256
0
                bool bOldGroupBarsPerAxis = true;
257
0
                rtl::Reference< Diagram > xDiagramProperties( m_xChartModel->getFirstChartDiagram() );
258
0
                if( xDiagramProperties.is() &&
259
0
                    (xDiagramProperties->getPropertyValue( u"GroupBarsPerAxis"_ustr ) >>= bOldGroupBarsPerAxis) &&
260
0
                    bOldGroupBarsPerAxis != m_bGroupBarsPerAxis )
261
0
                {
262
0
                    xDiagramProperties->setPropertyValue( u"GroupBarsPerAxis"_ustr , uno::Any(m_bGroupBarsPerAxis) );
263
0
                    bChanged = true;
264
0
                }
265
0
            }
266
0
         }
267
0
         break;
268
269
0
         case SCHATTR_STARTING_ANGLE:
270
0
         {
271
0
            if( m_bSupportingStartingAngle )
272
0
            {
273
0
                m_nStartingAngle = static_cast< const SdrAngleItem & >( rItemSet.Get( nWhichId )).GetValue().get() / 100;
274
0
                rtl::Reference< Diagram > xDiagramProperties( m_xChartModel->getFirstChartDiagram() );
275
0
                if( xDiagramProperties.is() )
276
0
                {
277
0
                    xDiagramProperties->setPropertyValue( u"StartingAngle"_ustr , uno::Any(m_nStartingAngle) );
278
0
                    bChanged = true;
279
0
                }
280
0
            }
281
0
        }
282
0
        break;
283
284
0
        case SCHATTR_CLOCKWISE:
285
0
        {
286
0
            bool bClockwise = static_cast< const SfxBoolItem & >(
287
0
                     rItemSet.Get( nWhichId )).GetValue();
288
0
            if( m_xCooSys.is() )
289
0
            {
290
0
                rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1, 0, m_xCooSys );
291
0
                if( xAxis.is() )
292
0
                {
293
0
                    chart2::ScaleData aScaleData( xAxis->getScaleData() );
294
0
                    aScaleData.Orientation = bClockwise ? chart2::AxisOrientation_REVERSE : chart2::AxisOrientation_MATHEMATICAL;
295
0
                    xAxis->setScaleData( aScaleData );
296
0
                    bChanged = true;
297
0
                }
298
0
            }
299
0
        }
300
0
        break;
301
302
0
        case SCHATTR_MISSING_VALUE_TREATMENT:
303
0
        {
304
0
            if( m_aSupportedMissingValueTreatments.hasElements() )
305
0
            {
306
0
                sal_Int32 nNew = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
307
0
                if( m_nMissingValueTreatment != nNew )
308
0
                {
309
0
                    try
310
0
                    {
311
0
                        rtl::Reference< Diagram > xDiagramProperties( m_xChartModel->getFirstChartDiagram() );
312
0
                        if( xDiagramProperties.is() )
313
0
                        {
314
0
                            xDiagramProperties->setPropertyValue( u"MissingValueTreatment"_ustr , uno::Any( nNew ));
315
0
                            bChanged = true;
316
0
                        }
317
0
                    }
318
0
                    catch( const uno::Exception& )
319
0
                    {
320
0
                        TOOLS_WARN_EXCEPTION("chart2", "" );
321
0
                    }
322
0
                }
323
0
            }
324
0
        }
325
0
        break;
326
0
        case SCHATTR_INCLUDE_HIDDEN_CELLS:
327
0
        {
328
0
            if( m_bSupportingPlottingOfHiddenCells )
329
0
            {
330
0
                bool bIncludeHiddenCells = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue();
331
0
                if (bIncludeHiddenCells != m_bIncludeHiddenCells)
332
0
                {
333
0
                    if (m_xChartModel)
334
0
                        bChanged = m_xChartModel->setIncludeHiddenCells( bIncludeHiddenCells );
335
0
                }
336
0
            }
337
0
        }
338
0
        break;
339
0
        case SCHATTR_HIDE_LEGEND_ENTRY:
340
0
        {
341
0
            bool bHideLegendEntry = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue();
342
0
            if (bHideLegendEntry != m_bHideLegendEntry)
343
0
            {
344
0
                GetPropertySet()->setPropertyValue(u"ShowLegendEntry"_ustr, css::uno::Any(!bHideLegendEntry));
345
0
            }
346
0
        }
347
0
        break;
348
0
    }
349
0
    return bChanged;
350
0
}
351
352
void SeriesOptionsItemConverter::FillSpecialItem(
353
    sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const
354
0
{
355
0
    switch( nWhichId )
356
0
    {
357
0
        case SCHATTR_AXIS:
358
0
        {
359
0
            rOutItemSet.Put( SfxInt32Item(nWhichId,AFAxix::toNum(m_bAttachToMainAxis ? AxisAtr::PrimaryY : AxisAtr::SecondaryY) ) );
360
0
            break;
361
0
        }
362
0
        case SCHATTR_BAR_OVERLAP:
363
0
        {
364
0
            if( m_bSupportingOverlapAndGapWidthProperties )
365
0
                rOutItemSet.Put( SfxInt32Item(nWhichId,m_nBarOverlap) );
366
0
            break;
367
0
        }
368
0
        case SCHATTR_BAR_GAPWIDTH:
369
0
        {
370
0
            if( m_bSupportingOverlapAndGapWidthProperties )
371
0
                rOutItemSet.Put( SfxInt32Item(nWhichId,m_nGapWidth) );
372
0
            break;
373
0
        }
374
0
        case SCHATTR_BAR_CONNECT:
375
0
        {
376
0
            if( m_bSupportingBarConnectors )
377
0
                rOutItemSet.Put( SfxBoolItem(nWhichId,m_bConnectBars));
378
0
            break;
379
0
        }
380
0
        case SCHATTR_GROUP_BARS_PER_AXIS:
381
0
        {
382
0
            if( m_bSupportingAxisSideBySide )
383
0
                rOutItemSet.Put( SfxBoolItem(nWhichId,m_bGroupBarsPerAxis) );
384
0
            break;
385
0
        }
386
0
        case SCHATTR_AXIS_FOR_ALL_SERIES:
387
0
        {
388
0
            break;
389
0
        }
390
0
        case SCHATTR_STARTING_ANGLE:
391
0
        {
392
0
            if( m_bSupportingStartingAngle )
393
0
                rOutItemSet.Put( SdrAngleItem(SCHATTR_STARTING_ANGLE, Degree100(m_nStartingAngle*100)) );
394
0
            break;
395
0
        }
396
0
        case SCHATTR_CLOCKWISE:
397
0
        {
398
0
            rOutItemSet.Put( SfxBoolItem(nWhichId,m_bClockwise) );
399
0
            break;
400
0
        }
401
0
        case SCHATTR_MISSING_VALUE_TREATMENT:
402
0
        {
403
0
            if( m_aSupportedMissingValueTreatments.hasElements() )
404
0
                rOutItemSet.Put( SfxInt32Item( nWhichId, m_nMissingValueTreatment ));
405
0
            break;
406
0
        }
407
0
        case SCHATTR_AVAILABLE_MISSING_VALUE_TREATMENTS:
408
0
        {
409
0
            rOutItemSet.Put( SfxIntegerListItem( nWhichId, m_aSupportedMissingValueTreatments ) );
410
0
            break;
411
0
        }
412
0
        case SCHATTR_INCLUDE_HIDDEN_CELLS:
413
0
        {
414
0
            if( m_bSupportingPlottingOfHiddenCells )
415
0
                rOutItemSet.Put( SfxBoolItem(nWhichId, m_bIncludeHiddenCells) );
416
0
            break;
417
0
        }
418
0
        case SCHATTR_HIDE_LEGEND_ENTRY:
419
0
        {
420
0
            rOutItemSet.Put(SfxBoolItem(nWhichId, m_bHideLegendEntry));
421
0
            break;
422
0
        }
423
0
        default:
424
0
            break;
425
0
   }
426
0
}
427
428
} //  namespace chart
429
430
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */