Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/controller/main/ChartController_Properties.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 <ChartController.hxx>
21
#include <ChartView.hxx>
22
#include <chartview/DrawModelWrapper.hxx>
23
#include <chartview/ChartSfxItemIds.hxx>
24
#include <ObjectIdentifier.hxx>
25
#include <chartview/ExplicitScaleValues.hxx>
26
#include <dlg_ObjectProperties.hxx>
27
#include <dlg_View3D.hxx>
28
#include <dlg_InsertErrorBars.hxx>
29
#include <ViewElementListProvider.hxx>
30
#include <DataPointItemConverter.hxx>
31
#include <TextLabelItemConverter.hxx>
32
#include <AxisItemConverter.hxx>
33
#include <MultipleChartConverters.hxx>
34
#include <TitleItemConverter.hxx>
35
#include <LegendItemConverter.hxx>
36
#include <DataTableItemConverter.hxx>
37
#include <RegressionCurveItemConverter.hxx>
38
#include <RegressionEquationItemConverter.hxx>
39
#include <ErrorBarItemConverter.hxx>
40
#include <Axis.hxx>
41
#include <AxisHelper.hxx>
42
#include <TitleHelper.hxx>
43
#include <ChartType.hxx>
44
#include <ChartModel.hxx>
45
#include <DataSeries.hxx>
46
#include <DataSeriesProperties.hxx>
47
#include <Diagram.hxx>
48
#include <ControllerLockGuard.hxx>
49
#include "UndoGuard.hxx"
50
#include <ObjectNameProvider.hxx>
51
#include <ResId.hxx>
52
#include <strings.hrc>
53
#include <ReferenceSizeProvider.hxx>
54
#include <RegressionCurveHelper.hxx>
55
#include <RegressionCurveModel.hxx>
56
#include <o3tl/string_view.hxx>
57
#include <com/sun/star/util/CloseVetoException.hpp>
58
59
#include <memory>
60
61
#include <vcl/svapp.hxx>
62
#include <svx/ActionDescriptionProvider.hxx>
63
#include <comphelper/diagnose_ex.hxx>
64
65
namespace chart
66
{
67
using namespace ::com::sun::star;
68
using namespace ::com::sun::star::chart2;
69
using namespace ::chart::DataSeriesProperties;
70
using ::com::sun::star::uno::Reference;
71
72
namespace
73
{
74
75
wrapper::ItemConverter* createItemConverter(
76
    std::u16string_view aObjectCID, const rtl::Reference<::chart::ChartModel>& xChartModel,
77
    const uno::Reference<uno::XComponentContext>& xContext, SdrModel& rDrawModel,
78
    ChartView* pExplicitValueProvider, ReferenceSizeProvider const * pRefSizeProvider )
79
0
{
80
0
    wrapper::ItemConverter* pItemConverter=nullptr;
81
82
    //get type of selected object
83
0
    ObjectType eObjectType = ObjectIdentifier::getObjectType( aObjectCID );
84
0
    if( eObjectType==OBJECTTYPE_UNKNOWN )
85
0
    {
86
0
        OSL_FAIL("unknown ObjectType");
87
0
        return nullptr;
88
0
    }
89
90
0
    std::u16string_view aParticleID = ObjectIdentifier::getParticleID( aObjectCID );
91
0
    bool bAffectsMultipleObjects = aParticleID == u"ALLELEMENTS";
92
0
    if( !bAffectsMultipleObjects )
93
0
    {
94
0
        uno::Reference< beans::XPropertySet > xObjectProperties =
95
0
            ObjectIdentifier::getObjectPropertySet( aObjectCID, xChartModel );
96
0
        if(!xObjectProperties.is())
97
0
            return nullptr;
98
        //create itemconverter for a single object
99
0
        switch(eObjectType)
100
0
        {
101
0
            case OBJECTTYPE_DATA_STOCK_LOSS:
102
0
            case OBJECTTYPE_DATA_STOCK_GAIN:
103
0
            case OBJECTTYPE_DIAGRAM_WALL:
104
0
            case OBJECTTYPE_DIAGRAM_FLOOR:
105
0
            case OBJECTTYPE_PAGE:
106
0
                pItemConverter =  new wrapper::GraphicPropertyItemConverter(
107
0
                                        xObjectProperties, rDrawModel.GetItemPool(),
108
0
                                        rDrawModel, xChartModel,
109
0
                                        wrapper::GraphicObjectType::LineAndFillProperties );
110
0
                    break;
111
0
            case OBJECTTYPE_TITLE:
112
0
            {
113
0
                std::optional<awt::Size> pRefSize;
114
0
                if (pRefSizeProvider)
115
0
                    pRefSize.emplace(pRefSizeProvider->getPageSize());
116
117
0
                pItemConverter = new wrapper::TitleItemConverter(
118
0
                    xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
119
0
                    xChartModel,
120
0
                    pRefSize);
121
0
            }
122
0
            break;
123
0
            case OBJECTTYPE_LEGEND:
124
0
            {
125
0
                std::optional<awt::Size> pRefSize;
126
0
                if (pRefSizeProvider)
127
0
                    pRefSize.emplace( pRefSizeProvider->getPageSize() );
128
129
0
                pItemConverter = new wrapper::LegendItemConverter(
130
0
                    xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
131
0
                    xChartModel,
132
0
                    pRefSize);
133
0
            }
134
0
            break;
135
0
            case OBJECTTYPE_LEGEND_ENTRY:
136
0
                    break;
137
0
            case OBJECTTYPE_DIAGRAM:
138
0
                    break;
139
0
            case OBJECTTYPE_AXIS:
140
0
            {
141
0
                std::optional<awt::Size> pRefSize;
142
0
                if (pRefSizeProvider)
143
0
                    pRefSize.emplace( pRefSizeProvider->getPageSize() );
144
145
                // the second property set contains the property CoordinateOrigin
146
                // nOriginIndex is the index of the corresponding index of the
147
                // origin (x=0, y=1, z=2)
148
149
0
                ExplicitScaleData aExplicitScale;
150
0
                ExplicitIncrementData aExplicitIncrement;
151
0
                if( pExplicitValueProvider )
152
0
                    pExplicitValueProvider->getExplicitValuesForAxis(
153
0
                        dynamic_cast< Axis* >( xObjectProperties.get() ),
154
0
                        aExplicitScale, aExplicitIncrement );
155
156
0
                pItemConverter =  new wrapper::AxisItemConverter(
157
0
                    xObjectProperties, rDrawModel.GetItemPool(),
158
0
                    rDrawModel,
159
0
                    xChartModel,
160
0
                    &aExplicitScale, &aExplicitIncrement,
161
0
                    pRefSize );
162
0
            }
163
0
            break;
164
0
            case OBJECTTYPE_AXIS_UNITLABEL:
165
0
                    break;
166
0
            case OBJECTTYPE_DATA_LABELS:
167
0
            case OBJECTTYPE_DATA_LABEL:
168
0
            {
169
0
                std::optional<awt::Size> pRefSize;
170
0
                if (pRefSizeProvider)
171
0
                    pRefSize.emplace( pRefSizeProvider->getPageSize() );
172
173
0
                rtl::Reference<DataSeries> xSeries = ObjectIdentifier::getDataSeriesForCID(aObjectCID, xChartModel);
174
175
0
                bool bDataSeries = eObjectType == OBJECTTYPE_DATA_LABELS;
176
177
0
                sal_Int32 nNumberFormat = xSeries->getExplicitNumberFormatKeyForDataLabel();
178
0
                sal_Int32 nPercentNumberFormat = ChartView::getExplicitPercentageNumberFormatKeyForDataLabel(
179
0
                    xObjectProperties, xChartModel);
180
181
0
                pItemConverter = new wrapper::TextLabelItemConverter(
182
0
                    xChartModel, xObjectProperties, xSeries,
183
0
                    rDrawModel.GetItemPool(), pRefSize, bDataSeries,
184
0
                    nNumberFormat, nPercentNumberFormat);
185
0
            }
186
0
            break;
187
0
            case OBJECTTYPE_DATA_SERIES:
188
0
            case OBJECTTYPE_DATA_POINT:
189
0
            {
190
0
                std::optional<awt::Size> pRefSize;
191
0
                if (pRefSizeProvider)
192
0
                    pRefSize.emplace( pRefSizeProvider->getPageSize() );
193
194
0
                wrapper::GraphicObjectType eMapTo =
195
0
                    wrapper::GraphicObjectType::FilledDataPoint;
196
197
0
                rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel );
198
0
                rtl::Reference< ChartType > xChartType = xChartModel->getChartTypeOfSeries( xSeries );
199
200
0
                rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
201
0
                sal_Int32 nDimensionCount = xDiagram->getDimension();
202
0
                if (xChartType.is() && !xChartType->isSupportingAreaProperties(nDimensionCount))
203
0
                    eMapTo = wrapper::GraphicObjectType::LineDataPoint;
204
205
0
                bool bDataSeries = eObjectType == OBJECTTYPE_DATA_SERIES;
206
207
                //special color for pie chart:
208
0
                bool bUseSpecialFillColor = false;
209
0
                sal_Int32 nSpecialFillColor =0;
210
0
                sal_Int32 nPointIndex = -1; /*-1 for whole series*/
211
0
                if(!bDataSeries)
212
0
                {
213
0
                    nPointIndex = o3tl::toInt32(aParticleID);
214
0
                    bool bVaryColorsByPoint = false;
215
0
                    if( xSeries.is() &&
216
                        // "VaryColorsByPoint"
217
0
                        (xSeries->getFastPropertyValue(PROP_DATASERIES_VARY_COLORS_BY_POINT) >>= bVaryColorsByPoint) &&
218
0
                        bVaryColorsByPoint )
219
0
                    {
220
0
                        if( !xSeries->hasPointOwnColor( nPointIndex, xObjectProperties ) )
221
0
                        {
222
0
                            bUseSpecialFillColor = true;
223
0
                            OSL_ASSERT( xDiagram.is());
224
0
                            uno::Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme() );
225
0
                            if( xColorScheme.is())
226
0
                                nSpecialFillColor = xColorScheme->getColorByIndex( nPointIndex );
227
0
                        }
228
0
                    }
229
0
                }
230
0
                sal_Int32 nNumberFormat=xSeries->getExplicitNumberFormatKeyForDataLabel();
231
0
                sal_Int32 nPercentNumberFormat=ChartView::getExplicitPercentageNumberFormatKeyForDataLabel(
232
0
                        xObjectProperties, xChartModel);
233
234
0
                pItemConverter =  new wrapper::DataPointItemConverter( xChartModel, xContext,
235
0
                                        xObjectProperties, xSeries, rDrawModel.GetItemPool(), rDrawModel,
236
0
                                        eMapTo, pRefSize, bDataSeries, bUseSpecialFillColor, nSpecialFillColor, true,
237
0
                                        nNumberFormat, nPercentNumberFormat, nPointIndex );
238
0
                break;
239
0
            }
240
0
            case OBJECTTYPE_GRID:
241
0
            case OBJECTTYPE_SUBGRID:
242
0
            case OBJECTTYPE_DATA_AVERAGE_LINE:
243
0
                pItemConverter =  new wrapper::GraphicPropertyItemConverter(
244
0
                                        xObjectProperties, rDrawModel.GetItemPool(),
245
0
                                        rDrawModel, xChartModel,
246
0
                                        wrapper::GraphicObjectType::LineProperties );
247
0
                    break;
248
249
0
            case OBJECTTYPE_DATA_ERRORS_X:
250
0
            case OBJECTTYPE_DATA_ERRORS_Y:
251
0
            case OBJECTTYPE_DATA_ERRORS_Z:
252
0
                pItemConverter =  new wrapper::ErrorBarItemConverter(
253
0
                    xChartModel, xObjectProperties, rDrawModel.GetItemPool(),
254
0
                    rDrawModel );
255
0
                break;
256
257
0
            case OBJECTTYPE_DATA_CURVE:
258
0
                pItemConverter =  new wrapper::RegressionCurveItemConverter(
259
0
                        xObjectProperties,
260
0
                        ObjectIdentifier::getDataSeriesForCID( aObjectCID, xChartModel ),
261
0
                        rDrawModel.GetItemPool(), rDrawModel,
262
0
                        xChartModel);
263
0
                break;
264
0
            case OBJECTTYPE_DATA_CURVE_EQUATION:
265
0
            {
266
0
                std::optional<awt::Size> pRefSize;
267
0
                if (pRefSizeProvider)
268
0
                    pRefSize.emplace(pRefSizeProvider->getPageSize());
269
270
0
                pItemConverter =  new wrapper::RegressionEquationItemConverter(
271
0
                                        xObjectProperties, rDrawModel.GetItemPool(), rDrawModel,
272
0
                                        xChartModel,
273
0
                                        pRefSize);
274
0
                break;
275
0
            }
276
0
            case OBJECTTYPE_DATA_STOCK_RANGE:
277
0
                    break;
278
0
            case OBJECTTYPE_DATA_TABLE:
279
0
            {
280
0
                pItemConverter =  new wrapper::DataTableItemConverter(
281
0
                                        xObjectProperties, rDrawModel.GetItemPool(),
282
0
                                        rDrawModel, xChartModel);
283
0
            }
284
0
            break;
285
0
            default: //OBJECTTYPE_UNKNOWN
286
0
                    break;
287
0
        }
288
0
    }
289
0
    else
290
0
    {
291
        //create itemconverter for all objects of given type
292
0
        switch(eObjectType)
293
0
        {
294
0
            case OBJECTTYPE_TITLE:
295
0
                pItemConverter =  new wrapper::AllTitleItemConverter( xChartModel, rDrawModel.GetItemPool(),
296
0
                                                                     rDrawModel );
297
0
                break;
298
0
            case OBJECTTYPE_AXIS:
299
0
            {
300
0
                std::optional<awt::Size> pRefSize;
301
0
                if (pRefSizeProvider)
302
0
                    pRefSize.emplace( pRefSizeProvider->getPageSize() );
303
304
0
                pItemConverter =  new wrapper::AllAxisItemConverter(
305
0
                    xChartModel, rDrawModel.GetItemPool(),
306
0
                    rDrawModel, pRefSize );
307
0
            }
308
0
            break;
309
0
            case OBJECTTYPE_GRID:
310
0
            case OBJECTTYPE_SUBGRID:
311
0
                pItemConverter =  new wrapper::AllGridItemConverter( xChartModel, rDrawModel.GetItemPool(),
312
0
                                                                     rDrawModel );
313
0
                break;
314
0
            default: //for this type it is not supported to change all elements at once
315
0
                break;
316
0
        }
317
318
0
    }
319
0
    return pItemConverter;
320
0
}
321
322
OUString lcl_getTitleCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel> & xChartModel )
323
0
{
324
0
    if( rDispatchCommand == "AllTitles")
325
0
        return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_TITLE, u"ALLELEMENTS" );
326
327
0
    TitleHelper::eTitleType nTitleType( TitleHelper::MAIN_TITLE );
328
0
    if( rDispatchCommand == "SubTitle" )
329
0
        nTitleType = TitleHelper::SUB_TITLE;
330
0
    else if( rDispatchCommand == "XTitle" )
331
0
        nTitleType = TitleHelper::X_AXIS_TITLE;
332
0
    else if( rDispatchCommand == "YTitle" )
333
0
        nTitleType = TitleHelper::Y_AXIS_TITLE;
334
0
    else if( rDispatchCommand == "ZTitle" )
335
0
        nTitleType = TitleHelper::Z_AXIS_TITLE;
336
0
    else if( rDispatchCommand == "SecondaryXTitle" )
337
0
        nTitleType = TitleHelper::SECONDARY_X_AXIS_TITLE;
338
0
    else if( rDispatchCommand == "SecondaryYTitle" )
339
0
        nTitleType = TitleHelper::SECONDARY_Y_AXIS_TITLE;
340
341
0
    rtl::Reference< Title > xTitle( TitleHelper::getTitle( nTitleType, xChartModel ) );
342
0
    return ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, xChartModel );
343
0
}
344
345
OUString lcl_getAxisCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel>& xChartModel )
346
0
{
347
0
    if( rDispatchCommand == "DiagramAxisAll")
348
0
        return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_AXIS, u"ALLELEMENTS" );
349
350
0
    sal_Int32   nDimensionIndex=0;
351
0
    bool        bMainAxis=true;
352
0
    if( rDispatchCommand == "DiagramAxisX")
353
0
    {
354
0
        nDimensionIndex=0; bMainAxis=true;
355
0
    }
356
0
    else if( rDispatchCommand == "DiagramAxisY")
357
0
    {
358
0
        nDimensionIndex=1; bMainAxis=true;
359
0
    }
360
0
    else if( rDispatchCommand == "DiagramAxisZ")
361
0
    {
362
0
        nDimensionIndex=2; bMainAxis=true;
363
0
    }
364
0
    else if( rDispatchCommand == "DiagramAxisA")
365
0
    {
366
0
        nDimensionIndex=0; bMainAxis=false;
367
0
    }
368
0
    else if( rDispatchCommand == "DiagramAxisB")
369
0
    {
370
0
        nDimensionIndex=1; bMainAxis=false;
371
0
    }
372
373
0
    rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
374
0
    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram );
375
0
    return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel );
376
0
}
377
378
OUString lcl_getGridCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel>& xChartModel )
379
0
{
380
0
    rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
381
382
0
    if( rDispatchCommand == "DiagramGridAll")
383
0
        return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_GRID, u"ALLELEMENTS" );
384
385
0
    sal_Int32   nDimensionIndex=0;
386
0
    bool        bMainGrid=true;
387
388
    //x and y is swapped in the commands
389
390
0
    if( rDispatchCommand == "DiagramGridYMain")
391
0
    {
392
0
        nDimensionIndex=0; bMainGrid=true;
393
0
    }
394
0
    else if( rDispatchCommand == "DiagramGridXMain")
395
0
    {
396
0
        nDimensionIndex=1; bMainGrid=true;
397
0
    }
398
0
    else if( rDispatchCommand == "DiagramGridZMain")
399
0
    {
400
0
        nDimensionIndex=2; bMainGrid=true;
401
0
    }
402
0
    else if( rDispatchCommand == "DiagramGridYHelp")
403
0
    {
404
0
        nDimensionIndex=0; bMainGrid=false;
405
0
    }
406
0
    else if( rDispatchCommand == "DiagramGridXHelp")
407
0
    {
408
0
        nDimensionIndex=1; bMainGrid=false;
409
0
    }
410
0
    else if( rDispatchCommand == "DiagramGridZHelp")
411
0
    {
412
0
        nDimensionIndex=2; bMainGrid=false;
413
0
    }
414
415
0
    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, true/*bMainAxis*/, xDiagram );
416
417
0
    sal_Int32   nSubGridIndex= bMainGrid ? -1 : 0;
418
0
    OUString aCID( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGridIndex ) );
419
0
    return aCID;
420
0
}
421
422
OUString lcl_getErrorCIDForCommand( const ObjectType eDispatchType, const ObjectType &eSelectedType, const OUString &rSelectedCID)
423
0
{
424
0
    if( eSelectedType == eDispatchType )
425
0
        return rSelectedCID;
426
427
0
    return ObjectIdentifier::createClassifiedIdentifierWithParent( eDispatchType, u"", rSelectedCID );
428
0
}
429
430
OUString lcl_getObjectCIDForCommand( std::string_view rDispatchCommand, const rtl::Reference<::chart::ChartModel> & xChartDocument, const OUString& rSelectedCID )
431
0
{
432
0
    ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
433
434
0
    const ObjectType eSelectedType = ObjectIdentifier::getObjectType( rSelectedCID );
435
0
    rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rSelectedCID, xChartDocument );
436
437
    //legend
438
0
    if( rDispatchCommand == "Legend" || rDispatchCommand == "FormatLegend" )
439
0
    {
440
0
        eObjectType = OBJECTTYPE_LEGEND;
441
        //@todo set particular aParticleID if we have more than one legend
442
0
    }
443
    //wall floor area
444
0
    else if( rDispatchCommand == "DiagramWall" || rDispatchCommand == "FormatWall" )
445
0
    {
446
        //OBJECTTYPE_DIAGRAM;
447
0
        eObjectType = OBJECTTYPE_DIAGRAM_WALL;
448
        //@todo set particular aParticleID if we have more than one diagram
449
0
    }
450
0
    else if( rDispatchCommand == "DiagramFloor" || rDispatchCommand == "FormatFloor" )
451
0
    {
452
0
        eObjectType = OBJECTTYPE_DIAGRAM_FLOOR;
453
        //@todo set particular aParticleID if we have more than one diagram
454
0
    }
455
0
    else if( rDispatchCommand == "DiagramArea" || rDispatchCommand == "FormatChartArea" )
456
0
    {
457
0
        eObjectType = OBJECTTYPE_PAGE;
458
0
    }
459
    //title
460
0
    else if( rDispatchCommand == "MainTitle"
461
0
        || rDispatchCommand == "SubTitle"
462
0
        || rDispatchCommand == "XTitle"
463
0
        || rDispatchCommand == "YTitle"
464
0
        || rDispatchCommand == "ZTitle"
465
0
        || rDispatchCommand == "SecondaryXTitle"
466
0
        || rDispatchCommand == "SecondaryYTitle"
467
0
        || rDispatchCommand == "AllTitles"
468
0
        )
469
0
    {
470
0
        return lcl_getTitleCIDForCommand( rDispatchCommand, xChartDocument );
471
0
    }
472
    //axis
473
0
    else if( rDispatchCommand == "DiagramAxisX"
474
0
        || rDispatchCommand == "DiagramAxisY"
475
0
        || rDispatchCommand == "DiagramAxisZ"
476
0
        || rDispatchCommand == "DiagramAxisA"
477
0
        || rDispatchCommand == "DiagramAxisB"
478
0
        || rDispatchCommand == "DiagramAxisAll"
479
0
        )
480
0
    {
481
0
        return lcl_getAxisCIDForCommand( rDispatchCommand, xChartDocument );
482
0
    }
483
    //grid
484
0
    else if( rDispatchCommand == "DiagramGridYMain"
485
0
        || rDispatchCommand == "DiagramGridXMain"
486
0
        || rDispatchCommand == "DiagramGridZMain"
487
0
        || rDispatchCommand == "DiagramGridYHelp"
488
0
        || rDispatchCommand == "DiagramGridXHelp"
489
0
        || rDispatchCommand == "DiagramGridZHelp"
490
0
        || rDispatchCommand == "DiagramGridAll"
491
0
        )
492
0
    {
493
0
        return lcl_getGridCIDForCommand( rDispatchCommand, xChartDocument );
494
0
    }
495
    //data series
496
0
    else if( rDispatchCommand == "FormatDataSeries" )
497
0
    {
498
0
        if( eSelectedType == OBJECTTYPE_DATA_SERIES )
499
0
            return rSelectedCID;
500
0
        else
501
0
            return ObjectIdentifier::createClassifiedIdentifier(
502
0
                OBJECTTYPE_DATA_SERIES, ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ) );
503
0
    }
504
    //data point
505
0
    else if( rDispatchCommand == "FormatDataPoint" )
506
0
    {
507
0
        return rSelectedCID;
508
0
    }
509
    //data labels
510
0
    else if( rDispatchCommand == "FormatDataLabels" )
511
0
    {
512
0
        if( eSelectedType == OBJECTTYPE_DATA_LABELS )
513
0
            return rSelectedCID;
514
0
        else
515
0
            return ObjectIdentifier::createClassifiedIdentifierWithParent(
516
0
                OBJECTTYPE_DATA_LABELS, u"", rSelectedCID );
517
0
    }
518
    //data labels
519
0
    else if( rDispatchCommand == "FormatDataLabel" )
520
0
    {
521
0
        if( eSelectedType == OBJECTTYPE_DATA_LABEL )
522
0
            return rSelectedCID;
523
0
        else
524
0
        {
525
0
            sal_Int32 nPointIndex = o3tl::toInt32(ObjectIdentifier::getParticleID( rSelectedCID ));
526
0
            if( nPointIndex>=0 )
527
0
            {
528
0
                OUString aSeriesParticle = ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID );
529
0
                OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) + "=" );
530
0
                OUString aLabelsCID = ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle );
531
0
                OUString aLabelCID_Stub = ObjectIdentifier::createClassifiedIdentifierWithParent(
532
0
                    OBJECTTYPE_DATA_LABEL, u"", aLabelsCID );
533
534
0
                return ObjectIdentifier::createPointCID( aLabelCID_Stub, nPointIndex );
535
0
            }
536
0
        }
537
0
    }
538
    //mean value line
539
0
    else if( rDispatchCommand == "FormatMeanValue" )
540
0
    {
541
0
        if( eSelectedType == OBJECTTYPE_DATA_AVERAGE_LINE )
542
0
            return rSelectedCID;
543
0
        else
544
0
            return ObjectIdentifier::createDataCurveCID(
545
0
                ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
546
0
                    RegressionCurveHelper::getRegressionCurveIndex( xSeries,
547
0
                        RegressionCurveHelper::getMeanValueLine( xSeries ) ), true );
548
0
    }
549
    //trend line
550
0
    else if( rDispatchCommand == "FormatTrendline" )
551
0
    {
552
0
        if( eSelectedType == OBJECTTYPE_DATA_CURVE )
553
0
            return rSelectedCID;
554
0
        else
555
0
            return ObjectIdentifier::createDataCurveCID(
556
0
                ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
557
0
                    RegressionCurveHelper::getRegressionCurveIndex( xSeries,
558
0
                        RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries ) ), false );
559
0
    }
560
    //trend line equation
561
0
    else if( rDispatchCommand == "FormatTrendlineEquation" )
562
0
    {
563
0
        if( eSelectedType == OBJECTTYPE_DATA_CURVE_EQUATION )
564
0
            return rSelectedCID;
565
0
        else
566
0
            return ObjectIdentifier::createDataCurveEquationCID(
567
0
                ObjectIdentifier::getSeriesParticleFromCID( rSelectedCID ),
568
0
                    RegressionCurveHelper::getRegressionCurveIndex( xSeries,
569
0
                        RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries ) ) );
570
0
    }
571
    // y error bars
572
0
    else if( rDispatchCommand == "FormatXErrorBars" )
573
0
    {
574
0
        return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_X, eSelectedType, rSelectedCID );
575
0
    }
576
    // y error bars
577
0
    else if( rDispatchCommand == "FormatYErrorBars" )
578
0
    {
579
0
        return lcl_getErrorCIDForCommand(OBJECTTYPE_DATA_ERRORS_Y, eSelectedType, rSelectedCID );
580
0
    }
581
    // axis
582
0
    else if( rDispatchCommand == "FormatAxis" )
583
0
    {
584
0
        if( eSelectedType == OBJECTTYPE_AXIS )
585
0
            return rSelectedCID;
586
0
        else
587
0
        {
588
0
            rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
589
0
            return ObjectIdentifier::createClassifiedIdentifierForObject( xAxis , xChartDocument );
590
0
        }
591
0
    }
592
    // major grid
593
0
    else if( rDispatchCommand == "FormatMajorGrid" )
594
0
    {
595
0
        if( eSelectedType == OBJECTTYPE_GRID )
596
0
            return rSelectedCID;
597
0
        else
598
0
        {
599
0
            rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
600
0
            return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartDocument );
601
0
        }
602
603
0
    }
604
    // minor grid
605
0
    else if( rDispatchCommand == "FormatMinorGrid" )
606
0
    {
607
0
        if( eSelectedType == OBJECTTYPE_SUBGRID )
608
0
            return rSelectedCID;
609
0
        else
610
0
        {
611
0
            rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rSelectedCID, xChartDocument );
612
0
            return ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartDocument, 0 /*sub grid index*/ );
613
0
        }
614
0
    }
615
    // title
616
0
    else if( rDispatchCommand == "FormatTitle" )
617
0
    {
618
0
        if( eSelectedType == OBJECTTYPE_TITLE )
619
0
            return rSelectedCID;
620
0
    }
621
    // stock loss
622
0
    else if( rDispatchCommand == "FormatStockLoss" )
623
0
    {
624
0
        if( eSelectedType == OBJECTTYPE_DATA_STOCK_LOSS )
625
0
            return rSelectedCID;
626
0
        else
627
0
            return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_LOSS, u"");
628
0
    }
629
    // stock gain
630
0
    else if( rDispatchCommand == "FormatStockGain" )
631
0
    {
632
0
        if( eSelectedType == OBJECTTYPE_DATA_STOCK_GAIN )
633
0
            return rSelectedCID;
634
0
        else
635
0
            return ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DATA_STOCK_GAIN, u"" );
636
0
    }
637
638
0
    return ObjectIdentifier::createClassifiedIdentifier(
639
0
        eObjectType,
640
0
        u"" ); // aParticleID
641
0
}
642
643
}
644
// anonymous namespace
645
646
void ChartController::executeDispatch_FormatObject(std::u16string_view rDispatchCommand)
647
0
{
648
0
    rtl::Reference<::chart::ChartModel> xChartDocument( getChartModel() );
649
0
    OString aCommand( OUStringToOString( rDispatchCommand, RTL_TEXTENCODING_ASCII_US ) );
650
0
    OUString rObjectCID = lcl_getObjectCIDForCommand( aCommand, xChartDocument, m_aSelection.getSelectedCID() );
651
0
    executeDlg_ObjectProperties( rObjectCID );
652
0
}
653
654
void ChartController::executeDispatch_ObjectProperties()
655
0
{
656
0
    executeDlg_ObjectProperties( m_aSelection.getSelectedCID() );
657
0
}
658
659
namespace
660
{
661
662
OUString lcl_getFormatCIDforSelectedCID( const OUString& rSelectedCID )
663
0
{
664
0
    OUString aFormatCID(rSelectedCID);
665
666
    //get type of selected object
667
0
    ObjectType eObjectType = ObjectIdentifier::getObjectType( aFormatCID );
668
669
    // some legend entries are handled as if they were data series
670
0
    if( eObjectType==OBJECTTYPE_LEGEND_ENTRY )
671
0
    {
672
0
        std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( rSelectedCID ) );
673
0
        aFormatCID  = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
674
0
    }
675
676
    // treat diagram as wall
677
0
    if( eObjectType==OBJECTTYPE_DIAGRAM )
678
0
        aFormatCID  = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, u"" );
679
680
0
    return aFormatCID;
681
0
}
682
683
}//end anonymous namespace
684
685
void ChartController::executeDlg_ObjectProperties( const OUString& rSelectedObjectCID )
686
0
{
687
0
    OUString aObjectCID = lcl_getFormatCIDforSelectedCID( rSelectedObjectCID );
688
689
0
    auto xUndoGuard = std::make_shared<UndoGuard>(
690
0
        ActionDescriptionProvider::createDescription(
691
0
            ActionDescriptionProvider::ActionType::Format,
692
0
            ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aObjectCID ))),
693
0
        m_xUndoManager );
694
695
0
    ChartController::executeDlg_ObjectProperties_withUndoGuard(std::move(xUndoGuard), aObjectCID, false );
696
0
}
697
698
void ChartController::executeDlg_ObjectProperties_withUndoGuard(
699
    std::shared_ptr<UndoGuard> xUndoGuard, const OUString& rObjectCID, bool bSuccessOnUnchanged )
700
0
{
701
    //return true if the properties were changed successfully
702
0
    if( rObjectCID.isEmpty() )
703
0
    {
704
0
       return;
705
0
    }
706
0
    try
707
0
    {
708
        //get type of object
709
0
        ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
710
0
        if( eObjectType==OBJECTTYPE_UNKNOWN )
711
0
        {
712
0
            return;
713
0
        }
714
0
        if( eObjectType==OBJECTTYPE_DIAGRAM_WALL || eObjectType==OBJECTTYPE_DIAGRAM_FLOOR )
715
0
        {
716
0
            if( !getFirstDiagram()->isSupportingFloorAndWall() )
717
0
                return;
718
0
        }
719
720
        //convert properties to ItemSet
721
722
0
        ReferenceSizeProvider aRefSizeProv(impl_createReferenceSizeProvider());
723
724
0
        rtl::Reference<::chart::ChartModel> xChartDoc(getChartModel());
725
726
0
        std::shared_ptr<wrapper::ItemConverter> pItemConverter(
727
0
            createItemConverter( rObjectCID, xChartDoc, m_xCC,
728
0
                                 m_pDrawModelWrapper->getSdrModel(),
729
0
                                 m_xChartView.get(),
730
0
                                 &aRefSizeProv));
731
732
0
        if (!pItemConverter)
733
0
            return;
734
735
0
        SfxItemSet aItemSet = pItemConverter->CreateEmptyItemSet();
736
737
0
        if ( eObjectType == OBJECTTYPE_DATA_ERRORS_X || eObjectType == OBJECTTYPE_DATA_ERRORS_Y )
738
0
            aItemSet.Put(SfxBoolItem(SCHATTR_STAT_ERRORBAR_TYPE, eObjectType == OBJECTTYPE_DATA_ERRORS_Y ));
739
740
0
        pItemConverter->FillItemSet(aItemSet);
741
742
        //prepare dialog
743
0
        ObjectPropertiesDialogParameter aDialogParameter( rObjectCID );
744
0
        aDialogParameter.init(xChartDoc);
745
0
        ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get() );
746
747
0
        SolarMutexGuard aGuard;
748
0
        std::shared_ptr<SchAttribTabDlg> aDlgPtr = std::make_shared<SchAttribTabDlg>(
749
0
            GetChartFrame(), &aItemSet, aDialogParameter,
750
0
            &aViewElementListProvider,
751
0
            xChartDoc);
752
753
0
        if(aDialogParameter.HasSymbolProperties())
754
0
        {
755
0
            uno::Reference< beans::XPropertySet > xObjectProperties =
756
0
                ObjectIdentifier::getObjectPropertySet( rObjectCID, xChartDoc );
757
0
            wrapper::DataPointItemConverter aSymbolItemConverter( xChartDoc, m_xCC
758
0
                                        , xObjectProperties, ObjectIdentifier::getDataSeriesForCID( rObjectCID, xChartDoc )
759
0
                                        , m_pDrawModelWrapper->getSdrModel().GetItemPool()
760
0
                                        , m_pDrawModelWrapper->getSdrModel()
761
0
                                        , wrapper::GraphicObjectType::FilledDataPoint );
762
763
0
            SfxItemSet aSymbolShapeProperties(aSymbolItemConverter.CreateEmptyItemSet() );
764
0
            aSymbolItemConverter.FillItemSet( aSymbolShapeProperties );
765
766
0
            sal_Int32 const nStandardSymbol=0;//@todo get from somewhere
767
0
            std::optional<Graphic> oAutoSymbolGraphic(std::in_place, aViewElementListProvider.GetSymbolGraphic( nStandardSymbol, &aSymbolShapeProperties ) );
768
            // note: the dialog takes the ownership of pSymbolShapeProperties and pAutoSymbolGraphic
769
0
            aDlgPtr->setSymbolInformation( std::move(aSymbolShapeProperties), std::move(oAutoSymbolGraphic) );
770
0
        }
771
0
        if( aDialogParameter.HasStatisticProperties() )
772
0
        {
773
0
            aDlgPtr->SetAxisMinorStepWidthForErrorBarDecimals(
774
0
                InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( xChartDoc, m_xChartView, rObjectCID ) );
775
0
        }
776
777
        //open the dialog
778
0
        SfxTabDialogController::runAsync(aDlgPtr, [aDlgPtr, xChartDoc, pItemConverter=std::move(pItemConverter),
779
0
                                                   bSuccessOnUnchanged, xUndoGuard=std::move(xUndoGuard)] (int nResult)
780
0
        {
781
0
            if (nResult == RET_OK || (bSuccessOnUnchanged && aDlgPtr->DialogWasClosedWithOK())) {
782
0
                const SfxItemSet* pOutItemSet = aDlgPtr->GetOutputItemSet();
783
0
                if(pOutItemSet) {
784
0
                    ControllerLockGuardUNO aCLGuard(xChartDoc);
785
0
                    (void)pItemConverter->ApplyItemSet(*pOutItemSet); //model should be changed now
786
0
                    xUndoGuard->commit();
787
0
                }
788
0
            }
789
0
        });
790
0
    }
791
0
    catch( const util::CloseVetoException& )
792
0
    {
793
0
    }
794
0
    catch( const uno::RuntimeException& )
795
0
    {
796
0
    }
797
0
}
798
799
void ChartController::executeDispatch_View3D()
800
0
{
801
0
    try
802
0
    {
803
0
        UndoLiveUpdateGuard aUndoGuard(
804
0
            SchResId( STR_ACTION_EDIT_3D_VIEW ),
805
0
            m_xUndoManager );
806
807
        //open dialog
808
0
        SolarMutexGuard aSolarGuard;
809
0
        View3DDialog aDlg(GetChartFrame(), getChartModel());
810
0
        if (aDlg.run() == RET_OK)
811
0
            aUndoGuard.commit();
812
0
    }
813
0
    catch(const uno::RuntimeException&)
814
0
    {
815
0
        TOOLS_WARN_EXCEPTION("chart2", "" );
816
0
    }
817
0
}
818
819
} //namespace chart
820
821
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */