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/sidebar/ChartEffectPanel.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
10
#include "ChartEffectPanel.hxx"
11
12
#include <ChartController.hxx>
13
#include <ChartModel.hxx>
14
#include <ViewElementListProvider.hxx>
15
16
#include <sfx2/weldutils.hxx>
17
#include <svx/sdmetitm.hxx>
18
#include <svx/sdprcitm.hxx>
19
#include <svx/tbcontrl.hxx>
20
#include <svx/xcolit.hxx>
21
#include <vcl/svapp.hxx>
22
23
namespace chart::sidebar
24
{
25
namespace
26
{
27
OUString getCID(const rtl::Reference<::chart::ChartModel>& xModel)
28
0
{
29
0
    css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
30
0
    css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController,
31
0
                                                                          css::uno::UNO_QUERY);
32
0
    if (!xSelectionSupplier.is())
33
0
        return OUString();
34
35
0
    css::uno::Any aAny = xSelectionSupplier->getSelection();
36
0
    if (!aAny.hasValue())
37
0
    {
38
        // if no selection, default to diagram wall so sidebar can show some editable properties
39
0
        ChartController* pController = dynamic_cast<ChartController*>(xController.get());
40
0
        if (pController)
41
0
        {
42
0
            pController->select(
43
0
                css::uno::Any(ObjectIdentifier::createClassifiedIdentifier(OBJECTTYPE_PAGE, u"")));
44
0
            xSelectionSupplier = css::uno::Reference<css::view::XSelectionSupplier>(
45
0
                xController, css::uno::UNO_QUERY);
46
0
            if (xSelectionSupplier.is())
47
0
                aAny = xSelectionSupplier->getSelection();
48
0
        }
49
50
0
        if (!aAny.hasValue())
51
0
            return OUString();
52
0
    }
53
54
0
    OUString aCID;
55
0
    aAny >>= aCID;
56
57
0
    return aCID;
58
0
}
59
60
css::uno::Reference<css::beans::XPropertySet>
61
getPropSet(const rtl::Reference<::chart::ChartModel>& xModel)
62
0
{
63
0
    OUString aCID = getCID(xModel);
64
0
    css::uno::Reference<css::beans::XPropertySet> xPropSet
65
0
        = ObjectIdentifier::getObjectPropertySet(aCID, xModel);
66
67
0
    ObjectType eType = ObjectIdentifier::getObjectType(aCID);
68
0
    if (eType == OBJECTTYPE_DIAGRAM)
69
0
    {
70
0
        css::uno::Reference<css::chart2::XDiagram> xDiagram(xPropSet, css::uno::UNO_QUERY);
71
0
        if (!xDiagram.is())
72
0
            return xPropSet;
73
74
0
        xPropSet.set(xDiagram->getWall());
75
0
    }
76
77
0
    return xPropSet;
78
0
}
79
80
class PreventUpdate
81
{
82
public:
83
    explicit PreventUpdate(bool& bUpdate)
84
0
        : mbUpdate(bUpdate)
85
0
    {
86
0
        mbUpdate = false;
87
0
    }
88
89
0
    ~PreventUpdate() { mbUpdate = true; }
90
91
private:
92
    bool& mbUpdate;
93
};
94
}
95
96
std::unique_ptr<PanelLayout> ChartEffectPanel::Create(weld::Widget* pParent,
97
                                                      ChartController* pController)
98
0
{
99
0
    if (pParent == nullptr)
100
0
        throw css::lang::IllegalArgumentException(
101
0
            u"no parent Window given to EffectPropertyPanel::Create"_ustr, nullptr, 0);
102
103
0
    return std::make_unique<ChartEffectPanel>(pParent, pController);
104
0
}
105
106
ChartEffectPanel::ChartEffectPanel(weld::Widget* pParent, ChartController* pController)
107
0
    : svx::sidebar::EffectPropertyPanelBase(pParent)
108
0
    , mxModel(pController->getChartModel())
109
0
    , mxListener(new ChartSidebarModifyListener(this))
110
0
    , mxSelectionListener(new ChartSidebarSelectionListener(this))
111
0
    , mbUpdate(true)
112
0
    , mbModelValid(true)
113
0
{
114
0
    std::vector<ObjectType> aAcceptedTypes{ OBJECTTYPE_PAGE,        OBJECTTYPE_DIAGRAM,
115
0
                                            OBJECTTYPE_DATA_SERIES, OBJECTTYPE_DATA_POINT,
116
0
                                            OBJECTTYPE_TITLE,       OBJECTTYPE_LEGEND };
117
0
    mxSelectionListener->setAcceptedTypes(std::move(aAcceptedTypes));
118
0
    Initialize();
119
0
}
120
121
0
ChartEffectPanel::~ChartEffectPanel() { doUpdateModel(nullptr); }
122
123
void ChartEffectPanel::Initialize()
124
0
{
125
0
    mxModel->addModifyListener(mxListener);
126
127
0
    css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(
128
0
        mxModel->getCurrentController(), css::uno::UNO_QUERY);
129
0
    if (xSelectionSupplier.is())
130
0
        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
131
132
0
    updateData();
133
0
}
134
135
void ChartEffectPanel::setGlowColor(const XColorItem& rItem)
136
0
{
137
0
    PreventUpdate aProtector(mbUpdate);
138
0
    const css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
139
0
    if (!xPropSet.is())
140
0
        return;
141
142
0
    xPropSet->setPropertyValue(u"GlowEffectColor"_ustr, css::uno::Any(rItem.GetColorValue()));
143
0
}
144
145
void ChartEffectPanel::setGlowRadius(const SdrMetricItem& rItem)
146
0
{
147
0
    PreventUpdate aProtector(mbUpdate);
148
0
    css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
149
0
    if (!xPropSet.is())
150
0
        return;
151
152
0
    xPropSet->setPropertyValue(u"GlowEffectRadius"_ustr, css::uno::Any(rItem.GetValue()));
153
0
}
154
155
void ChartEffectPanel::setGlowTransparency(const SdrPercentItem& rItem)
156
0
{
157
0
    PreventUpdate aProtector(mbUpdate);
158
0
    css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
159
0
    if (!xPropSet.is())
160
0
        return;
161
162
0
    xPropSet->setPropertyValue(u"GlowEffectTransparency"_ustr, css::uno::Any(rItem.GetValue()));
163
0
}
164
165
void ChartEffectPanel::setSoftEdgeRadius(const SdrMetricItem& rItem)
166
0
{
167
0
    PreventUpdate aProtector(mbUpdate);
168
0
    const css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
169
0
    if (!xPropSet.is())
170
0
        return;
171
172
0
    xPropSet->setPropertyValue(u"SoftEdgeRadius"_ustr, css::uno::Any(rItem.GetValue()));
173
0
}
174
175
void ChartEffectPanel::updateData()
176
0
{
177
0
    if (!mbUpdate || !mbModelValid)
178
0
        return;
179
180
0
    const css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
181
0
    if (!xPropSet.is())
182
0
        return;
183
184
0
    const css::uno::Reference<css::beans::XPropertySetInfo> xInfo(xPropSet->getPropertySetInfo());
185
0
    if (!xInfo.is())
186
0
        return;
187
188
0
    SolarMutexGuard aGuard;
189
0
    if (xInfo->hasPropertyByName(u"GlowEffectRadius"_ustr))
190
0
    {
191
0
        sal_Int32 nRadius = 0;
192
0
        xPropSet->getPropertyValue(u"GlowEffectRadius"_ustr) >>= nRadius;
193
0
        const SdrMetricItem aRadiusItem(SDRATTR_GLOW_RADIUS, nRadius);
194
0
        updateGlowRadius(true, &aRadiusItem);
195
0
    }
196
197
0
    if (xInfo->hasPropertyByName(u"GlowEffectColor"_ustr))
198
0
    {
199
0
        sal_uInt32 nColor = 0;
200
0
        xPropSet->getPropertyValue(u"GlowEffectColor"_ustr) >>= nColor;
201
0
        const XColorItem aColorItem(SDRATTR_GLOW_COLOR, Color(ColorTransparency, nColor));
202
0
        updateGlowColor(true, &aColorItem);
203
0
    }
204
205
0
    if (xInfo->hasPropertyByName(u"GlowEffectTransparency"_ustr))
206
0
    {
207
0
        sal_Int16 nTransparency = 0;
208
0
        xPropSet->getPropertyValue(u"GlowEffectTransparency"_ustr) >>= nTransparency;
209
0
        const SdrPercentItem aTransparencyItem(SDRATTR_GLOW_TRANSPARENCY, nTransparency);
210
0
        updateGlowTransparency(true, &aTransparencyItem);
211
0
    }
212
0
}
213
214
0
void ChartEffectPanel::modelInvalid() { mbModelValid = false; }
215
216
void ChartEffectPanel::selectionChanged(bool bCorrectType)
217
0
{
218
0
    if (bCorrectType)
219
0
        updateData();
220
0
}
221
222
void ChartEffectPanel::doUpdateModel(const rtl::Reference<::chart::ChartModel>& xModel)
223
0
{
224
0
    if (mbModelValid)
225
0
    {
226
0
        mxModel->removeModifyListener(mxListener);
227
228
0
        css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
229
0
            mxModel->getCurrentController(), css::uno::UNO_QUERY);
230
0
        if (oldSelectionSupplier.is())
231
0
        {
232
0
            oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
233
0
        }
234
0
    }
235
236
0
    mxModel = xModel;
237
0
    mbModelValid = mxModel.is();
238
239
0
    if (!mbModelValid)
240
0
        return;
241
242
0
    mxModel->addModifyListener(mxListener);
243
244
0
    css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(
245
0
        mxModel->getCurrentController(), css::uno::UNO_QUERY);
246
0
    if (xSelectionSupplier.is())
247
0
        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
248
0
}
249
250
void ChartEffectPanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
251
0
{
252
0
    ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
253
    assert(!xModel || pModel);
254
0
    doUpdateModel(pModel);
255
0
}
256
}
257
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */