Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/controller/main/ControllerCommandDispatch.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 <sal/config.h>
21
22
#include <ControllerCommandDispatch.hxx>
23
#include <ChartModel.hxx>
24
#include <Diagram.hxx>
25
#include <Axis.hxx>
26
#include <AxisHelper.hxx>
27
#include <TitleHelper.hxx>
28
#include <LegendHelper.hxx>
29
#include <ObjectIdentifier.hxx>
30
#include <ChartType.hxx>
31
#include <ChartController.hxx>
32
#include <RegressionCurveHelper.hxx>
33
#include <DataSeries.hxx>
34
#include <DataSeriesHelper.hxx>
35
#include <StatisticsHelper.hxx>
36
#include <ReferenceSizeProvider.hxx>
37
#include <RegressionCurveModel.hxx>
38
#include "ShapeController.hxx"
39
#include <CharacterProperties.hxx>
40
41
#include <vcl/svapp.hxx>
42
#include <sal/log.hxx>
43
#include <comphelper/diagnose_ex.hxx>
44
#include <comphelper/lok.hxx>
45
#include <sfx2/viewsh.hxx>
46
#include <sfx2/objsh.hxx>
47
48
#include <com/sun/star/chart2/XDataProviderAccess.hpp>
49
#include <com/sun/star/frame/status/FontHeight.hpp>
50
51
using namespace ::com::sun::star;
52
53
using ::com::sun::star::uno::Reference;
54
using ::com::sun::star::uno::Sequence;
55
56
namespace
57
{
58
uno::Any getPropertyIfSame(std::vector<Reference<beans::XPropertySet>>& xProperties,
59
                           const OUString& aPropName)
60
0
{
61
0
    if (xProperties.size() < 1)
62
0
        return {};
63
64
0
    if (!xProperties[0])
65
0
        return {};
66
67
0
    uno::Any aValue = xProperties[0]->getPropertyValue(aPropName);
68
0
    for (std::size_t i = 1; i < xProperties.size(); i++)
69
0
    {
70
0
        if (xProperties[i] && aValue != xProperties[i]->getPropertyValue(aPropName))
71
0
            return {};
72
0
    }
73
0
    return aValue;
74
0
}
75
76
} // anonymous namespace
77
78
namespace chart
79
{
80
81
namespace impl
82
{
83
84
/// Constants for moving the series.
85
namespace {
86
    bool const MOVE_SERIES_FORWARD = true;
87
    bool const MOVE_SERIES_BACKWARD = false;
88
}
89
90
/** Represents the current state of the controller (needed for issue 63017).
91
92
    You can set the state by calling update().  After this call the state is
93
    preserved in this class until the next call to update().
94
95
    This is useful, not to say necessary, for enabling and disabling of menu
96
    entries (e.g. format>arrangement). As the status requests are sent very
97
    frequently it would be impossible, from a performance point of view, to
98
    query the current status every time directly at the model.  So this class
99
    serves as a cache for the state.
100
*/
101
struct ControllerState
102
{
103
    ControllerState();
104
105
    void update( const Reference< frame::XController > & xController,
106
                 const rtl::Reference<::chart::ChartModel> & xModel );
107
108
    // -- State variables -------
109
    bool bHasSelectedObject;
110
    bool bIsPositionableObject;
111
    bool bIsTextObject;
112
    bool bIsDeleteableObjectSelected;
113
    bool bIsFormateableObjectSelected;
114
115
    // May the selected series be moved forward or backward (cf
116
    // format>arrangement).
117
    bool bMayMoveSeriesForward;
118
    bool bMayMoveSeriesBackward;
119
120
    // trendlines
121
    bool bMayAddMenuTrendline;
122
    bool bMayAddTrendline;
123
    bool bMayAddTrendlineEquation;
124
    bool bMayAddR2Value;
125
    bool bMayAddMeanValue;
126
    bool bMayAddXErrorBars;
127
    bool bMayAddYErrorBars;
128
129
    bool bMayDeleteTrendline;
130
    bool bMayDeleteTrendlineEquation;
131
    bool bMayDeleteR2Value;
132
    bool bMayDeleteMeanValue;
133
    bool bMayDeleteXErrorBars;
134
    bool bMayDeleteYErrorBars;
135
136
    bool bMayFormatTrendline;
137
    bool bMayFormatTrendlineEquation;
138
    bool bMayFormatMeanValue;
139
    bool bMayFormatXErrorBars;
140
    bool bMayFormatYErrorBars;
141
};
142
143
ControllerState::ControllerState() :
144
0
        bHasSelectedObject( false ),
145
0
        bIsPositionableObject( false ),
146
0
        bIsTextObject(false),
147
0
        bIsDeleteableObjectSelected(false),
148
0
        bIsFormateableObjectSelected(false),
149
0
        bMayMoveSeriesForward( false ),
150
0
        bMayMoveSeriesBackward( false ),
151
0
        bMayAddMenuTrendline( false ),
152
0
        bMayAddTrendline( false ),
153
0
        bMayAddTrendlineEquation( false ),
154
0
        bMayAddR2Value( false ),
155
0
        bMayAddMeanValue( false ),
156
0
        bMayAddXErrorBars( false ),
157
0
        bMayAddYErrorBars( false ),
158
0
        bMayDeleteTrendline( false ),
159
0
        bMayDeleteTrendlineEquation( false ),
160
0
        bMayDeleteR2Value( false ),
161
0
        bMayDeleteMeanValue( false ),
162
0
        bMayDeleteXErrorBars( false ),
163
0
        bMayDeleteYErrorBars( false ),
164
0
        bMayFormatTrendline( false ),
165
0
        bMayFormatTrendlineEquation( false ),
166
0
        bMayFormatMeanValue( false ),
167
0
        bMayFormatXErrorBars( false ),
168
0
        bMayFormatYErrorBars( false )
169
0
{}
170
171
void ControllerState::update(
172
    const Reference< frame::XController > & xController,
173
    const rtl::Reference<::chart::ChartModel> & xModel )
174
0
{
175
0
    if (!xModel)
176
0
        return;
177
178
0
    Reference< view::XSelectionSupplier > xSelectionSupplier(
179
0
        xController, uno::UNO_QUERY );
180
181
    // Update ControllerState variables.
182
0
    if( !xSelectionSupplier.is())
183
0
        return;
184
185
0
    uno::Any aSelObj( xSelectionSupplier->getSelection() );
186
0
    ObjectIdentifier aSelOID( aSelObj );
187
0
    const OUString& aSelObjCID( aSelOID.getObjectCID() );
188
189
0
    bHasSelectedObject = aSelOID.isValid();
190
191
0
    ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID ));
192
193
0
    bIsPositionableObject = (aObjectType != OBJECTTYPE_DATA_POINT) && aSelOID.isDragableObject();
194
0
    bIsTextObject = aObjectType == OBJECTTYPE_TITLE;
195
196
0
    rtl::Reference< Diagram > xDiagram = xModel->getFirstChartDiagram();
197
0
    bIsFormateableObjectSelected = bHasSelectedObject && aSelOID.isAutoGeneratedObject();
198
0
    if( aObjectType==OBJECTTYPE_DIAGRAM || aObjectType==OBJECTTYPE_DIAGRAM_WALL || aObjectType==OBJECTTYPE_DIAGRAM_FLOOR )
199
0
        bIsFormateableObjectSelected = xDiagram->isSupportingFloorAndWall();
200
201
0
    rtl::Reference< DataSeries > xGivenDataSeries =
202
0
        ObjectIdentifier::getDataSeriesForCID(
203
0
            aSelObjCID, xModel );
204
205
0
    bIsDeleteableObjectSelected = ChartController::isObjectDeleteable( aSelObj );
206
207
0
    bMayMoveSeriesForward = (aObjectType!=OBJECTTYPE_DATA_POINT) && xDiagram && xDiagram->isSeriesMoveable(
208
0
        xGivenDataSeries,
209
0
        MOVE_SERIES_FORWARD );
210
211
0
    bMayMoveSeriesBackward = (aObjectType!=OBJECTTYPE_DATA_POINT) && xDiagram && xDiagram->isSeriesMoveable(
212
0
        xGivenDataSeries,
213
0
        MOVE_SERIES_BACKWARD );
214
215
0
    bMayAddMenuTrendline = false;
216
0
    bMayAddTrendline = false;
217
0
    bMayAddTrendlineEquation = false;
218
0
    bMayAddR2Value = false;
219
0
    bMayAddMeanValue = false;
220
0
    bMayAddXErrorBars = false;
221
0
    bMayAddYErrorBars = false;
222
0
    bMayDeleteTrendline = false;
223
0
    bMayDeleteTrendlineEquation = false;
224
0
    bMayDeleteR2Value = false;
225
0
    bMayDeleteMeanValue = false;
226
0
    bMayDeleteXErrorBars = false;
227
0
    bMayDeleteYErrorBars = false;
228
0
    bMayFormatTrendline = false;
229
0
    bMayFormatTrendlineEquation = false;
230
0
    bMayFormatMeanValue = false;
231
0
    bMayFormatXErrorBars = false;
232
0
    bMayFormatYErrorBars = false;
233
0
    if( !bHasSelectedObject )
234
0
        return;
235
236
0
    if( xGivenDataSeries.is())
237
0
    {
238
0
        bMayAddMenuTrendline = true;
239
0
        sal_Int32 nDimensionCount = xDiagram->getDimension();
240
0
        rtl::Reference< ::chart::ChartType > xFirstChartType(
241
0
            DataSeriesHelper::getChartTypeOfSeries( xGivenDataSeries, xDiagram ));
242
243
        // trend lines/mean value line
244
0
        if( (aObjectType == OBJECTTYPE_DATA_SERIES || aObjectType == OBJECTTYPE_DATA_POINT)
245
0
            && xFirstChartType.is() ? xFirstChartType->isSupportingRegressionProperties(nDimensionCount) : true)
246
0
        {
247
            // Trendline
248
0
            bMayAddTrendline = true;
249
250
            // Mean Value
251
0
            bMayFormatMeanValue = bMayDeleteMeanValue = RegressionCurveHelper::hasMeanValueLine( xGivenDataSeries );
252
0
            bMayAddMeanValue = ! bMayDeleteMeanValue;
253
0
        }
254
255
        // error bars
256
0
        if( (aObjectType == OBJECTTYPE_DATA_SERIES || aObjectType == OBJECTTYPE_DATA_POINT)
257
0
            && xFirstChartType.is() ? xFirstChartType->isSupportingStatisticProperties(nDimensionCount) : true)
258
0
        {
259
0
            bMayFormatXErrorBars = bMayDeleteXErrorBars = StatisticsHelper::hasErrorBars( xGivenDataSeries, false );
260
0
            bMayAddXErrorBars = ! bMayDeleteXErrorBars;
261
262
0
            bMayFormatYErrorBars = bMayDeleteYErrorBars = StatisticsHelper::hasErrorBars( xGivenDataSeries );
263
0
            bMayAddYErrorBars = ! bMayDeleteYErrorBars;
264
0
        }
265
0
    }
266
267
0
    if( aObjectType == OBJECTTYPE_DATA_AVERAGE_LINE )
268
0
        bMayFormatMeanValue = true;
269
270
0
    if( aObjectType == OBJECTTYPE_DATA_ERRORS_X)
271
0
        bMayFormatXErrorBars = true;
272
273
0
    if( aObjectType == OBJECTTYPE_DATA_ERRORS_Y )
274
0
        bMayFormatYErrorBars = true;
275
276
0
    if( aObjectType == OBJECTTYPE_DATA_CURVE )
277
0
    {
278
0
        bMayFormatTrendline = true;
279
0
        bMayDeleteTrendline = true;
280
0
        rtl::Reference< RegressionCurveModel > xRegCurve(
281
0
            dynamic_cast<RegressionCurveModel*>(ObjectIdentifier::getObjectPropertySet( aSelObjCID, xModel ).get()) );
282
283
        // Trendline Equation
284
0
        bMayFormatTrendlineEquation = bMayDeleteTrendlineEquation = RegressionCurveHelper::hasEquation( xRegCurve );
285
0
        bMayAddTrendlineEquation = !bMayDeleteTrendlineEquation;
286
0
        bMayAddR2Value = RegressionCurveHelper::MayHaveCorrelationCoefficient( xRegCurve ) && bMayAddTrendlineEquation;
287
0
    }
288
0
    else if( aObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
289
0
    {
290
0
        bMayFormatTrendlineEquation = true;
291
0
        bool bHasR2Value = false;
292
0
        bool bMayHaveR2 = true;
293
0
        try
294
0
        {
295
0
            uno::Reference< beans::XPropertySet > xEquationProperties =
296
0
                ObjectIdentifier::getObjectPropertySet( aSelObjCID, xModel );
297
0
            if( xEquationProperties.is() )
298
0
            {
299
0
                xEquationProperties->getPropertyValue( u"ShowCorrelationCoefficient"_ustr ) >>= bHasR2Value;
300
0
                xEquationProperties->getPropertyValue( u"MayHaveCorrelationCoefficient"_ustr ) >>= bMayHaveR2;
301
0
            }
302
0
        }
303
0
        catch(const uno::RuntimeException&)
304
0
        {
305
0
            TOOLS_WARN_EXCEPTION("chart2", "" );
306
0
        }
307
0
        bMayAddR2Value = !bHasR2Value && bMayHaveR2;
308
0
        bMayDeleteR2Value = bHasR2Value;
309
0
    }
310
0
}
311
312
/** Represents the current state of the model.
313
314
    You can set the state by calling update().  After this call the state is
315
    preserved in this class until the next call to update().
316
317
    This is useful, not to say necessary, for enabling and disabling of menu
318
    entries and toolbar icons.  As the status requests are sent very frequently
319
    it would be impossible, from a performance point of view, to query the
320
    current status every time directly at the model.  So this class serves as a
321
    cache for the state.
322
 */
323
struct ModelState
324
{
325
    ModelState();
326
327
    void update( const rtl::Reference<::chart::ChartModel> & xModel );
328
329
    bool HasAnyAxis() const;
330
    bool HasAnyGrid() const;
331
    bool HasAnyTitle() const;
332
333
    bool bIsReadOnly;
334
    bool bIsThreeD;
335
    bool bHasOwnData;
336
    bool bHasDataFromPivotTable;
337
338
    bool bHasMainTitle;
339
    bool bHasSubTitle;
340
    bool bHasXAxisTitle;
341
    bool bHasYAxisTitle;
342
    bool bHasZAxisTitle;
343
    bool bHasSecondaryXAxisTitle;
344
    bool bHasSecondaryYAxisTitle;
345
346
    bool bHasXAxis;
347
    bool bHasYAxis;
348
    bool bHasZAxis;
349
    bool bHasAAxis;
350
    bool bHasBAxis;
351
352
    bool bHasMainXGrid;
353
    bool bHasMainYGrid;
354
    bool bHasMainZGrid;
355
    bool bHasHelpXGrid;
356
    bool bHasHelpYGrid;
357
    bool bHasHelpZGrid;
358
359
    bool bHasAutoScaledText;
360
    bool bHasLegend;
361
    bool bHasWall;
362
    bool bHasFloor;
363
364
    bool bSupportsStatistics;
365
    bool bSupportsAxes;
366
367
    bool bDataTable = false;
368
};
369
370
ModelState::ModelState() :
371
0
        bIsReadOnly(true),
372
0
        bIsThreeD(false),
373
0
        bHasOwnData(false),
374
0
        bHasDataFromPivotTable(false),
375
0
        bHasMainTitle(false),
376
0
        bHasSubTitle(false),
377
0
        bHasXAxisTitle(false),
378
0
        bHasYAxisTitle(false),
379
0
        bHasZAxisTitle(false),
380
0
        bHasSecondaryXAxisTitle(false),
381
0
        bHasSecondaryYAxisTitle(false),
382
0
        bHasXAxis(false),
383
0
        bHasYAxis(false),
384
0
        bHasZAxis(false),
385
0
        bHasAAxis(false),
386
0
        bHasBAxis(false),
387
0
        bHasMainXGrid(false),
388
0
        bHasMainYGrid(false),
389
0
        bHasMainZGrid(false),
390
0
        bHasHelpXGrid(false),
391
0
        bHasHelpYGrid(false),
392
0
        bHasHelpZGrid(false),
393
0
        bHasAutoScaledText(false),
394
0
        bHasLegend(false),
395
0
        bHasWall(false),
396
0
        bHasFloor(false),
397
0
        bSupportsStatistics(false),
398
0
        bSupportsAxes(false)
399
0
{}
400
401
void ModelState::update( const rtl::Reference<::chart::ChartModel> & xModel )
402
0
{
403
0
    rtl::Reference< Diagram > xDiagram = xModel->getFirstChartDiagram();
404
405
0
    bIsReadOnly = xModel->isReadonly();
406
407
0
    sal_Int32 nDimensionCount = 0;
408
0
    if (xDiagram)
409
0
        nDimensionCount = xDiagram->getDimension();
410
411
0
    rtl::Reference<ChartType> xFirstChartType;
412
0
    if (xDiagram)
413
0
        xFirstChartType = xDiagram->getChartTypeByIndex( 0 );
414
0
    bSupportsStatistics = xFirstChartType.is() ?  xFirstChartType->isSupportingStatisticProperties(nDimensionCount) : true;
415
0
    bSupportsAxes = xFirstChartType.is() ?  xFirstChartType->isSupportingMainAxis(nDimensionCount, 0) : true;
416
417
0
    bIsThreeD = (nDimensionCount == 3);
418
0
    if (xModel.is())
419
0
    {
420
0
        bHasOwnData = xModel->hasInternalDataProvider();
421
0
        bHasDataFromPivotTable = !bHasOwnData && xModel->isDataFromPivotTable();
422
0
    }
423
424
0
    bHasMainTitle =  TitleHelper::getTitle( TitleHelper::MAIN_TITLE, xModel ).is();
425
0
    bHasSubTitle =   TitleHelper::getTitle( TitleHelper::SUB_TITLE, xModel ).is();
426
0
    bHasXAxisTitle = TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, xModel ).is();
427
0
    bHasYAxisTitle = TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, xModel ).is();
428
0
    bHasZAxisTitle = TitleHelper::getTitle( TitleHelper::Z_AXIS_TITLE, xModel ).is();
429
0
    bHasSecondaryXAxisTitle = TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xModel ).is();
430
0
    bHasSecondaryYAxisTitle = TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xModel ).is();
431
432
0
    bHasXAxis = bSupportsAxes && AxisHelper::getAxis( 0, true, xDiagram ).is();
433
0
    bHasYAxis = bSupportsAxes && AxisHelper::getAxis( 1, true, xDiagram ).is();
434
0
    bHasZAxis = bSupportsAxes && AxisHelper::getAxis( 2, true, xDiagram ).is();
435
0
    bHasAAxis = bSupportsAxes && AxisHelper::getAxis( 0, false, xDiagram ).is();
436
0
    bHasBAxis = bSupportsAxes && AxisHelper::getAxis( 1, false, xDiagram ).is();
437
438
0
    bHasMainXGrid = bSupportsAxes && AxisHelper::isGridShown( 0, 0, true, xDiagram );
439
0
    bHasMainYGrid = bSupportsAxes && AxisHelper::isGridShown( 1, 0, true, xDiagram );
440
0
    bHasMainZGrid = bSupportsAxes && AxisHelper::isGridShown( 2, 0, true, xDiagram );
441
0
    bHasHelpXGrid = bSupportsAxes && AxisHelper::isGridShown( 0, 0, false, xDiagram );
442
0
    bHasHelpYGrid = bSupportsAxes && AxisHelper::isGridShown( 1, 0, false, xDiagram );
443
0
    bHasHelpZGrid = bSupportsAxes && AxisHelper::isGridShown( 2, 0, false, xDiagram );
444
445
0
    bHasAutoScaledText =
446
0
        (ReferenceSizeProvider::getAutoResizeState( xModel ) ==
447
0
         ReferenceSizeProvider::AUTO_RESIZE_YES);
448
449
0
    bHasLegend = LegendHelper::hasLegend( xDiagram );
450
0
    bHasWall = xDiagram && xDiagram->isSupportingFloorAndWall();
451
0
    bHasFloor = bHasWall && bIsThreeD;
452
453
0
    bDataTable = xDiagram.is() && xDiagram->getDataTable().is();
454
0
}
455
456
bool ModelState::HasAnyAxis() const
457
0
{
458
0
    return bHasXAxis || bHasYAxis || bHasZAxis || bHasAAxis || bHasBAxis;
459
0
}
460
461
bool ModelState::HasAnyGrid() const
462
0
{
463
0
    return bHasMainXGrid || bHasMainYGrid || bHasMainZGrid ||
464
0
        bHasHelpXGrid || bHasHelpYGrid || bHasHelpZGrid;
465
0
}
466
467
bool ModelState::HasAnyTitle() const
468
0
{
469
0
    return bHasMainTitle || bHasSubTitle || bHasXAxisTitle || bHasYAxisTitle || bHasZAxisTitle || bHasSecondaryXAxisTitle || bHasSecondaryYAxisTitle;
470
0
}
471
472
} // namespace impl
473
474
ControllerCommandDispatch::ControllerCommandDispatch(
475
    const Reference< uno::XComponentContext > & xContext,
476
    ChartController* pController, CommandDispatchContainer* pContainer ) :
477
0
        impl::ControllerCommandDispatch_Base( xContext ),
478
0
        m_xChartController( pController ),
479
0
        m_xSelectionSupplier( Reference< view::XSelectionSupplier >( pController ) ),
480
0
        m_xDispatch( Reference< frame::XDispatch >( pController ) ),
481
0
        m_apModelState( new impl::ModelState() ),
482
0
        m_apControllerState( new impl::ControllerState() ),
483
0
        m_pDispatchContainer( pContainer )
484
0
{
485
0
}
Unexecuted instantiation: chart::ControllerCommandDispatch::ControllerCommandDispatch(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, chart::ChartController*, chart::CommandDispatchContainer*)
Unexecuted instantiation: chart::ControllerCommandDispatch::ControllerCommandDispatch(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, chart::ChartController*, chart::CommandDispatchContainer*)
486
487
ControllerCommandDispatch::~ControllerCommandDispatch()
488
0
{
489
0
}
490
491
void ControllerCommandDispatch::initialize()
492
0
{
493
0
    if( !m_xChartController.is())
494
0
        return;
495
496
0
    rtl::Reference<::chart::ChartModel> xModel( m_xChartController->getChartModel());
497
0
    OSL_ASSERT( xModel.is());
498
0
    if( xModel.is())
499
0
        xModel->addModifyListener( this );
500
501
    // Listen selection modifications (Arrangement feature - issue 63017).
502
0
    if( m_xSelectionSupplier.is() )
503
0
        m_xSelectionSupplier->addSelectionChangeListener( this );
504
505
0
    if( m_apModelState && xModel.is())
506
0
        m_apModelState->update( xModel );
507
508
0
    if( m_apControllerState && xModel.is())
509
0
        m_apControllerState->update( m_xChartController, xModel );
510
511
0
    updateCommandAvailability();
512
0
}
513
514
void ControllerCommandDispatch::fireStatusEventForURLImpl(
515
    const OUString & rURL,
516
    const Reference< frame::XStatusListener > & xSingleListener )
517
0
{
518
0
    std::map< OUString, uno::Any >::const_iterator aArgIt( m_aCommandArguments.find( rURL ));
519
0
    if( aArgIt != m_aCommandArguments.end())
520
0
        fireStatusEventForURL( rURL, aArgIt->second, commandAvailable( rURL ), xSingleListener );
521
0
    else
522
0
        fireStatusEventForURL( rURL, uno::Any(), commandAvailable( rURL ), xSingleListener );
523
0
}
524
525
void ControllerCommandDispatch::updateCommandAvailability()
526
0
{
527
0
    bool bModelStateIsValid = (m_apModelState != nullptr);
528
0
    bool bControllerStateIsValid = (m_apControllerState != nullptr);
529
    // Model and controller states exist.
530
0
    OSL_ASSERT( bModelStateIsValid );
531
0
    OSL_ASSERT( bControllerStateIsValid );
532
533
    // read-only
534
0
    bool bIsWritable = bModelStateIsValid && (! m_apModelState->bIsReadOnly);
535
0
    bool bShapeContext = m_xChartController.is() && m_xChartController->isShapeContext();
536
0
    bool bIsTextEdit = m_xChartController.is() && m_xChartController->IsTextEdit();
537
538
0
    bool bEnableDataTableDialog = false;
539
0
    bool bCanCreateDataProvider = false;
540
541
0
    if ( m_xChartController.is() )
542
0
    {
543
0
        Reference< beans::XPropertySet > xProps( m_xChartController->getModel(), uno::UNO_QUERY );
544
0
        if ( xProps.is() )
545
0
        {
546
0
            try
547
0
            {
548
0
                xProps->getPropertyValue(u"EnableDataTableDialog"_ustr) >>= bEnableDataTableDialog;
549
0
            }
550
0
            catch( const uno::Exception& )
551
0
            {
552
0
                TOOLS_WARN_EXCEPTION("chart2", "" );
553
0
            }
554
0
        }
555
556
0
        rtl::Reference< ChartModel > xChartModel = m_xChartController->getChartModel();
557
0
        OSL_ENSURE(xChartModel.is(), "Invalid XChartDocument");
558
0
        if ( xChartModel.is() )
559
0
        {
560
0
            css::uno::Reference< css::chart2::XDataProviderAccess > xCreatorDoc(xChartModel->getParent(), uno::UNO_QUERY);
561
0
            bCanCreateDataProvider = xCreatorDoc.is();
562
0
        }
563
0
    }
564
565
    // edit commands
566
0
    m_aCommandAvailability[ u".uno:Cut"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsDeleteableObjectSelected;
567
0
    m_aCommandAvailability[ u".uno:Copy"_ustr ] = bControllerStateIsValid && m_apControllerState->bHasSelectedObject;
568
0
    m_aCommandAvailability[ u".uno:Paste"_ustr ] = bIsWritable;
569
570
    // toolbar commands
571
0
    m_aCommandAvailability[ u".uno:ToggleGridHorizontal"_ustr ] = bIsWritable;
572
0
    m_aCommandArguments[ u".uno:ToggleGridHorizontal"_ustr ] <<= bModelStateIsValid && m_apModelState->bHasMainYGrid;
573
0
    m_aCommandAvailability[ u".uno:ToggleGridVertical"_ustr ] = bIsWritable;
574
0
    m_aCommandArguments[ u".uno:ToggleGridVertical"_ustr ] <<= bModelStateIsValid && m_apModelState->bHasMainXGrid;
575
576
0
    m_aCommandAvailability[ u".uno:ToggleLegend"_ustr ] = bIsWritable;
577
0
    m_aCommandArguments[ u".uno:ToggleLegend"_ustr ] <<= bModelStateIsValid && m_apModelState->bHasLegend;
578
579
0
    m_aCommandAvailability[ u".uno:NewArrangement"_ustr ] = bIsWritable;
580
0
    m_aCommandAvailability[ u".uno:Update"_ustr ] = bIsWritable;
581
0
    m_aCommandAvailability[ u".uno:DefaultColors"_ustr ] = bIsWritable;
582
0
    m_aCommandAvailability[ u".uno:BarWidth"_ustr ] = bIsWritable;
583
0
    m_aCommandAvailability[ u".uno:NumberOfLines"_ustr ] = bIsWritable;
584
0
    m_aCommandAvailability[ u".uno:ArrangeRow"_ustr ] =
585
0
        bShapeContext || ( bIsWritable && bControllerStateIsValid && ( m_apControllerState->bMayMoveSeriesForward || m_apControllerState->bMayMoveSeriesBackward ) );
586
587
    // insert objects
588
0
    m_aCommandAvailability[ u".uno:InsertTitles"_ustr ] = m_aCommandAvailability[ u".uno:InsertMenuTitles"_ustr ] = bIsWritable;
589
0
    m_aCommandAvailability[ u".uno:InsertLegend"_ustr ] = m_aCommandAvailability[ u".uno:InsertMenuLegend"_ustr ] = bIsWritable;
590
0
    m_aCommandAvailability[ u".uno:DeleteLegend"_ustr ] = bIsWritable;
591
0
    m_aCommandAvailability[ u".uno:InsertMenuDataLabels"_ustr ] = bIsWritable;
592
0
    m_aCommandAvailability[ u".uno:InsertRemoveAxes"_ustr ] = m_aCommandAvailability[ u".uno:InsertMenuAxes"_ustr ] = bIsWritable && m_apModelState->bSupportsAxes;
593
0
    m_aCommandAvailability[ u".uno:InsertMenuGrids"_ustr ] = bIsWritable && m_apModelState->bSupportsAxes;
594
0
    m_aCommandAvailability[ u".uno:InsertMenuTrendlines"_ustr ] = bIsWritable && m_apModelState->bSupportsStatistics && bControllerStateIsValid && m_apControllerState->bMayAddMenuTrendline;
595
0
    m_aCommandAvailability[ u".uno:InsertMenuMeanValues"_ustr ] = bIsWritable && m_apModelState->bSupportsStatistics;
596
0
    m_aCommandAvailability[ u".uno:InsertMenuXErrorBars"_ustr ] = bIsWritable && m_apModelState->bSupportsStatistics;
597
0
    m_aCommandAvailability[ u".uno:InsertMenuYErrorBars"_ustr ] = bIsWritable && m_apModelState->bSupportsStatistics;
598
0
    m_aCommandAvailability[ u".uno:InsertSymbol"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsTextObject;
599
0
    m_aCommandAvailability[ u".uno:InsertMenuDataTable"_ustr ] = bIsWritable;
600
601
    // format objects
602
0
    bool bFormatObjectAvailable = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsFormateableObjectSelected;
603
0
    m_aCommandAvailability[ u".uno:FormatSelection"_ustr ] = bFormatObjectAvailable && !bIsTextEdit;
604
0
    m_aCommandAvailability[ u".uno:FontDialog"_ustr ] = (bShapeContext ? isShapeControllerCommandAvailable(u".uno:FontDialog"_ustr) :
605
0
        bFormatObjectAvailable) && bIsTextEdit;
606
0
    m_aCommandAvailability[ u".uno:FormatAxis"_ustr ] = bFormatObjectAvailable;
607
0
    m_aCommandAvailability[ u".uno:FormatTitle"_ustr ] = bFormatObjectAvailable && !bIsTextEdit;
608
0
    m_aCommandAvailability[ u".uno:FormatDataSeries"_ustr ] = bFormatObjectAvailable;
609
0
    m_aCommandAvailability[ u".uno:FormatDataPoint"_ustr ] = bFormatObjectAvailable;
610
0
    m_aCommandAvailability[ u".uno:FormatDataLabels"_ustr ] = bFormatObjectAvailable;
611
0
    m_aCommandAvailability[ u".uno:FormatDataLabel"_ustr ] = bFormatObjectAvailable;
612
0
    m_aCommandAvailability[ u".uno:FormatXErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatXErrorBars;
613
0
    m_aCommandAvailability[ u".uno:FormatYErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatYErrorBars;
614
0
    m_aCommandAvailability[ u".uno:FormatMeanValue"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatMeanValue;
615
0
    m_aCommandAvailability[ u".uno:FormatTrendline"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayFormatTrendline;
616
0
    m_aCommandAvailability[ u".uno:FormatTrendlineEquation"_ustr ] = bFormatObjectAvailable && bControllerStateIsValid && m_apControllerState->bMayFormatTrendlineEquation;
617
0
    m_aCommandAvailability[ u".uno:FormatStockLoss"_ustr ] = bFormatObjectAvailable;
618
0
    m_aCommandAvailability[ u".uno:FormatStockGain"_ustr ] = bFormatObjectAvailable;
619
0
    if (comphelper::LibreOfficeKit::isActive())
620
0
    {
621
0
        m_aCommandAvailability[u".uno:FillColor"_ustr] = bFormatObjectAvailable;
622
0
        m_aCommandAvailability[u".uno:XLineColor"_ustr] = bFormatObjectAvailable;
623
0
        m_aCommandAvailability[u".uno:LineWidth"_ustr] = bFormatObjectAvailable;
624
0
        m_aCommandAvailability[u".uno:FillGradient"_ustr] = bFormatObjectAvailable;
625
0
    }
626
627
0
    m_aCommandAvailability[ u".uno:DiagramType"_ustr ] = bIsWritable;
628
0
    m_aCommandAvailability[ u".uno:Legend"_ustr ] = bIsWritable && m_apModelState->bHasLegend;
629
0
    m_aCommandAvailability[ u".uno:DiagramWall"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasWall;
630
0
    m_aCommandAvailability[ u".uno:DiagramArea"_ustr ] = bIsWritable;
631
632
0
    m_aCommandAvailability[ u".uno:TransformDialog"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bHasSelectedObject && m_apControllerState->bIsPositionableObject;
633
634
    // 3d commands
635
0
    m_aCommandAvailability[ u".uno:View3D"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bIsThreeD;
636
0
    m_aCommandAvailability[ u".uno:DiagramFloor"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasFloor;
637
638
    //some more format commands with different ui text
639
0
    m_aCommandAvailability[ u".uno:FormatWall"_ustr ] = m_aCommandAvailability[ u".uno:DiagramWall"_ustr ];
640
0
    m_aCommandAvailability[ u".uno:FormatFloor"_ustr ] = m_aCommandAvailability[ u".uno:DiagramFloor"_ustr ];
641
0
    m_aCommandAvailability[ u".uno:FormatChartArea"_ustr ] = m_aCommandAvailability[ u".uno:DiagramArea"_ustr ];
642
0
    m_aCommandAvailability[ u".uno:FormatLegend"_ustr ] = m_aCommandAvailability[ u".uno:Legend"_ustr ];
643
644
    // depending on own data and ability to create new data provider
645
0
    m_aCommandAvailability[u".uno:DataRanges"_ustr] = bIsWritable && bModelStateIsValid && !m_apModelState->bHasDataFromPivotTable
646
0
        && ((m_apModelState->bHasOwnData && bCanCreateDataProvider) || !m_apModelState->bHasOwnData);
647
0
    m_aCommandAvailability[ u".uno:DiagramData"_ustr ] = bIsWritable && bModelStateIsValid &&  m_apModelState->bHasOwnData && bEnableDataTableDialog;
648
649
    // titles
650
0
    m_aCommandAvailability[ u".uno:MainTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainTitle;
651
0
    m_aCommandAvailability[ u".uno:SubTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSubTitle;
652
0
    m_aCommandAvailability[ u".uno:XTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasXAxisTitle;
653
0
    m_aCommandAvailability[ u".uno:YTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasYAxisTitle;
654
0
    m_aCommandAvailability[ u".uno:ZTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasZAxisTitle;
655
0
    m_aCommandAvailability[ u".uno:SecondaryXTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSecondaryXAxisTitle;
656
0
    m_aCommandAvailability[ u".uno:SecondaryYTitle"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasSecondaryYAxisTitle;
657
0
    m_aCommandAvailability[ u".uno:AllTitles"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyTitle();
658
659
    // text
660
0
    m_aCommandAvailability[ u".uno:ScaleText"_ustr ] = bIsWritable && bModelStateIsValid ;
661
0
    m_aCommandArguments[ u".uno:ScaleText"_ustr ] <<= bModelStateIsValid && m_apModelState->bHasAutoScaledText;
662
663
0
    bool bTitleIsInEditMode = false;
664
0
    try
665
0
    {
666
0
        OUString aObjectCID2 = m_xChartController->getSelectionMember().getSelectedCID();
667
0
        if (!aObjectCID2.isEmpty())
668
0
            if (ObjectIdentifier::getObjectType(aObjectCID2) == OBJECTTYPE_TITLE)
669
0
                if (m_xChartController->GetDrawViewWrapper())
670
0
                    if (m_xChartController->GetDrawViewWrapper()->GetTextEditOutlinerView())
671
0
                        bTitleIsInEditMode = true;
672
0
    }
673
0
    catch (const uno::Exception&) { TOOLS_WARN_EXCEPTION("chart2", ""); }
674
675
0
    bool bEnableUnoCommands = bIsWritable && bModelStateIsValid && !bTitleIsInEditMode;
676
0
    m_aCommandAvailability[u".uno:Bold"_ustr] = bEnableUnoCommands;
677
0
    m_aCommandAvailability[u".uno:Strikeout"_ustr] = bEnableUnoCommands;
678
0
    m_aCommandAvailability[u".uno:CharFontName"_ustr] = bEnableUnoCommands;
679
0
    m_aCommandAvailability[u".uno:FontHeight"_ustr] = bEnableUnoCommands;
680
0
    m_aCommandAvailability[u".uno:Italic"_ustr] = bEnableUnoCommands;
681
0
    m_aCommandAvailability[u".uno:Underline"_ustr] = bEnableUnoCommands;
682
0
    m_aCommandAvailability[u".uno:Shadowed"_ustr] = bEnableUnoCommands;
683
0
    m_aCommandAvailability[u".uno:Color"_ustr] = bEnableUnoCommands;
684
0
    m_aCommandAvailability[u".uno:FontColor"_ustr] = bEnableUnoCommands;
685
0
    m_aCommandAvailability[u".uno:Grow"_ustr] = bEnableUnoCommands;
686
0
    m_aCommandAvailability[u".uno:Shrink"_ustr] = bEnableUnoCommands;
687
0
    m_aCommandAvailability[u".uno:SuperScript"_ustr] = bEnableUnoCommands;
688
0
    m_aCommandAvailability[u".uno:SubScript"_ustr] = bEnableUnoCommands;
689
0
    m_aCommandAvailability[u".uno:Spacing"_ustr] = bEnableUnoCommands;
690
0
    m_aCommandAvailability[u".uno:ResetAttributes"_ustr] = bEnableUnoCommands;
691
692
0
    if (!bTitleIsInEditMode)
693
0
    {
694
        // at default they are not filled in the sidebar
695
0
        m_aCommandArguments[u".uno:CharFontName"_ustr] <<= false;
696
0
        m_aCommandArguments[u".uno:FontHeight"_ustr] <<= false;
697
0
        m_aCommandArguments[u".uno:Bold"_ustr] <<= false;
698
0
        m_aCommandArguments[u".uno:Strikeout"_ustr] <<= false;
699
0
        m_aCommandArguments[u".uno:Italic"_ustr] <<= false;
700
0
        m_aCommandArguments[u".uno:Underline"_ustr] <<= false;
701
0
        m_aCommandArguments[u".uno:Shadowed"_ustr] <<= false;
702
0
        m_aCommandArguments[u".uno:Color"_ustr] <<= false;
703
0
        m_aCommandArguments[u".uno:FontColor"_ustr] <<= false;
704
0
        m_aCommandArguments[u".uno:SuperScript"_ustr] <<= false;
705
0
        m_aCommandArguments[u".uno:SubScript"_ustr] <<= false;
706
0
        m_aCommandArguments[u".uno:Spacing"_ustr] <<= false;
707
0
        m_aCommandArguments[u".uno:ResetAttributes"_ustr] <<= false;
708
0
    }
709
710
    // They are filled based on the text properties.. if there are only 1
711
    // but only those properties that are true for the whole text
712
0
    try
713
0
    {
714
        // if title is selected, and in edit mode, then the font panel should be disabled
715
        // enable the uno commands only if the title is not in edit mode
716
        // Todo: enable font panel here if the panel will be able to handle edited title.
717
0
        OUString aObjectCID = m_xChartController->getSelectionMember().getSelectedCID();
718
0
        if (!aObjectCID.isEmpty() && !bTitleIsInEditMode)
719
0
        {
720
            // If the selected is not title, then we should check the text properties..
721
            // or the selected text properties?
722
0
            std::vector<Reference<beans::XPropertySet>> xProperties;
723
0
            xProperties.emplace(xProperties.end(),
724
0
                                ObjectIdentifier::getObjectPropertySet(
725
0
                                    aObjectCID, m_xChartController->getChartModel()));
726
727
0
            if (ObjectIdentifier::getObjectType(aObjectCID) == OBJECTTYPE_TITLE)
728
0
            {
729
0
                Reference<chart2::XTitle> xTitle(xProperties[0], uno::UNO_QUERY);
730
0
                if (xTitle.is())
731
0
                {
732
0
                    const Sequence<Reference<chart2::XFormattedString>> aStrings(xTitle->getText());
733
0
                    xProperties.pop_back();
734
0
                    for (const auto& aString : aStrings)
735
0
                    {
736
0
                        Reference<beans::XPropertySet> xTitlePropSet(aString, uno::UNO_QUERY);
737
0
                        xProperties.push_back(xTitlePropSet);
738
0
                    }
739
0
                }
740
0
            }
741
742
0
            Reference<beans::XMultiPropertySet> aMObjProps(xProperties[0], uno::UNO_QUERY);
743
0
            if (aMObjProps)
744
0
            {
745
0
                awt::FontDescriptor aFont
746
0
                    = CharacterProperties::createFontDescriptorFromPropertySet(aMObjProps);
747
748
0
                if (!aFont.Name.isEmpty())
749
0
                {
750
0
                    if (getPropertyIfSame(xProperties, u"CharFontName"_ustr).hasValue())
751
0
                    {
752
0
                        m_aCommandArguments[u".uno:CharFontName"_ustr] <<= aFont;
753
0
                    }
754
0
                }
755
0
            }
756
0
            if (frame::status::FontHeight aFontHeight;
757
0
                getPropertyIfSame(xProperties, u"CharHeight"_ustr) >>= aFontHeight.Height)
758
0
            {
759
                // another type is needed here, so
760
0
                m_aCommandArguments[u".uno:FontHeight"_ustr] <<= aFontHeight;
761
0
            }
762
763
0
            if (float nFontWeight;
764
0
                getPropertyIfSame(xProperties, u"CharWeight"_ustr) >>= nFontWeight)
765
0
            {
766
0
                bool bFontWeight = (nFontWeight > 100.0);
767
0
                m_aCommandArguments[u".uno:Bold"_ustr] <<= bFontWeight;
768
0
            }
769
770
0
            if (awt::FontSlant nFontItalic;
771
0
                getPropertyIfSame(xProperties, u"CharPosture"_ustr) >>= nFontItalic)
772
0
            {
773
0
                bool bItalic = (nFontItalic == awt::FontSlant_ITALIC);
774
0
                m_aCommandArguments[u".uno:Italic"_ustr] <<= bItalic;
775
0
            }
776
777
0
            if (sal_Int16 nFontStrikeout;
778
0
                getPropertyIfSame(xProperties, u"CharStrikeout"_ustr) >>= nFontStrikeout)
779
0
            {
780
0
                bool bFontStrikeout = (nFontStrikeout > 0);
781
0
                m_aCommandArguments[u".uno:Strikeout"_ustr] <<= bFontStrikeout;
782
0
            }
783
784
0
            if (sal_Int16 nFontUnderline;
785
0
                getPropertyIfSame(xProperties, u"CharUnderline"_ustr) >>= nFontUnderline)
786
0
            {
787
0
                bool bFontUnderline = (nFontUnderline > 0);
788
0
                m_aCommandArguments[u".uno:Underline"_ustr] <<= bFontUnderline;
789
0
            }
790
791
0
            if (bool bShadowed; getPropertyIfSame(xProperties, u"CharShadowed"_ustr) >>= bShadowed)
792
0
            {
793
0
                m_aCommandArguments[u".uno:Shadowed"_ustr] <<= bShadowed;
794
0
            }
795
796
            // Font color is not set in panel... it is just enabled to use
797
0
            m_aCommandArguments[u".uno:Color"_ustr] <<= false;
798
0
            m_aCommandArguments[u".uno:FontColor"_ustr] <<= false;
799
800
0
            if (sal_Int32 nCharEscapement;
801
0
                getPropertyIfSame(xProperties, u"CharEscapement"_ustr) >>= nCharEscapement)
802
0
            {
803
0
                m_aCommandArguments[u".uno:SuperScript"_ustr] <<= (nCharEscapement > 0);
804
0
                m_aCommandArguments[u".uno:SubScript"_ustr] <<= (nCharEscapement < 0);
805
0
            }
806
807
            // Font Spacing is not set in panel... it is just enabled to use
808
0
            m_aCommandArguments[u".uno:Spacing"_ustr] <<= false;
809
0
        }
810
0
    }
811
0
    catch (const uno::Exception&)
812
0
    {
813
0
        TOOLS_WARN_EXCEPTION("chart2", "");
814
0
    }
815
816
    // axes
817
0
    m_aCommandAvailability[ u".uno:DiagramAxisX"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasXAxis;
818
0
    m_aCommandAvailability[ u".uno:DiagramAxisY"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasYAxis;
819
0
    m_aCommandAvailability[ u".uno:DiagramAxisZ"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasZAxis;
820
0
    m_aCommandAvailability[ u".uno:DiagramAxisA"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasAAxis;
821
0
    m_aCommandAvailability[ u".uno:DiagramAxisB"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasBAxis;
822
0
    m_aCommandAvailability[ u".uno:DiagramAxisAll"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyAxis();
823
824
    // grids
825
    // note: x and y are swapped in the commands!
826
0
    m_aCommandAvailability[ u".uno:DiagramGridYMain"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainXGrid;
827
0
    m_aCommandAvailability[ u".uno:DiagramGridXMain"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainYGrid;
828
0
    m_aCommandAvailability[ u".uno:DiagramGridZMain"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainZGrid;
829
0
    m_aCommandAvailability[ u".uno:DiagramGridYHelp"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpXGrid;
830
0
    m_aCommandAvailability[ u".uno:DiagramGridXHelp"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpYGrid;
831
0
    m_aCommandAvailability[ u".uno:DiagramGridZHelp"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bHasHelpZGrid;
832
0
    m_aCommandAvailability[ u".uno:DiagramGridAll"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->HasAnyGrid();
833
834
    // series arrangement
835
0
    m_aCommandAvailability[ u".uno:Forward"_ustr ] = ( bShapeContext ? isShapeControllerCommandAvailable( u".uno:Forward"_ustr ) :
836
0
        ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward && bEnableDataTableDialog ) );
837
0
    m_aCommandAvailability[ u".uno:Backward"_ustr ] = ( bShapeContext ? isShapeControllerCommandAvailable( u".uno:Backward"_ustr ) :
838
0
        ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward && bEnableDataTableDialog ) );
839
840
0
    m_aCommandAvailability[ u".uno:InsertDataLabels"_ustr ] = bIsWritable;
841
0
    m_aCommandAvailability[ u".uno:InsertDataLabel"_ustr ] = bIsWritable;
842
0
    m_aCommandAvailability[ u".uno:InsertMeanValue"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddMeanValue;
843
0
    m_aCommandAvailability[ u".uno:InsertTrendline"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddTrendline;
844
0
    const bool bInsertTrendlineEquation = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddTrendlineEquation;
845
0
    m_aCommandAvailability[ u".uno:InsertTrendlineEquation"_ustr ] = bInsertTrendlineEquation;
846
0
    m_aCommandAvailability[ u".uno:InsertTrendlineEquationAndR2"_ustr ] = bInsertTrendlineEquation && m_apControllerState->bMayAddR2Value;
847
0
    m_aCommandAvailability[ u".uno:InsertR2Value"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddR2Value
848
0
        && !m_apControllerState->bMayAddTrendlineEquation;
849
0
    m_aCommandAvailability[ u".uno:DeleteR2Value"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteR2Value;
850
851
0
    m_aCommandAvailability[ u".uno:InsertXErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddXErrorBars;
852
0
    m_aCommandAvailability[ u".uno:InsertYErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayAddYErrorBars;
853
854
0
    m_aCommandAvailability[ u".uno:DeleteDataLabels"_ustr ] = bIsWritable;
855
0
    m_aCommandAvailability[ u".uno:DeleteDataLabel"_ustr ] = bIsWritable;
856
0
    m_aCommandAvailability[ u".uno:DeleteTrendline"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteTrendline;
857
0
    m_aCommandAvailability[ u".uno:DeleteTrendlineEquation"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteTrendlineEquation;
858
0
    m_aCommandAvailability[ u".uno:DeleteMeanValue"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteMeanValue;
859
0
    m_aCommandAvailability[ u".uno:DeleteXErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteXErrorBars;
860
0
    m_aCommandAvailability[ u".uno:DeleteYErrorBars"_ustr ] = bIsWritable && bControllerStateIsValid && m_apControllerState->bMayDeleteYErrorBars;
861
862
0
    m_aCommandAvailability[ u".uno:ResetDataPoint"_ustr ] = bIsWritable;
863
0
    m_aCommandAvailability[ u".uno:ResetAllDataPoints"_ustr ] = bIsWritable;
864
865
0
    m_aCommandAvailability[ u".uno:InsertAxis"_ustr ] = bIsWritable;
866
0
    m_aCommandAvailability[ u".uno:DeleteAxis"_ustr ] = bIsWritable;
867
0
    m_aCommandAvailability[ u".uno:InsertAxisTitle"_ustr ] = bIsWritable;
868
0
    m_aCommandAvailability[ u".uno:FormatMajorGrid"_ustr ] = bIsWritable;
869
0
    m_aCommandAvailability[ u".uno:InsertMajorGrid"_ustr ] = bIsWritable;
870
0
    m_aCommandAvailability[ u".uno:DeleteMajorGrid"_ustr ] = bIsWritable;
871
0
    m_aCommandAvailability[ u".uno:FormatMinorGrid"_ustr ] = bIsWritable;
872
0
    m_aCommandAvailability[ u".uno:InsertMinorGrid"_ustr ] = bIsWritable;
873
0
    m_aCommandAvailability[ u".uno:DeleteMinorGrid"_ustr ] = bIsWritable;
874
875
    // data table
876
0
    m_aCommandAvailability[ u".uno:InsertDataTable"_ustr ] = bIsWritable && bModelStateIsValid && !m_apModelState->bDataTable;
877
0
    m_aCommandAvailability[ u".uno:DeleteDataTable"_ustr ] = bIsWritable && bModelStateIsValid && m_apModelState->bDataTable;
878
0
}
879
880
bool ControllerCommandDispatch::commandAvailable(const OUString& rCommand) const
881
0
{
882
0
    std::map< OUString, bool >::const_iterator aIt( m_aCommandAvailability.find( rCommand ));
883
0
    if( aIt != m_aCommandAvailability.end())
884
0
        return aIt->second;
885
0
    SAL_WARN("chart2", "commandAvailable: command not in availability map:" << rCommand);
886
0
    return false;
887
0
}
888
889
bool ControllerCommandDispatch::commandHandled(const OUString& rCommand) const
890
0
{
891
0
    return m_aCommandAvailability.contains(rCommand);
892
0
}
893
894
bool ControllerCommandDispatch::isShapeControllerCommandAvailable( const OUString& rCommand )
895
0
{
896
0
    ShapeController* pShapeController(nullptr);
897
0
    {
898
0
        SolarMutexGuard g;
899
0
        if (m_pDispatchContainer)
900
0
            pShapeController = m_pDispatchContainer->getShapeController();
901
0
    }
902
0
    if ( pShapeController )
903
0
    {
904
0
        FeatureState aState( pShapeController->getState( rCommand ) );
905
0
        return aState.bEnabled;
906
0
    }
907
0
    return false;
908
0
}
909
910
void ControllerCommandDispatch::fireStatusEvent(
911
    const OUString & rURL,
912
    const Reference< frame::XStatusListener > & xSingleListener /* = 0 */ )
913
0
{
914
0
    if (rURL.isEmpty() || rURL == ".uno:ChartElementSelector")
915
0
    {
916
0
        uno::Any aArg;
917
0
        aArg <<= Reference< frame::XController >(m_xChartController);
918
0
        fireStatusEventForURL( u".uno:ChartElementSelector"_ustr, aArg, true, xSingleListener );
919
0
    }
920
921
0
    if( rURL.isEmpty() )
922
0
    {
923
0
        for (auto const& elem : m_aCommandAvailability)
924
0
            fireStatusEventForURLImpl( elem.first, xSingleListener );
925
0
    }
926
0
    else if (m_aCommandAvailability.contains(rURL))
927
0
        fireStatusEventForURLImpl( rURL, xSingleListener );
928
0
}
929
930
// ____ XDispatch ____
931
void SAL_CALL ControllerCommandDispatch::dispatch(
932
    const util::URL& URL,
933
    const Sequence< beans::PropertyValue >& Arguments )
934
0
{
935
0
    if( commandAvailable( URL.Complete ))
936
0
        m_xDispatch->dispatch( URL, Arguments );
937
0
}
938
939
// ____ WeakComponentImplHelperBase ____
940
/// is called when this is disposed
941
void ControllerCommandDispatch::disposing(std::unique_lock<std::mutex>& /*rGuard*/)
942
0
{
943
0
    m_xChartController.clear();
944
0
    m_xDispatch.clear();
945
0
    m_xSelectionSupplier.clear();
946
0
}
947
948
// ____ XEventListener (base of XModifyListener) ____
949
void SAL_CALL ControllerCommandDispatch::disposing( const lang::EventObject& /* Source */ )
950
0
{
951
0
    m_xChartController.clear();
952
0
    m_xDispatch.clear();
953
0
    m_xSelectionSupplier.clear();
954
0
}
955
956
// ____ XModifyListener ____
957
void SAL_CALL ControllerCommandDispatch::modified( const lang::EventObject& aEvent )
958
0
{
959
0
    bool bUpdateCommandAvailability = false;
960
961
    // Update the "ModelState" Struct.
962
0
    if( m_apModelState && m_xChartController.is())
963
0
    {
964
0
        m_apModelState->update( m_xChartController->getChartModel());
965
0
        bUpdateCommandAvailability = true;
966
0
    }
967
968
    // Update the "ControllerState" Struct.
969
0
    if( m_apControllerState && m_xChartController.is())
970
0
    {
971
0
        m_apControllerState->update( m_xChartController, m_xChartController->getChartModel());
972
0
        bUpdateCommandAvailability = true;
973
0
    }
974
975
0
    if( bUpdateCommandAvailability )
976
0
        updateCommandAvailability();
977
978
0
    if (comphelper::LibreOfficeKit::isActive())
979
0
    {
980
0
        if (SfxViewShell* pViewShell = SfxViewShell::Current())
981
0
            if (SfxObjectShell* pObjSh = pViewShell->GetObjectShell())
982
0
                pObjSh->SetModified();
983
0
    }
984
985
0
    CommandDispatch::modified( aEvent );
986
0
}
987
988
// ____ XSelectionChangeListener ____
989
void SAL_CALL ControllerCommandDispatch::selectionChanged( const lang::EventObject& aEvent )
990
0
{
991
    // Update the "ControllerState" Struct.
992
0
    if( m_apControllerState && m_xChartController.is())
993
0
    {
994
0
        m_apControllerState->update( m_xChartController, m_xChartController->getChartModel());
995
0
        updateCommandAvailability();
996
0
    }
997
998
0
    CommandDispatch::modified( aEvent );
999
0
}
1000
1001
} //  namespace chart
1002
1003
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */