Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/unoobj/TablePivotCharts.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 <memory>
11
#include <com/sun/star/embed/Aspects.hpp>
12
#include <com/sun/star/embed/XEmbeddedObject.hpp>
13
#include <com/sun/star/awt/Size.hpp>
14
#include <com/sun/star/chart/ChartDataRowSource.hpp>
15
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
16
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
17
18
#include <tools/gen.hxx>
19
#include <svx/svdoole2.hxx>
20
#include <svx/svdpage.hxx>
21
#include <svx/svdundo.hxx>
22
#include <unotools/moduleoptions.hxx>
23
#include <comphelper/propertysequence.hxx>
24
#include <comphelper/classids.hxx>
25
#include <toolkit/helper/vclunohelper.hxx>
26
#include <tools/globname.hxx>
27
#include <svtools/embedhlp.hxx>
28
#include <comphelper/sequence.hxx>
29
#include <vcl/svapp.hxx>
30
31
#include <TablePivotChart.hxx>
32
#include <TablePivotCharts.hxx>
33
#include <PivotTableDataProvider.hxx>
34
#include <ChartTools.hxx>
35
36
#include <miscuno.hxx>
37
#include <docsh.hxx>
38
#include <drwlayer.hxx>
39
40
using namespace css;
41
42
namespace sc
43
{
44
45
SC_SIMPLE_SERVICE_INFO(TablePivotCharts, u"TablePivotCharts"_ustr, u"com.sun.star.table.TablePivotCharts"_ustr)
46
47
TablePivotCharts::TablePivotCharts(ScDocShell* pDocShell, SCTAB nTab)
48
0
    : m_pDocShell(pDocShell)
49
0
    , m_nTab(nTab)
50
0
{
51
0
    m_pDocShell->GetDocument().AddUnoObject(*this);
52
0
}
53
54
TablePivotCharts::~TablePivotCharts()
55
0
{
56
0
    SolarMutexGuard aGuard;
57
58
0
    if (m_pDocShell)
59
0
        m_pDocShell->GetDocument().RemoveUnoObject(*this);
60
0
}
61
62
void TablePivotCharts::Notify(SfxBroadcaster& /*rBroadcaster*/, const SfxHint& rHint)
63
0
{
64
0
    if (rHint.GetId() == SfxHintId::Dying)
65
0
        m_pDocShell = nullptr;
66
0
}
67
68
// XTablePivotCharts
69
void SAL_CALL TablePivotCharts::addNewByName(OUString const & rName,
70
                                             const awt::Rectangle& aRect,
71
                                             OUString const & rDataPilotName)
72
0
{
73
0
    SolarMutexGuard aGuard;
74
75
0
    if (!m_pDocShell)
76
0
        return;
77
78
0
    ScDocument& rDoc = m_pDocShell->GetDocument();
79
0
    ScDrawLayer* pModel = m_pDocShell->MakeDrawLayer();
80
0
    SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
81
0
    if (!pPage)
82
0
        return;
83
84
    //  chart can't be inserted if any ole object with that name exists on any table
85
    //  (empty string: generate valid name)
86
87
0
    OUString aName = rName;
88
0
    SCTAB nDummy;
89
0
    if (!aName.isEmpty() && pModel->GetNamedObject(aName, SdrObjKind::OLE2, nDummy))
90
0
    {
91
        //  object exists - only RuntimeException is specified
92
0
        throw uno::RuntimeException();
93
0
    }
94
95
0
    uno::Reference<embed::XEmbeddedObject> xObject;
96
97
0
    if (SvtModuleOptions().IsChartInstalled())
98
0
        xObject = m_pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject(SvGlobalName(SO3_SCH_CLASSID).GetByteSequence(), aName);
99
100
0
    if (!xObject.is())
101
0
            return;
102
103
0
    Point aRectPos(aRect.X, aRect.Y);
104
0
    bool bLayoutRTL = rDoc.IsLayoutRTL(m_nTab);
105
0
    if ((aRectPos.X() < 0 && !bLayoutRTL) || (aRectPos.X() > 0 && bLayoutRTL))
106
0
        aRectPos.setX( 0 );
107
108
0
    if (aRectPos.Y() < 0)
109
0
         aRectPos.setY( 0 );
110
111
0
    Size aRectSize(aRect.Width, aRect.Height);
112
0
    if (aRectSize.Width() <= 0)
113
0
        aRectSize.setWidth( 5000 ); // default size
114
115
0
    if (aRectSize.Height() <= 0)
116
0
        aRectSize.setHeight( 5000 );
117
118
0
    ::tools::Rectangle aInsRect(aRectPos, aRectSize);
119
120
0
    sal_Int64 nAspect(embed::Aspects::MSOLE_CONTENT);
121
0
    MapUnit aMapUnit(VCLUnoHelper::UnoEmbed2VCLMapUnit(xObject->getMapUnit(nAspect)));
122
0
    Size aSize(aInsRect.GetSize());
123
0
    aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aMapUnit));
124
0
    awt::Size aAwtSize;
125
0
    aAwtSize.Width = aSize.Width();
126
0
    aAwtSize.Height = aSize.Height();
127
128
0
    rtl::Reference<sc::PivotTableDataProvider> pPivotTableDataProvider(new sc::PivotTableDataProvider(rDoc));
129
0
    pPivotTableDataProvider->setPivotTableName(rDataPilotName);
130
131
0
    uno::Reference<chart2::data::XDataReceiver> xReceiver;
132
133
0
    if (xObject.is())
134
0
        xReceiver.set(xObject->getComponent(), uno::UNO_QUERY);
135
136
0
    if (xReceiver.is())
137
0
    {
138
0
        xReceiver->attachDataProvider(uno::Reference<chart2::data::XDataProvider>(pPivotTableDataProvider));
139
140
0
        uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(cppu::getXWeak(m_pDocShell->GetModel()), uno::UNO_QUERY);
141
0
        xReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier);
142
143
0
        uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({
144
0
                    { "CellRangeRepresentation", uno::Any(rDataPilotName) },
145
0
                    { "HasCategories", uno::Any(true) },
146
0
                    { "DataRowSource", uno::Any(chart::ChartDataRowSource_COLUMNS) }
147
0
                }));
148
0
        xReceiver->setArguments(aArgs);
149
0
    }
150
151
0
    rtl::Reference<SdrOle2Obj> pObject = new SdrOle2Obj(
152
0
            *pModel,
153
0
            svt::EmbeddedObjectRef(xObject, embed::Aspects::MSOLE_CONTENT),
154
0
            aName,
155
0
            aInsRect);
156
157
0
    if (xObject.is())
158
0
        xObject->setVisualAreaSize(nAspect, aAwtSize);
159
160
0
    pPage->InsertObject(pObject.get());
161
0
    pModel->AddUndo(std::make_unique<SdrUndoInsertObj>(*pObject));
162
0
}
163
164
void SAL_CALL TablePivotCharts::removeByName(const OUString& rName)
165
0
{
166
0
    SolarMutexGuard aGuard;
167
0
    SdrOle2Obj* pObject = sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE);
168
0
    if (pObject)
169
0
    {
170
0
        ScDocument& rDoc = m_pDocShell->GetDocument();
171
0
        ScDrawLayer* pModel = rDoc.GetDrawLayer();
172
0
        SdrPage* pPage = pModel->GetPage(sal_uInt16(m_nTab));
173
0
        pModel->AddUndo(std::make_unique<SdrUndoDelObj>(*pObject));
174
0
        pPage->RemoveObject(pObject->GetOrdNum());
175
0
    }
176
0
}
177
178
// XIndexAccess
179
sal_Int32 SAL_CALL TablePivotCharts::getCount()
180
0
{
181
0
    SolarMutexGuard aGuard;
182
0
    sal_Int32 nCount = 0;
183
184
0
    if (!m_pDocShell)
185
0
        return nCount;
186
187
0
    sctools::ChartIterator aIterator(m_pDocShell, m_nTab, sctools::ChartSourceType::PIVOT_TABLE);
188
189
0
    SdrOle2Obj* pOleObject = aIterator.next();
190
0
    while (pOleObject)
191
0
    {
192
0
        if (pOleObject->GetObjRef().is())
193
0
            nCount++;
194
0
        pOleObject = aIterator.next();
195
0
    }
196
0
    return nCount;
197
0
}
198
199
uno::Any SAL_CALL TablePivotCharts::getByIndex(sal_Int32 nIndex)
200
0
{
201
0
    SolarMutexGuard aGuard;
202
0
    SdrOle2Obj* pObject = sctools::getChartByIndex(m_pDocShell, m_nTab, nIndex,
203
0
                                                     sctools::ChartSourceType::PIVOT_TABLE);
204
0
    if (!pObject)
205
0
        throw lang::IndexOutOfBoundsException();
206
207
0
    OUString aName;
208
0
    uno::Reference<embed::XEmbeddedObject> xObject = pObject->GetObjRef();
209
0
    if (xObject.is())
210
0
        aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
211
212
0
    if (aName.isEmpty())
213
0
        throw lang::IndexOutOfBoundsException();
214
215
0
    uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, aName));
216
0
    if (!xChart.is())
217
0
        throw lang::IndexOutOfBoundsException();
218
219
0
    return uno::Any(xChart);
220
0
}
221
222
uno::Type SAL_CALL TablePivotCharts::getElementType()
223
0
{
224
0
    return cppu::UnoType<table::XTablePivotChart>::get();
225
0
}
226
227
sal_Bool SAL_CALL TablePivotCharts::hasElements()
228
0
{
229
0
    SolarMutexGuard aGuard;
230
0
    return getCount() != 0;
231
0
}
232
233
uno::Any SAL_CALL TablePivotCharts::getByName(OUString const & rName)
234
0
{
235
0
    SolarMutexGuard aGuard;
236
237
0
    if (!sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE))
238
0
        throw container::NoSuchElementException();
239
240
0
    uno::Reference<table::XTablePivotChart> xChart(new TablePivotChart(m_pDocShell, m_nTab, rName));
241
0
    if (!xChart.is())
242
0
        throw container::NoSuchElementException();
243
244
0
    return uno::Any(xChart);
245
0
}
246
247
uno::Sequence<OUString> SAL_CALL TablePivotCharts::getElementNames()
248
0
{
249
0
    SolarMutexGuard aGuard;
250
251
0
    std::vector<OUString> aElements;
252
0
    sctools::ChartIterator aIterator(m_pDocShell, m_nTab, sctools::ChartSourceType::PIVOT_TABLE);
253
254
0
    SdrOle2Obj* pOleObject = aIterator.next();
255
0
    while (pOleObject)
256
0
    {
257
0
        uno::Reference<embed::XEmbeddedObject> xObject = pOleObject->GetObjRef();
258
0
        if (xObject.is())
259
0
        {
260
0
            OUString aName = m_pDocShell->GetEmbeddedObjectContainer().GetEmbeddedObjectName(xObject);
261
0
            aElements.push_back(aName);
262
0
        }
263
0
        pOleObject = aIterator.next();
264
0
    }
265
0
    return comphelper::containerToSequence(aElements);
266
0
}
267
268
sal_Bool SAL_CALL TablePivotCharts::hasByName(OUString const & rName)
269
0
{
270
0
    SolarMutexGuard aGuard;
271
272
0
    return sctools::findChartsByName(m_pDocShell, m_nTab, rName, sctools::ChartSourceType::PIVOT_TABLE) != nullptr;
273
0
}
274
275
} // end sc namespace
276
277
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */